diff --git a/src/ytdl_sub/downloaders/source_plugin.py b/src/ytdl_sub/downloaders/source_plugin.py index 167f67fd..f5357fa5 100644 --- a/src/ytdl_sub/downloaders/source_plugin.py +++ b/src/ytdl_sub/downloaders/source_plugin.py @@ -17,7 +17,7 @@ from ytdl_sub.entries.entry import Entry from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive -class SourcePluginExtension(Plugin[TOptionsValidator], ABC): +class SourcePluginExtension(Plugin[TOptionsValidator], Generic[TOptionsValidator], ABC): """ Plugins that get added automatically by using a downloader. Downloader options are the plugin options. diff --git a/src/ytdl_sub/downloaders/url/downloader.py b/src/ytdl_sub/downloaders/url/downloader.py index 984aaded..5fc8c60b 100644 --- a/src/ytdl_sub/downloaders/url/downloader.py +++ b/src/ytdl_sub/downloaders/url/downloader.py @@ -42,7 +42,30 @@ class URLDownloadState: self.entries_downloaded = 0 -class UrlDownloaderThumbnailPlugin(SourcePluginExtension): +class UrlDownloaderBasePluginExtension(SourcePluginExtension[MultiUrlValidator]): + def _match_entry_to_url_validator(self, entry: Entry) -> UrlValidator: + """ + Handle matching a URL to its original validator. This is for .info.json updates + when older entries have missing variables + """ + input_url_idx = entry.get(v.ytdl_sub_input_url_index, int) + entry_input_url = entry.get(v.ytdl_sub_input_url, str) + + if 0 <= input_url_idx < len(self.plugin_options.urls.list): + validator = self.plugin_options.urls.list[input_url_idx] + if self.overrides.apply_formatter(validator.url) == entry_input_url: + return validator + + # Match the first validator based on the URL, if one exists + for validator in self.plugin_options.urls.list: + if self.overrides.apply_formatter(validator.url) == entry_input_url: + return validator + + # Return the first validator if none exist + return self.plugin_options.urls.list[0] + + +class UrlDownloaderThumbnailPlugin(UrlDownloaderBasePluginExtension): def __init__( self, options: MultiUrlValidator, @@ -134,15 +157,13 @@ class UrlDownloaderThumbnailPlugin(SourcePluginExtension): try_convert_download_thumbnail(entry=entry) self._download_url_thumbnails( - collection_url=self.plugin_options.urls.list[ - entry.get(v.ytdl_sub_input_url_index, int) - ], + collection_url=self._match_entry_to_url_validator(entry=entry), entry=entry, ) return entry -class UrlDownloaderCollectionVariablePlugin(SourcePluginExtension): +class UrlDownloaderCollectionVariablePlugin(UrlDownloaderBasePluginExtension): def __init__( self, options: MultiUrlValidator, @@ -160,7 +181,7 @@ class UrlDownloaderCollectionVariablePlugin(SourcePluginExtension): """ Add collection variables to the entry """ - collection_url = self.plugin_options.urls.list[entry.get(v.ytdl_sub_input_url_index, int)] + collection_url = self._match_entry_to_url_validator(entry=entry) entry.add(collection_url.variables.dict_with_format_strings) return entry diff --git a/src/ytdl_sub/entries/script/variable_definitions.py b/src/ytdl_sub/entries/script/variable_definitions.py index 5f2a991d..4fc9e29e 100644 --- a/src/ytdl_sub/entries/script/variable_definitions.py +++ b/src/ytdl_sub/entries/script/variable_definitions.py @@ -756,7 +756,9 @@ class YtdlSubVariableDefinitions(ABC): :description: The index of the input URL as defined in the subscription, top-most being the 0th index. """ - return IntegerVariable(variable_name="ytdl_sub_input_url_index", definition="{ %int(0) }") + # init as -1 so if prior downloaded entries are known when they do not have this value + # in their .info.json + return IntegerVariable(variable_name="ytdl_sub_input_url_index", definition="{ %int(-1) }") @cached_property def ytdl_sub_input_url_count(self: "VariableDefinitions") -> IntegerVariable: