Skip to content

Commit 52293e4

Browse files
committed
add support for descengind playlists
1 parent c1130f3 commit 52293e4

File tree

5 files changed

+54
-18
lines changed

5 files changed

+54
-18
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ vimeo = [ # Multiple keys will be rotated.
7878
update_period = "12h" # How often query for updates, examples: "60m", "4h", "2h45m"
7979
quality = "high" # or "low"
8080
format = "video" # or "audio"
81+
playlist_sort = "asc" # or "desc", which will fetch playlist items from the end
8182
# 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.
8283
# 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
8384
# max_height = 720 # Optional maximal height of video, example: 720, 1080, 1440, 2160, ...

pkg/builder/youtube.go

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -330,11 +330,14 @@ func (yt *YouTubeBuilder) queryVideoDescriptions(ctx context.Context, playlist m
330330
return nil
331331
}
332332

333-
// Cost: (3 units + 5 units) * X pages = 8 units per page
333+
// Cost:
334+
// ASC mode = (3 units + 5 units) * X pages = 8 units per page
335+
// DESC mode = 3 units * (number of pages in the entire playlist) + 5 units
334336
func (yt *YouTubeBuilder) queryItems(ctx context.Context, feed *model.Feed) error {
335337
var (
336-
token string
337-
count int
338+
token string
339+
count int
340+
allSnippets []*youtube.PlaylistItemSnippet
338341
)
339342

340343
for {
@@ -346,25 +349,39 @@ func (yt *YouTubeBuilder) queryItems(ctx context.Context, feed *model.Feed) erro
346349
token = pageToken
347350

348351
if len(items) == 0 {
349-
return nil
352+
break
350353
}
351354

352355
// Extract playlist snippets
353-
snippets := map[string]*youtube.PlaylistItemSnippet{}
354356
for _, item := range items {
355-
snippets[item.Snippet.ResourceId.VideoId] = item.Snippet
357+
allSnippets = append(allSnippets, item.Snippet)
356358
count++
357359
}
358360

359-
// Query video descriptions from the list of ids
360-
if err := yt.queryVideoDescriptions(ctx, snippets, feed); err != nil {
361-
return err
361+
if (feed.PlaylistSort != model.SortingDesc && count >= feed.PageSize) || token == "" {
362+
break
362363
}
364+
}
363365

364-
if count >= feed.PageSize || token == "" {
365-
return nil
366+
if len(allSnippets) > feed.PageSize {
367+
if feed.PlaylistSort != model.SortingDesc {
368+
allSnippets = allSnippets[:feed.PageSize]
369+
} else {
370+
allSnippets = allSnippets[len(allSnippets)-feed.PageSize:]
366371
}
367372
}
373+
374+
snippets := map[string]*youtube.PlaylistItemSnippet{}
375+
for _, snippet := range allSnippets {
376+
snippets[snippet.ResourceId.VideoId] = snippet
377+
}
378+
379+
// Query video descriptions from the list of ids
380+
if err := yt.queryVideoDescriptions(ctx, snippets, feed); err != nil {
381+
return err
382+
}
383+
384+
return nil
368385
}
369386

370387
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
374391
}
375392

376393
feed := &model.Feed{
377-
ItemID: info.ItemID,
378-
Provider: info.Provider,
379-
LinkType: info.LinkType,
380-
Format: cfg.Format,
381-
Quality: cfg.Quality,
382-
PageSize: cfg.PageSize,
383-
UpdatedAt: time.Now().UTC(),
394+
ItemID: info.ItemID,
395+
Provider: info.Provider,
396+
LinkType: info.LinkType,
397+
Format: cfg.Format,
398+
Quality: cfg.Quality,
399+
PageSize: cfg.PageSize,
400+
PlaylistSort: cfg.PlaylistSort,
401+
UpdatedAt: time.Now().UTC(),
384402
}
385403

386404
if feed.PageSize == 0 {

pkg/config/config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ type Feed struct {
4545
YouTubeDLArgs []string `toml:"youtube_dl_args"`
4646
// Included in OPML file
4747
OPML bool `toml:"opml"`
48+
// Playlist sort
49+
PlaylistSort model.Sorting `toml:"playlist_sort"`
4850
}
4951

5052
type Filters struct {
@@ -237,5 +239,9 @@ func (c *Config) applyDefaults(configPath string) {
237239
if feed.PageSize == 0 {
238240
feed.PageSize = model.DefaultPageSize
239241
}
242+
243+
if feed.PlaylistSort == "" {
244+
feed.PlaylistSort = model.SortingAsc
245+
}
240246
}
241247
}

pkg/config/config_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ timeout = 15
4040
format = "audio"
4141
quality = "low"
4242
filters = { title = "regex for title here" }
43+
playlist_sort = "desc"
4344
clean = { keep_last = 10 }
4445
[feeds.XYZ.custom]
4546
cover_art = "http://img"
@@ -80,6 +81,7 @@ timeout = 15
8081
assert.EqualValues(t, "low", feed.Quality)
8182
assert.EqualValues(t, "regex for title here", feed.Filters.Title)
8283
assert.EqualValues(t, 10, feed.Clean.KeepLast)
84+
assert.EqualValues(t, model.SortingDesc, feed.PlaylistSort)
8385

8486
assert.EqualValues(t, "http://img", feed.Custom.CoverArt)
8587
assert.EqualValues(t, "high", feed.Custom.CoverArtQuality)

pkg/model/feed.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ const (
2020
FormatVideo = Format("video")
2121
)
2222

23+
// Playlist sorting style
24+
type Sorting string
25+
26+
const (
27+
SortingDesc = Sorting("desc")
28+
SortingAsc = Sorting("asc")
29+
)
30+
2331
type Episode struct {
2432
// ID of episode
2533
ID string `json:"id"`
@@ -54,6 +62,7 @@ type Feed struct {
5462
ItemURL string `json:"item_url"` // Platform specific URL
5563
Episodes []*Episode `json:"-"` // Array of episodes
5664
UpdatedAt time.Time `json:"updated_at"`
65+
PlaylistSort Sorting `json:"playlist_sort"`
5766
}
5867

5968
type EpisodeStatus string

0 commit comments

Comments
 (0)