From c29cca2b3dddc7a9319fa1e2685ecc801f8e6a69 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Mon, 8 Jan 2024 22:51:42 -0800 Subject: [PATCH] [FEATURE] YouTube playlists to fetch playlist uploader's poster + fanart (#887) Implements https://github.com/jmbannon/ytdl-sub/issues/756 TV Show presets whose URL is a playlist will try to get the playlist uploader's poster and fanart. --- src/ytdl_sub/downloaders/url/downloader.py | 14 +++++++------- src/ytdl_sub/prebuilt_presets/helpers/url.yaml | 5 +++++ .../tv_show/tv_show_collection.yaml | 5 +++++ .../chapters/test_chapters_from_comments.json | 2 +- .../test_chapters_sb_and_embedded_subs.json | 2 +- .../youtube/test_playlist.json | 2 ++ .../youtube/test_playlist_archive_migrated.json | 2 ++ .../youtube/test_playlist.txt | 2 ++ 8 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/ytdl_sub/downloaders/url/downloader.py b/src/ytdl_sub/downloaders/url/downloader.py index b1be016b..a0ceb535 100644 --- a/src/ytdl_sub/downloaders/url/downloader.py +++ b/src/ytdl_sub/downloaders/url/downloader.py @@ -112,13 +112,6 @@ class UrlDownloaderThumbnailPlugin(SourcePluginExtension): directory, run this function. This lets the downloader add any extra files directly to the output directory, for things like YT channel image, banner. """ - if playlist_metadata := entry.get(v.playlist_metadata, dict): - self._download_parent_thumbnails( - thumbnail_list_info=collection_url.playlist_thumbnails, - entry=entry, - parent=EntryParent(playlist_metadata, working_directory=self.working_directory), - ) - if source_metadata := entry.get(v.source_metadata, dict): self._download_parent_thumbnails( thumbnail_list_info=collection_url.source_thumbnails, @@ -126,6 +119,13 @@ class UrlDownloaderThumbnailPlugin(SourcePluginExtension): parent=EntryParent(source_metadata, working_directory=self.working_directory), ) + if playlist_metadata := entry.get(v.playlist_metadata, dict): + self._download_parent_thumbnails( + thumbnail_list_info=collection_url.playlist_thumbnails, + entry=entry, + parent=EntryParent(playlist_metadata, working_directory=self.working_directory), + ) + def modify_entry(self, entry: Entry) -> Optional[Entry]: """ Use the entry to download thumbnails (or move if LATEST_ENTRY). diff --git a/src/ytdl_sub/prebuilt_presets/helpers/url.yaml b/src/ytdl_sub/prebuilt_presets/helpers/url.yaml index 746578ea..787e0713 100644 --- a/src/ytdl_sub/prebuilt_presets/helpers/url.yaml +++ b/src/ytdl_sub/prebuilt_presets/helpers/url.yaml @@ -20,6 +20,11 @@ presets: uid: "avatar_uncropped" - name: "{banner_uncropped_thumbnail_file_name}" uid: "banner_uncropped" + source_thumbnails: + - name: "{avatar_uncropped_thumbnail_file_name}" + uid: "avatar_uncropped" + - name: "{banner_uncropped_thumbnail_file_name}" + uid: "banner_uncropped" - url: "{url2}" - url: "{url3}" - url: "{url4}" diff --git a/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml b/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml index 1b374d33..e54e07d2 100644 --- a/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml +++ b/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml @@ -34,6 +34,11 @@ presets: uid: "avatar_uncropped" - name: "{tv_show_fanart_file_name}" uid: "banner_uncropped" + source_thumbnails: + - name: "{tv_show_poster_file_name}" + uid: "avatar_uncropped" + - name: "{tv_show_fanart_file_name}" + uid: "banner_uncropped" output_directory_nfo_tags: tags: diff --git a/tests/resources/expected_downloads_summaries/plugins/chapters/test_chapters_from_comments.json b/tests/resources/expected_downloads_summaries/plugins/chapters/test_chapters_from_comments.json index 1ff13886..49314662 100644 --- a/tests/resources/expected_downloads_summaries/plugins/chapters/test_chapters_from_comments.json +++ b/tests/resources/expected_downloads_summaries/plugins/chapters/test_chapters_from_comments.json @@ -1,6 +1,6 @@ { ".ytdl-sub-chapters_from_comments-download-archive.json": "2510b2ff3c54aa4813a4f23ea079e1ec", "JMC/Move 78 - Automated Improvisation [Full Album].jpg": "c12e6a6f242680d1096a1a99d74a62c6", - "JMC/Move 78 - Automated Improvisation [Full Album].mp4": "f401b98c332b76ee1c87065e195d73ce", + "JMC/Move 78 - Automated Improvisation [Full Album].mp4": "068526b2d8f85fdcf914df3e23d0b1fa", "JMC/Move 78 - Automated Improvisation [Full Album].nfo": "039268e97673a6f2b391772ec3b52fac" } \ No newline at end of file diff --git a/tests/resources/expected_downloads_summaries/plugins/test_chapters_sb_and_embedded_subs.json b/tests/resources/expected_downloads_summaries/plugins/test_chapters_sb_and_embedded_subs.json index f6777ba6..03a1f924 100644 --- a/tests/resources/expected_downloads_summaries/plugins/test_chapters_sb_and_embedded_subs.json +++ b/tests/resources/expected_downloads_summaries/plugins/test_chapters_sb_and_embedded_subs.json @@ -1,6 +1,6 @@ { ".ytdl-sub-sponsorblock_with_embedded_subs_test-download-archive.json": "2cb4b9586fd5bb7f1fed76ed9195e6e4", "JMC/This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.jpg": "b5353a824a4800cc26f884e3025ed969", - "JMC/This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.mp4": "8c12640f0c5c280c7a77423431b4ecb1", + "JMC/This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.mp4": "526b6df52a8aaf11dfe56f25ac35a567", "JMC/This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.nfo": "ae73ec18a9f0e5a54c90061ccd32e7f4" } \ No newline at end of file diff --git a/tests/resources/expected_downloads_summaries/youtube/test_playlist.json b/tests/resources/expected_downloads_summaries/youtube/test_playlist.json index c4fb6cca..872a49bd 100644 --- a/tests/resources/expected_downloads_summaries/youtube/test_playlist.json +++ b/tests/resources/expected_downloads_summaries/youtube/test_playlist.json @@ -12,6 +12,8 @@ "JMC/Season 01/s01.e11032101 - Jesse's Minecraft Server [Trailer - Mar.21].info.json": "INFO_JSON", "JMC/Season 01/s01.e11032101 - Jesse's Minecraft Server [Trailer - Mar.21].mp4": "7f1a1d5c1d94938a9b6f565e8159c3d6", "JMC/Season 01/s01.e11032101 - Jesse's Minecraft Server [Trailer - Mar.21].nfo": "c56083e2f3545fa2cafc4d67cbfdacf8", + "JMC/fanart.jpg": "129c6639b47299bc48062f0365e670ee", + "JMC/poster.jpg": "5de28eea5a921a041452ab3ce1041f73", "JMC/season01-poster.jpg": "e7830aa8a64b0cde65ba3f7e5fc56530", "JMC/tvshow.nfo": "e92e4a2c01522dd9a9c3423f0f9304dc" } \ No newline at end of file diff --git a/tests/resources/expected_downloads_summaries/youtube/test_playlist_archive_migrated.json b/tests/resources/expected_downloads_summaries/youtube/test_playlist_archive_migrated.json index c5490aa6..81618c34 100644 --- a/tests/resources/expected_downloads_summaries/youtube/test_playlist_archive_migrated.json +++ b/tests/resources/expected_downloads_summaries/youtube/test_playlist_archive_migrated.json @@ -12,6 +12,8 @@ "JMC/Season 01/s01.e11032101 - Jesse's Minecraft Server [Trailer - Mar.21].info.json": "INFO_JSON", "JMC/Season 01/s01.e11032101 - Jesse's Minecraft Server [Trailer - Mar.21].mp4": "7f1a1d5c1d94938a9b6f565e8159c3d6", "JMC/Season 01/s01.e11032101 - Jesse's Minecraft Server [Trailer - Mar.21].nfo": "c56083e2f3545fa2cafc4d67cbfdacf8", + "JMC/fanart.jpg": "129c6639b47299bc48062f0365e670ee", + "JMC/poster.jpg": "5de28eea5a921a041452ab3ce1041f73", "JMC/season01-poster.jpg": "e7830aa8a64b0cde65ba3f7e5fc56530", "JMC/tvshow.nfo": "e92e4a2c01522dd9a9c3423f0f9304dc" } \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/youtube/test_playlist.txt b/tests/resources/transaction_log_summaries/youtube/test_playlist.txt index 3213a124..ae53c14d 100644 --- a/tests/resources/transaction_log_summaries/youtube/test_playlist.txt +++ b/tests/resources/transaction_log_summaries/youtube/test_playlist.txt @@ -2,6 +2,8 @@ Files created: ---------------------------------------- {output_directory} .ytdl-sub-music_video_playlist_test-download-archive.json + fanart.jpg + poster.jpg season01-poster.jpg tvshow.nfo NFO tags: