From db1af8bd5f93e81cfd3d578d26e329f43ad63a04 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Mon, 12 Sep 2022 22:41:53 -0700 Subject: [PATCH] validate with variables, need to add downloader logic in preset --- pyproject.toml | 1 + src/ytdl_sub/config/preset_options.py | 39 +++++++++++++++++++ src/ytdl_sub/downloaders/downloader.py | 3 +- .../downloaders/generic/collection.py | 26 +++++++++++-- src/ytdl_sub/entries/entry_parent.py | 10 ++++- src/ytdl_sub/plugins/plugin.py | 32 +-------------- 6 files changed, 76 insertions(+), 35 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d11f30ae..1f0df34f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ disable = [ "R0903", # too-few-public-methods "R0801", # similar lines "R0913", # Too many arguments + "R0901", # too-many-ancestors "W0511", # TODO ] diff --git a/src/ytdl_sub/config/preset_options.py b/src/ytdl_sub/config/preset_options.py index d1ddb35a..ed96b333 100644 --- a/src/ytdl_sub/config/preset_options.py +++ b/src/ytdl_sub/config/preset_options.py @@ -1,4 +1,6 @@ +from abc import ABC from typing import Dict +from typing import List from typing import Optional from yt_dlp.utils import sanitize_filename @@ -13,6 +15,43 @@ from ytdl_sub.validators.validators import BoolValidator from ytdl_sub.validators.validators import LiteralDictValidator +# pylint: disable=no-self-use +# pylint: disable=unused-argument +class AddsVariablesMixin(ABC): + """ + Mixin for parts of the Preset that adds source variables + """ + + def added_source_variables(self) -> List[str]: + """ + If the plugin adds source variables, list them here. + + Returns + ------- + List of added source variables this plugin creates + """ + return [] + + def validate_with_variables( + self, source_variables: List[str], override_variables: List[str] + ) -> None: + """ + Optional validation after init with the session's source and override variables. + + Parameters + ---------- + source_variables + Available source variables when running the plugin + override_variables + Available override variables when running the plugin + """ + return None + + +# pylint: enable=no-self-use +# pylint: enable=unused-argument + + class YTDLOptions(LiteralDictValidator): """ Optional. This section allows you to add any ytdl argument to ytdl-sub's downloader. diff --git a/src/ytdl_sub/downloaders/downloader.py b/src/ytdl_sub/downloaders/downloader.py index cdb85691..7b966a22 100644 --- a/src/ytdl_sub/downloaders/downloader.py +++ b/src/ytdl_sub/downloaders/downloader.py @@ -21,6 +21,7 @@ import yt_dlp as ytdl from yt_dlp.utils import ExistingVideoReached from yt_dlp.utils import RejectedVideoReached +from ytdl_sub.config.preset_options import AddsVariablesMixin from ytdl_sub.config.preset_options import Overrides from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder from ytdl_sub.entries.base_entry import BaseEntry @@ -36,7 +37,7 @@ from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadAr download_logger = Logger.get(name="downloader") -class DownloaderValidator(StrictDictValidator, ABC): +class DownloaderValidator(StrictDictValidator, AddsVariablesMixin, ABC): """ Placeholder class to define downloader options """ diff --git a/src/ytdl_sub/downloaders/generic/collection.py b/src/ytdl_sub/downloaders/generic/collection.py index 516a7442..ef42e64b 100644 --- a/src/ytdl_sub/downloaders/generic/collection.py +++ b/src/ytdl_sub/downloaders/generic/collection.py @@ -115,6 +115,28 @@ class CollectionDownloadOptions(DownloaderValidator): """ return self._urls + def added_source_variables(self) -> List[str]: + """ + Returns + ------- + List of variables added. The first collection url always contains all the variables. + """ + return list(self._urls.list[0].variables.keys()) + + def validate_with_variables( + self, source_variables: List[str], override_variables: List[str] + ) -> None: + """ + Ensures new variables added are not existing variables + """ + # TODO: Make sure they resolve + for added_source_var in self.added_source_variables(): + if added_source_var in source_variables: + raise self._validation_exception( + f"'{added_source_var}' cannot be used as a variable name because it " + f"is an existing source variable" + ) + class CollectionDownloader(Downloader[CollectionDownloadOptions, Entry]): downloader_options_type = CollectionDownloadOptions @@ -141,9 +163,7 @@ class CollectionDownloader(Downloader[CollectionDownloadOptions, Entry]): leaf_children.append(parent.child_entries[idx]) for leaf_child in leaf_children: - leaf_child.add_variables( - parent.get_children_entry_variables_to_add(parent.child_entries) - ) + leaf_child.add_variables(parent.get_children_entry_variables_to_add()) leaf_child.add_variables(collection_url.variables) return leaf_children diff --git a/src/ytdl_sub/entries/entry_parent.py b/src/ytdl_sub/entries/entry_parent.py index 03564558..830e2f94 100644 --- a/src/ytdl_sub/entries/entry_parent.py +++ b/src/ytdl_sub/entries/entry_parent.py @@ -35,6 +35,9 @@ class EntryParent(BaseEntry): # pylint: enable=no-self-use def read_nested_children_from_entry_dicts(self, entry_dicts: List[Dict]): + """ + Populates a tree of EntryParents that belong to this instance + """ child_entries: List["EntryParent"] = [] for entry_dict in entry_dicts: @@ -155,4 +158,9 @@ class EntryParent(BaseEntry): return entry_parent def to_entry(self) -> Entry: - return Entry(entry_dict=self._kwargs, working_directory=self.working_directory()) + """ + Returns + ------- + EntryParent converted to Entry + """ + return Entry(entry_dict=self._kwargs, working_directory=self._working_directory) diff --git a/src/ytdl_sub/plugins/plugin.py b/src/ytdl_sub/plugins/plugin.py index 8c555641..7ee6d8a0 100644 --- a/src/ytdl_sub/plugins/plugin.py +++ b/src/ytdl_sub/plugins/plugin.py @@ -8,6 +8,7 @@ from typing import Type from typing import TypeVar from typing import final +from ytdl_sub.config.preset_options import AddsVariablesMixin from ytdl_sub.config.preset_options import Overrides from ytdl_sub.entries.entry import Entry from ytdl_sub.utils.file_handler import FileMetadata @@ -39,40 +40,11 @@ class PluginPriority: return self.modify_entry >= PluginPriority.MODIFY_ENTRY_AFTER_SPLIT -class PluginOptions(StrictDictValidator): +class PluginOptions(StrictDictValidator, AddsVariablesMixin, ABC): """ Class that defines the parameters to a plugin """ - # pylint: disable=no-self-use - def added_source_variables(self) -> List[str]: - """ - If the plugin adds source variables, list them here. - - Returns - ------- - List of added source variables this plugin creates - """ - return [] - - # pylint: disable=unused-argument - def validate_with_variables( - self, source_variables: List[str], override_variables: List[str] - ) -> None: - """ - Optional validation after init with the session's source and override variables. - - Parameters - ---------- - source_variables - Available source variables when running the plugin - override_variables - Available override variables when running the plugin - """ - return None - - # pylint: enable=no-self-use,unused-argument - PluginOptionsT = TypeVar("PluginOptionsT", bound=PluginOptions)