From 915e29379ad18958e3dc9893773834e644d6bcab Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Mon, 8 Jan 2024 18:53:00 -0800 Subject: [PATCH] [BACKEND] Try to fetch source metadata from uploader_url (#886) Makes it possible to fix https://github.com/jmbannon/ytdl-sub/issues/756 In the case that uploader_url does not equal the input url, keep trying to fetch uploader_url to get all possible metadata that yt-dlp does not provide in a single API call --- src/ytdl_sub/downloaders/ytdlp.py | 20 +++++++++++++++++++- src/ytdl_sub/entries/entry_parent.py | 11 +++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/ytdl_sub/downloaders/ytdlp.py b/src/ytdl_sub/downloaders/ytdlp.py index a7912232..0f43b606 100644 --- a/src/ytdl_sub/downloaders/ytdlp.py +++ b/src/ytdl_sub/downloaders/ytdlp.py @@ -216,11 +216,14 @@ class YTDLP: **kwargs arguments passed directory to YoutubeDL extract_info """ + parent_dict: Dict = {} try: with cls._listen_and_log_downloaded_info_json( working_directory=working_directory, log_prefix=log_prefix_on_info_json_dl ): - _ = cls.extract_info(ytdl_options_overrides=ytdl_options_overrides, **kwargs) + parent_dict = cls.extract_info( + ytdl_options_overrides=ytdl_options_overrides, **kwargs + ) except RejectedVideoReached: cls.logger.debug( "RejectedVideoReached, stopping additional downloads " @@ -234,4 +237,19 @@ class YTDLP: except MaxDownloadsReached: cls.logger.info("MaxDownloadsReached, stopping additional downloads.") + # For YouTube playlists in particular, channel metadata is not fetched. Attempt to get + # channel metadata via grabbing uploader_url info json a max of 3 times + current_iter = 0 + url = kwargs.get("url") + uploader_url = parent_dict.get("uploader_url") + while current_iter < 3 and uploader_url and url != uploader_url: + cls.logger.debug("Attempting to get parent metadata from URL %s", uploader_url) + parent_dict = cls.extract_info( + ytdl_options_overrides=ytdl_options_overrides | {"playlist_items": "0:0"}, + url=uploader_url, + ) + current_iter += 1 + url = uploader_url + uploader_url = parent_dict.get("uploader_url") + return cls._get_entry_dicts_from_info_json_files(working_directory=working_directory) diff --git a/src/ytdl_sub/entries/entry_parent.py b/src/ytdl_sub/entries/entry_parent.py index 6cf7dcb1..232b2ab4 100644 --- a/src/ytdl_sub/entries/entry_parent.py +++ b/src/ytdl_sub/entries/entry_parent.py @@ -157,13 +157,16 @@ class EntryParent(BaseEntry): def _uid_is_uploader_id(parent: "EntryParent"): return parent.uid == parent.uploader_id - top_level_parents = [ - parent for parent in parents if parent.num_children() == 0 and _url_matches(parent) - ] + top_level_parents = [parent for parent in parents if parent.num_children() == 0] # If more than 1 parent exists, assume the uploader_id is the root parent if len(top_level_parents) > 1: - top_level_parents = [parent for parent in parents if _uid_is_uploader_id(parent)] + top_level_parents = [ + parent for parent in top_level_parents if _uid_is_uploader_id(parent) + ] + + if len(top_level_parents) > 1: + top_level_parents = [parent for parent in top_level_parents if _url_matches(parent)] match len(top_level_parents): case 0: