1
0
mirror of https://github.com/mxpv/podsync.git synced 2024-05-11 05:55:04 +00:00

add support for descengind playlists

This commit is contained in:
Matej Drobnic
2021-12-28 08:06:10 +01:00
parent c1130f3f97
commit 52293e4ad2
5 changed files with 56 additions and 20 deletions

View File

@@ -78,6 +78,7 @@ vimeo = [ # Multiple keys will be rotated.
update_period = "12h" # How often query for updates, examples: "60m", "4h", "2h45m"
quality = "high" # or "low"
format = "video" # or "audio"
playlist_sort = "asc" # or "desc", which will fetch playlist items from the end
# custom.cover_art_quality use "high" or "low" to special cover image quality from channel cover default is equal with "quality" and disable when custom.cover_art was set.
# custom = { title = "Level1News", description = "News sections of Level1Techs, in a podcast feed!", author = "Level1Tech", cover_art = "{IMAGE_URL}", cover_art_quality = "high", category = "TV", subcategories = ["Documentary", "Tech News"], explicit = true, lang = "en" } # Optional feed customizations
# max_height = 720 # Optional maximal height of video, example: 720, 1080, 1440, 2160, ...

View File

@@ -330,11 +330,14 @@ func (yt *YouTubeBuilder) queryVideoDescriptions(ctx context.Context, playlist m
return nil
}
// Cost: (3 units + 5 units) * X pages = 8 units per page
// Cost:
// ASC mode = (3 units + 5 units) * X pages = 8 units per page
// DESC mode = 3 units * (number of pages in the entire playlist) + 5 units
func (yt *YouTubeBuilder) queryItems(ctx context.Context, feed *model.Feed) error {
var (
token string
count int
token string
count int
allSnippets []*youtube.PlaylistItemSnippet
)
for {
@@ -346,25 +349,39 @@ func (yt *YouTubeBuilder) queryItems(ctx context.Context, feed *model.Feed) erro
token = pageToken
if len(items) == 0 {
return nil
break
}
// Extract playlist snippets
snippets := map[string]*youtube.PlaylistItemSnippet{}
for _, item := range items {
snippets[item.Snippet.ResourceId.VideoId] = item.Snippet
allSnippets = append(allSnippets, item.Snippet)
count++
}
// Query video descriptions from the list of ids
if err := yt.queryVideoDescriptions(ctx, snippets, feed); err != nil {
return err
}
if count >= feed.PageSize || token == "" {
return nil
if (feed.PlaylistSort != model.SortingDesc && count >= feed.PageSize) || token == "" {
break
}
}
if len(allSnippets) > feed.PageSize {
if feed.PlaylistSort != model.SortingDesc {
allSnippets = allSnippets[:feed.PageSize]
} else {
allSnippets = allSnippets[len(allSnippets)-feed.PageSize:]
}
}
snippets := map[string]*youtube.PlaylistItemSnippet{}
for _, snippet := range allSnippets {
snippets[snippet.ResourceId.VideoId] = snippet
}
// Query video descriptions from the list of ids
if err := yt.queryVideoDescriptions(ctx, snippets, feed); err != nil {
return err
}
return nil
}
func (yt *YouTubeBuilder) Build(ctx context.Context, cfg *config.Feed) (*model.Feed, error) {
@@ -374,13 +391,14 @@ func (yt *YouTubeBuilder) Build(ctx context.Context, cfg *config.Feed) (*model.F
}
feed := &model.Feed{
ItemID: info.ItemID,
Provider: info.Provider,
LinkType: info.LinkType,
Format: cfg.Format,
Quality: cfg.Quality,
PageSize: cfg.PageSize,
UpdatedAt: time.Now().UTC(),
ItemID: info.ItemID,
Provider: info.Provider,
LinkType: info.LinkType,
Format: cfg.Format,
Quality: cfg.Quality,
PageSize: cfg.PageSize,
PlaylistSort: cfg.PlaylistSort,
UpdatedAt: time.Now().UTC(),
}
if feed.PageSize == 0 {

View File

@@ -45,6 +45,8 @@ type Feed struct {
YouTubeDLArgs []string `toml:"youtube_dl_args"`
// Included in OPML file
OPML bool `toml:"opml"`
// Playlist sort
PlaylistSort model.Sorting `toml:"playlist_sort"`
}
type Filters struct {
@@ -237,5 +239,9 @@ func (c *Config) applyDefaults(configPath string) {
if feed.PageSize == 0 {
feed.PageSize = model.DefaultPageSize
}
if feed.PlaylistSort == "" {
feed.PlaylistSort = model.SortingAsc
}
}
}

View File

@@ -40,6 +40,7 @@ timeout = 15
format = "audio"
quality = "low"
filters = { title = "regex for title here" }
playlist_sort = "desc"
clean = { keep_last = 10 }
[feeds.XYZ.custom]
cover_art = "http://img"
@@ -80,6 +81,7 @@ timeout = 15
assert.EqualValues(t, "low", feed.Quality)
assert.EqualValues(t, "regex for title here", feed.Filters.Title)
assert.EqualValues(t, 10, feed.Clean.KeepLast)
assert.EqualValues(t, model.SortingDesc, feed.PlaylistSort)
assert.EqualValues(t, "http://img", feed.Custom.CoverArt)
assert.EqualValues(t, "high", feed.Custom.CoverArtQuality)

View File

@@ -20,6 +20,14 @@ const (
FormatVideo = Format("video")
)
// Playlist sorting style
type Sorting string
const (
SortingDesc = Sorting("desc")
SortingAsc = Sorting("asc")
)
type Episode struct {
// ID of episode
ID string `json:"id"`
@@ -54,6 +62,7 @@ type Feed struct {
ItemURL string `json:"item_url"` // Platform specific URL
Episodes []*Episode `json:"-"` // Array of episodes
UpdatedAt time.Time `json:"updated_at"`
PlaylistSort Sorting `json:"playlist_sort"`
}
type EpisodeStatus string