From e3bdc730134ae47f51715cb26ca136aa06ab2012 Mon Sep 17 00:00:00 2001 From: Svilen Markov <7613769+svilenmarkov@users.noreply.github.com> Date: Fri, 6 Dec 2024 10:53:08 +0000 Subject: [PATCH] Allow specifying playlist in videos widget Co-authored-by: vishalkadam47 --- docs/configuration.md | 10 +++++++++- internal/glance/widget-videos.go | 25 ++++++++++++++----------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 6ef4b87..2c1b924 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -587,7 +587,15 @@ Preview: | video-url-template | string | no | https://www.youtube.com/watch?v={VIDEO-ID} | ##### `channels` -A list of channel IDs. One way of getting the ID of a channel is going to the channel's page and clicking on its description: +A list of channel or playlist IDs. To specify a playlist, use the `playlist:` prefix like such: + +```yaml +channels: + - playlist:PL8mG-RkN2uTyZZ00ObwZxxoG_nJbs3qec + - playlist:PL8mG-RkN2uTxTK4m_Vl2dYR9yE41kRdBg +``` + +One way of getting the ID of a channel is going to the channel's page and clicking on its description: ![](images/videos-channel-description-example.png) diff --git a/internal/glance/widget-videos.go b/internal/glance/widget-videos.go index e1f3b14..398989f 100644 --- a/internal/glance/widget-videos.go +++ b/internal/glance/widget-videos.go @@ -12,6 +12,8 @@ import ( "time" ) +const videosWidgetPlaylistPrefix = "playlist:" + var ( videosWidgetTemplate = mustParseTemplate("videos.html", "widget-base.html", "video-card-contents.html") videosWidgetGridTemplate = mustParseTemplate("videos-grid.html", "widget-base.html", "video-card-contents.html") @@ -43,7 +45,7 @@ func (widget *videosWidget) initialize() error { } func (widget *videosWidget) update(ctx context.Context) { - videos, err := FetchYoutubeChannelUploads(widget.Channels, widget.VideoUrlTemplate, widget.IncludeShorts) + videos, err := fetchYoutubeChannelUploads(widget.Channels, widget.VideoUrlTemplate, widget.IncludeShorts) if !widget.canContinueUpdateAfterHandlingErr(err) { return @@ -110,16 +112,19 @@ func (v videoList) sortByNewest() videoList { return v } -func FetchYoutubeChannelUploads(channelIds []string, videoUrlTemplate string, includeShorts bool) (videoList, error) { - requests := make([]*http.Request, 0, len(channelIds)) +func fetchYoutubeChannelUploads(channelOrPlaylistIDs []string, videoUrlTemplate string, includeShorts bool) (videoList, error) { + requests := make([]*http.Request, 0, len(channelOrPlaylistIDs)) - for i := range channelIds { + for i := range channelOrPlaylistIDs { var feedUrl string - if !includeShorts && strings.HasPrefix(channelIds[i], "UC") { - playlistId := strings.Replace(channelIds[i], "UC", "UULF", 1) + if strings.HasPrefix(channelOrPlaylistIDs[i], videosWidgetPlaylistPrefix) { + feedUrl = "https://www.youtube.com/feeds/videos.xml?playlist_id=" + + strings.TrimPrefix(channelOrPlaylistIDs[i], videosWidgetPlaylistPrefix) + } else if !includeShorts && strings.HasPrefix(channelOrPlaylistIDs[i], "UC") { + playlistId := strings.Replace(channelOrPlaylistIDs[i], "UC", "UULF", 1) feedUrl = "https://www.youtube.com/feeds/videos.xml?playlist_id=" + playlistId } else { - feedUrl = "https://www.youtube.com/feeds/videos.xml?channel_id=" + channelIds[i] + feedUrl = "https://www.youtube.com/feeds/videos.xml?channel_id=" + channelOrPlaylistIDs[i] } request, _ := http.NewRequest("GET", feedUrl, nil) @@ -127,20 +132,18 @@ func FetchYoutubeChannelUploads(channelIds []string, videoUrlTemplate string, in } job := newJob(decodeXmlFromRequestTask[youtubeFeedResponseXml](defaultHTTPClient), requests).withWorkers(30) - responses, errs, err := workerPoolDo(job) if err != nil { return nil, fmt.Errorf("%w: %v", errNoContent, err) } - videos := make(videoList, 0, len(channelIds)*15) - + videos := make(videoList, 0, len(channelOrPlaylistIDs)*15) var failed int for i := range responses { if errs[i] != nil { failed++ - slog.Error("Failed to fetch youtube feed", "channel", channelIds[i], "error", errs[i]) + slog.Error("Failed to fetch youtube feed", "channel", channelOrPlaylistIDs[i], "error", errs[i]) continue }