generated by Claude-3.7-Sonnet
This commit is contained in:
40
model/apple_podcast.go
Normal file
40
model/apple_podcast.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Package model 提供播客和剧集的数据模型
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Podcast 表示从Apple Podcasts API获取的播客信息
|
||||
type ApplePodcast struct {
|
||||
WrapperType string `json:"wrapperType,omitempty"`
|
||||
Kind string `json:"kind,omitempty"`
|
||||
CollectionID int `json:"collectionId,omitempty"`
|
||||
TrackID int `json:"trackId,omitempty"`
|
||||
ArtistName string `json:"artistName,omitempty"`
|
||||
CollectionName string `json:"collectionName,omitempty"`
|
||||
TrackName string `json:"trackName,omitempty"`
|
||||
CollectionCensoredName string `json:"collectionCensoredName,omitempty"`
|
||||
TrackCensoredName string `json:"trackCensoredName,omitempty"`
|
||||
CollectionViewURL string `json:"collectionViewUrl,omitempty"`
|
||||
FeedURL string `json:"feedUrl,omitempty"`
|
||||
TrackViewURL string `json:"trackViewUrl,omitempty"`
|
||||
ArtworkURL30 string `json:"artworkUrl30,omitempty"`
|
||||
ArtworkURL60 string `json:"artworkUrl60,omitempty"`
|
||||
ArtworkURL100 string `json:"artworkUrl100,omitempty"`
|
||||
CollectionPrice float64 `json:"collectionPrice,omitempty"`
|
||||
TrackPrice float64 `json:"trackPrice,omitempty"`
|
||||
CollectionHDPrice float64 `json:"collectionHdPrice,omitempty"`
|
||||
ReleaseDate time.Time `json:"releaseDate,omitempty"`
|
||||
CollectionExplicitness string `json:"collectionExplicitness,omitempty"`
|
||||
TrackExplicitness string `json:"trackExplicitness,omitempty"`
|
||||
TrackCount int `json:"trackCount,omitempty"`
|
||||
TrackTimeMillis int `json:"trackTimeMillis,omitempty"`
|
||||
Country string `json:"country,omitempty"`
|
||||
Currency string `json:"currency,omitempty"`
|
||||
PrimaryGenreName string `json:"primaryGenreName,omitempty"`
|
||||
ContentAdvisoryRating string `json:"contentAdvisoryRating,omitempty"`
|
||||
ArtworkURL600 string `json:"artworkUrl600,omitempty"`
|
||||
GenreIDs []string `json:"genreIds,omitempty"`
|
||||
Genres []string `json:"genres,omitempty"`
|
||||
}
|
||||
118
model/podcast.go
Normal file
118
model/podcast.go
Normal file
@@ -0,0 +1,118 @@
|
||||
// Package model 提供播客和剧集的数据模型
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mmcdole/gofeed"
|
||||
)
|
||||
|
||||
// Podcast 表示一个播客及其剧集
|
||||
type Podcast struct {
|
||||
// 播客的唯一标识符
|
||||
GUID string `json:"guid,omitempty"`
|
||||
|
||||
// 播客的URL
|
||||
URL string `json:"url,omitempty"`
|
||||
|
||||
// 播客的链接
|
||||
Link string `json:"link,omitempty"`
|
||||
|
||||
// 播客的标题
|
||||
Title string `json:"title,omitempty"`
|
||||
|
||||
// 播客的描述
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// 播客的图片URL
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
// 版权信息
|
||||
Copyright string `json:"copyright,omitempty"`
|
||||
|
||||
// 是否锁定,表示此订阅是否可以被导入到其他平台
|
||||
Locked *Locked `json:"locked,omitempty"`
|
||||
|
||||
// 资金支持信息
|
||||
Funding []Funding `json:"funding,omitempty"`
|
||||
|
||||
// 人员信息
|
||||
Persons []Person `json:"persons,omitempty"`
|
||||
|
||||
// 价值交换信息
|
||||
Value []Value `json:"value,omitempty"`
|
||||
|
||||
// 阻止标签
|
||||
Block []Block `json:"block,omitempty"`
|
||||
|
||||
// 剧集列表
|
||||
Episodes []Episode `json:"episodes,omitempty"`
|
||||
|
||||
// 远程项目
|
||||
RemoteItems []RemoteItem `json:"remote_items,omitempty"`
|
||||
|
||||
// 媒体类型
|
||||
Medium Medium `json:"medium,omitempty"`
|
||||
}
|
||||
|
||||
// LoadFeed 从URL加载播客RSS订阅
|
||||
func LoadFeed(url string) (*Podcast, error) {
|
||||
fp := gofeed.NewParser()
|
||||
feed, err := fp.ParseURL(url)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("解析播客订阅失败: %w", err)
|
||||
}
|
||||
|
||||
if feed == nil {
|
||||
return nil, errors.New("解析播客订阅失败: 空订阅")
|
||||
}
|
||||
|
||||
podcast := &Podcast{
|
||||
Title: feed.Title,
|
||||
Description: feed.Description,
|
||||
Link: feed.Link,
|
||||
Image: feed.Image.URL,
|
||||
Copyright: feed.Copyright,
|
||||
Episodes: make([]Episode, 0),
|
||||
Funding: make([]Funding, 0),
|
||||
Persons: make([]Person, 0),
|
||||
Value: make([]Value, 0),
|
||||
Block: make([]Block, 0),
|
||||
Medium: MediumPodcast,
|
||||
}
|
||||
|
||||
// 解析剧集
|
||||
for _, item := range feed.Items {
|
||||
episode := Episode{
|
||||
GUID: item.GUID,
|
||||
Title: item.Title,
|
||||
Description: item.Description,
|
||||
Link: item.Link,
|
||||
PublicationDate: item.PublishedParsed,
|
||||
Author: item.Author.Name,
|
||||
}
|
||||
|
||||
// 解析媒体URL
|
||||
if len(item.Enclosures) > 0 {
|
||||
episode.ContentURL = item.Enclosures[0].URL
|
||||
}
|
||||
|
||||
// 解析剧集图片
|
||||
if item.Image != nil && item.Image.URL != "" {
|
||||
episode.ImageURL = item.Image.URL
|
||||
}
|
||||
|
||||
// 解析时长
|
||||
if item.ITunesExt != nil && item.ITunesExt.Duration != "" {
|
||||
// 简单处理,实际应该解析时间格式
|
||||
durationSec := 0
|
||||
fmt.Sscanf(item.ITunesExt.Duration, "%d", &durationSec)
|
||||
episode.Duration = durationSec
|
||||
}
|
||||
|
||||
podcast.Episodes = append(podcast.Episodes, episode)
|
||||
}
|
||||
|
||||
return podcast, nil
|
||||
}
|
||||
45
model/search.go
Normal file
45
model/search.go
Normal file
@@ -0,0 +1,45 @@
|
||||
// Package model 提供播客和剧集的数据模型
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Item 表示搜索结果中的一个播客项目
|
||||
type Item struct {
|
||||
// 播客的集合ID
|
||||
CollectionID int `json:"collectionId,omitempty"`
|
||||
|
||||
// 播客的标题
|
||||
Title string `json:"title,omitempty"`
|
||||
|
||||
// 播客的作者
|
||||
Author string `json:"author,omitempty"`
|
||||
|
||||
// 播客的Feed URL
|
||||
FeedURL string `json:"feedUrl,omitempty"`
|
||||
|
||||
// 播客的小尺寸封面图URL
|
||||
ArtworkURL string `json:"artworkUrl,omitempty"`
|
||||
|
||||
// 播客的大尺寸封面图URL
|
||||
ArtworkURL600 string `json:"artworkUrl600,omitempty"`
|
||||
|
||||
// 播客的流派
|
||||
Genres []string `json:"genres,omitempty"`
|
||||
}
|
||||
|
||||
// SearchResult 表示播客搜索的结果
|
||||
type SearchResult struct {
|
||||
// 结果数量
|
||||
ResultCount int `json:"resultCount,omitempty"`
|
||||
|
||||
// 搜索是否成功
|
||||
Successful bool `json:"successful,omitempty"`
|
||||
|
||||
// 搜索结果项目列表
|
||||
Items []Item `json:"items,omitempty"`
|
||||
|
||||
// 处理时间
|
||||
ProcessedTime time.Time `json:"processedTime,omitempty"`
|
||||
}
|
||||
57
model/transcript.go
Normal file
57
model/transcript.go
Normal file
@@ -0,0 +1,57 @@
|
||||
// Package model 提供播客和剧集的数据模型
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// TranscriptFormat 表示转录文件的格式
|
||||
type TranscriptFormat string
|
||||
|
||||
const (
|
||||
// TranscriptFormatJSON 表示JSON格式的转录
|
||||
TranscriptFormatJSON TranscriptFormat = "json"
|
||||
// TranscriptFormatSubrip 表示SRT格式的转录
|
||||
TranscriptFormatSubrip TranscriptFormat = "subrip"
|
||||
// TranscriptFormatUnsupported 表示不支持的格式
|
||||
TranscriptFormatUnsupported TranscriptFormat = "unsupported"
|
||||
)
|
||||
|
||||
// TranscriptURL 表示播客中包含的转录URL
|
||||
type TranscriptURL struct {
|
||||
// 转录的URL
|
||||
URL string `json:"url,omitempty"`
|
||||
|
||||
// 转录的类型:json或srt
|
||||
Type TranscriptFormat `json:"type,omitempty"`
|
||||
|
||||
// 转录的语言
|
||||
Language string `json:"language,omitempty"`
|
||||
|
||||
// 如果设置为captions,表示这是一个闭合字幕文件
|
||||
Rel string `json:"rel,omitempty"`
|
||||
}
|
||||
|
||||
// Transcript 表示一个转录
|
||||
type Transcript struct {
|
||||
// 字幕列表
|
||||
Subtitles []Subtitle `json:"subtitles,omitempty"`
|
||||
}
|
||||
|
||||
// Subtitle 表示转录中的一行
|
||||
type Subtitle struct {
|
||||
// 字幕的索引(顺序)
|
||||
Index int `json:"index,omitempty"`
|
||||
|
||||
// 字幕的开始时间
|
||||
Start time.Duration `json:"start,omitempty"`
|
||||
|
||||
// 字幕的结束时间
|
||||
End time.Duration `json:"end,omitempty"`
|
||||
|
||||
// 字幕的文本内容
|
||||
Data string `json:"data,omitempty"`
|
||||
|
||||
// 发言人(可选)
|
||||
Speaker string `json:"speaker,omitempty"`
|
||||
}
|
||||
150
model/types.go
Normal file
150
model/types.go
Normal file
@@ -0,0 +1,150 @@
|
||||
// Package model 提供播客和剧集的数据模型
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Medium 表示媒体类型
|
||||
type Medium string
|
||||
|
||||
const (
|
||||
// MediumPodcast 表示播客媒体类型
|
||||
MediumPodcast Medium = "podcast"
|
||||
// MediumMusic 表示音乐媒体类型
|
||||
MediumMusic Medium = "music"
|
||||
// MediumAudiobook 表示有声书媒体类型
|
||||
MediumAudiobook Medium = "audiobook"
|
||||
)
|
||||
|
||||
// Locked 表示播客是否锁定
|
||||
type Locked struct {
|
||||
// 是否锁定
|
||||
Locked bool `json:"locked,omitempty"`
|
||||
// 锁定的所有者
|
||||
Owner string `json:"owner,omitempty"`
|
||||
}
|
||||
|
||||
// Funding 表示资金支持信息
|
||||
type Funding struct {
|
||||
// 资金支持URL
|
||||
URL string `json:"url,omitempty"`
|
||||
// 资金支持文本
|
||||
Text string `json:"text,omitempty"`
|
||||
}
|
||||
|
||||
// Person 表示人员信息
|
||||
type Person struct {
|
||||
// 人员名称
|
||||
Name string `json:"name,omitempty"`
|
||||
// 人员角色
|
||||
Role string `json:"role,omitempty"`
|
||||
// 人员组
|
||||
Group string `json:"group,omitempty"`
|
||||
// 人员头像URL
|
||||
Img string `json:"img,omitempty"`
|
||||
// 人员URL
|
||||
Href string `json:"href,omitempty"`
|
||||
}
|
||||
|
||||
// Value 表示价值交换信息
|
||||
type Value struct {
|
||||
// 类型
|
||||
Type string `json:"type,omitempty"`
|
||||
// 方法
|
||||
Method string `json:"method,omitempty"`
|
||||
// 建议
|
||||
Suggested string `json:"suggested,omitempty"`
|
||||
// 接收者
|
||||
Recipients []ValueRecipient `json:"recipients,omitempty"`
|
||||
}
|
||||
|
||||
// ValueRecipient 表示价值接收者
|
||||
type ValueRecipient struct {
|
||||
// 名称
|
||||
Name string `json:"name,omitempty"`
|
||||
// 类型
|
||||
Type string `json:"type,omitempty"`
|
||||
// 地址
|
||||
Address string `json:"address,omitempty"`
|
||||
// 分割
|
||||
Split float64 `json:"split,omitempty"`
|
||||
// 自定义键
|
||||
CustomKey string `json:"customKey,omitempty"`
|
||||
// 自定义值
|
||||
CustomValue string `json:"customValue,omitempty"`
|
||||
}
|
||||
|
||||
// Block 表示阻止标签
|
||||
type Block struct {
|
||||
// 阻止的ID
|
||||
ID string `json:"id,omitempty"`
|
||||
// 阻止的URL
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// Episode 表示播客剧集
|
||||
type Episode struct {
|
||||
// 剧集的唯一标识符
|
||||
GUID string `json:"guid,omitempty"`
|
||||
|
||||
// 剧集的标题
|
||||
Title string `json:"title,omitempty"`
|
||||
|
||||
// 剧集的描述
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// 剧集的链接
|
||||
Link string `json:"link,omitempty"`
|
||||
|
||||
// 剧集的发布日期
|
||||
PublicationDate *time.Time `json:"publicationDate,omitempty"`
|
||||
|
||||
// 剧集的作者
|
||||
Author string `json:"author,omitempty"`
|
||||
|
||||
// 剧集的内容URL
|
||||
ContentURL string `json:"contentUrl,omitempty"`
|
||||
|
||||
// 剧集的图片URL
|
||||
ImageURL string `json:"imageUrl,omitempty"`
|
||||
|
||||
// 剧集的时长(秒)
|
||||
Duration int `json:"duration,omitempty"`
|
||||
|
||||
// 剧集的转录URL列表
|
||||
TranscriptURLs []TranscriptURL `json:"transcriptUrls,omitempty"`
|
||||
}
|
||||
|
||||
// RemoteItem 表示远程项目
|
||||
type RemoteItem struct {
|
||||
// 远程项目的唯一标识符
|
||||
GUID string `json:"guid,omitempty"`
|
||||
|
||||
// 远程项目的标题
|
||||
Title string `json:"title,omitempty"`
|
||||
|
||||
// 远程项目的描述
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// 远程项目的链接
|
||||
Link string `json:"link,omitempty"`
|
||||
|
||||
// 远程项目的发布日期
|
||||
PublicationDate *time.Time `json:"publicationDate,omitempty"`
|
||||
|
||||
// 远程项目的作者
|
||||
Author string `json:"author,omitempty"`
|
||||
|
||||
// 远程项目的内容URL
|
||||
ContentURL string `json:"contentUrl,omitempty"`
|
||||
|
||||
// 远程项目的图片URL
|
||||
ImageURL string `json:"imageUrl,omitempty"`
|
||||
|
||||
// 远程项目的时长(秒)
|
||||
Duration int `json:"duration,omitempty"`
|
||||
|
||||
// 远程项目的转录URL列表
|
||||
TranscriptURLs []TranscriptURL `json:"transcriptUrls,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user