generated by Claude-3.7-Sonnet
This commit is contained in:
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
|
||||
}
|
||||
Reference in New Issue
Block a user