refactored, validation now in subscription
This commit is contained in:
parent
276d1de979
commit
a6702dc723
5 changed files with 92 additions and 58 deletions
|
|
@ -1,5 +1,7 @@
|
|||
from typing import Iterable
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Set
|
||||
from typing import Tuple
|
||||
from typing import Type
|
||||
|
||||
|
|
@ -44,3 +46,31 @@ class PresetPlugins:
|
|||
if plugin_type in plugin_option_types:
|
||||
return self.plugin_options[plugin_option_types.index(plugin_type)]
|
||||
return None
|
||||
|
||||
def get_added_and_modified_variables(
|
||||
self, additional_options: List[OptionsValidator]
|
||||
) -> Iterable[Tuple[OptionsValidator, Set[str], Set[str]]]:
|
||||
"""
|
||||
Iterates and returns the plugin options, added variables, modified variables
|
||||
"""
|
||||
for plugin_options in self.plugin_options + additional_options:
|
||||
added_variables: Set[str] = set()
|
||||
modified_variables: Set[str] = set()
|
||||
|
||||
for plugin_added_variables in plugin_options.added_variables(
|
||||
unresolved_variables=set(),
|
||||
).values():
|
||||
added_variables |= set(plugin_added_variables)
|
||||
|
||||
for plugin_modified_variables in plugin_options.modified_variables().values():
|
||||
modified_variables = plugin_modified_variables
|
||||
|
||||
yield plugin_options, added_variables, modified_variables
|
||||
|
||||
def get_all_variables(self, additional_options: List[OptionsValidator]) -> Set[str]:
|
||||
all_variables: Set[str] = set()
|
||||
for _, added, modified in self.get_added_and_modified_variables(additional_options):
|
||||
all_variables.update(added)
|
||||
all_variables.update(modified)
|
||||
|
||||
return all_variables
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import copy
|
|||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Set
|
||||
|
||||
from mergedeep import mergedeep
|
||||
|
||||
|
|
@ -11,7 +12,6 @@ from ytdl_sub.config.plugin.plugin_mapping import PluginMapping
|
|||
from ytdl_sub.config.plugin.preset_plugins import PresetPlugins
|
||||
from ytdl_sub.config.preset_options import OutputOptions
|
||||
from ytdl_sub.config.preset_options import YTDLOptions
|
||||
from ytdl_sub.config.validators.variable_validation import VariableValidation
|
||||
from ytdl_sub.downloaders.url.validators import MultiUrlValidator
|
||||
from ytdl_sub.prebuilt_presets import PREBUILT_PRESET_NAMES
|
||||
from ytdl_sub.prebuilt_presets import PUBLISHED_PRESET_NAMES
|
||||
|
|
@ -172,6 +172,37 @@ class Preset(_PresetShell):
|
|||
mergedeep.merge({}, *reversed(presets_to_merge), strategy=mergedeep.Strategy.ADDITIVE)
|
||||
)
|
||||
|
||||
def _initialize_overrides_script(self, overrides: Overrides) -> Overrides:
|
||||
"""
|
||||
Do some gymnastics to initialize the Overrides script.
|
||||
"""
|
||||
unresolved_variables: Set[str] = set()
|
||||
|
||||
for (
|
||||
plugin_options,
|
||||
added_variables,
|
||||
modified_variables,
|
||||
) in self.plugins.get_added_and_modified_variables(
|
||||
additional_options=[self.downloader_options, self.output_options]
|
||||
):
|
||||
for added_variable in added_variables:
|
||||
if not overrides.ensure_added_plugin_variable_valid(added_variable=added_variable):
|
||||
# pylint: disable=protected-access
|
||||
raise plugin_options._validation_exception(
|
||||
f"Cannot use the variable name {added_variable} because it exists as a"
|
||||
" built-in ytdl-sub variable name."
|
||||
)
|
||||
# pylint: enable=protected-access
|
||||
|
||||
# Set unresolved as variables that are added but do not exist as
|
||||
# entry/override variables since they are created at run-time
|
||||
unresolved_variables |= added_variables | modified_variables
|
||||
|
||||
# Initialize overrides with unresolved variables + modified variables to throw an error.
|
||||
# For modified variables, this is to prevent a resolve(update=True) to setting any
|
||||
# dependencies until it has been explicitly added
|
||||
return overrides.initialize_script(unresolved_variables=unresolved_variables)
|
||||
|
||||
def __init__(self, config: ConfigValidator, name: str, value: Any):
|
||||
super().__init__(name=name, value=value)
|
||||
|
||||
|
|
@ -192,16 +223,8 @@ class Preset(_PresetShell):
|
|||
)
|
||||
|
||||
self.plugins: PresetPlugins = self._validate_and_get_plugins()
|
||||
self.overrides = self._validate_key(key="overrides", validator=Overrides, default={})
|
||||
|
||||
self.validated_dict = (
|
||||
VariableValidation(
|
||||
downloader_options=self.downloader_options,
|
||||
output_options=self.output_options,
|
||||
plugins=self.plugins,
|
||||
)
|
||||
.initialize_preset_overrides(overrides=self.overrides)
|
||||
.ensure_proper_usage()
|
||||
self.overrides = self._initialize_overrides_script(
|
||||
overrides=self._validate_key(key="overrides", validator=Overrides, default={})
|
||||
)
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -100,48 +100,21 @@ class VariableValidation:
|
|||
self.resolved_variables: Set[str] = set()
|
||||
self.unresolved_variables: Set[str] = set()
|
||||
|
||||
def initialize_preset_overrides(self, overrides: Overrides) -> "VariableValidation":
|
||||
"""
|
||||
Do some gymnastics to initialize the Overrides script.
|
||||
"""
|
||||
override_variables = set(list(overrides.initial_variables().keys()))
|
||||
def initialize_preset_overrides(
|
||||
self,
|
||||
overrides: Overrides,
|
||||
) -> "VariableValidation":
|
||||
plugin_variables = self.plugins.get_all_variables(
|
||||
additional_options=[self.output_options, self.downloader_options]
|
||||
)
|
||||
|
||||
self.unresolved_variables = plugin_variables
|
||||
|
||||
# Set resolved variables as all entry + override variables
|
||||
# at this point to generate every possible added/modified variable
|
||||
self.resolved_variables = set(_DUMMY_ENTRY_VARIABLES.keys()) | override_variables
|
||||
plugin_variables: Set[str] = set()
|
||||
|
||||
for (
|
||||
plugin_options,
|
||||
added_variables,
|
||||
modified_variables,
|
||||
) in _get_added_and_modified_variables(
|
||||
plugins=self.plugins,
|
||||
downloader_options=self.downloader_options,
|
||||
output_options=self.output_options,
|
||||
):
|
||||
|
||||
for added_variable in added_variables:
|
||||
if not overrides.ensure_added_plugin_variable_valid(added_variable=added_variable):
|
||||
# pylint: disable=protected-access
|
||||
raise plugin_options._validation_exception(
|
||||
f"Cannot use the variable name {added_variable} because it exists as a"
|
||||
" built-in ytdl-sub variable name."
|
||||
)
|
||||
# pylint: enable=protected-access
|
||||
|
||||
# Set unresolved as variables that are added but do not exist as
|
||||
# entry/override variables since they are created at run-time
|
||||
self.unresolved_variables |= added_variables | modified_variables
|
||||
plugin_variables |= added_variables | modified_variables
|
||||
|
||||
# Then update resolved variables to reflect that
|
||||
self.resolved_variables -= self.unresolved_variables
|
||||
|
||||
# Initialize overrides with unresolved variables + modified variables to throw an error.
|
||||
# For modified variables, this is to prevent a resolve(update=True) to setting any
|
||||
# dependencies until it has been explicitly added
|
||||
overrides = overrides.initialize_script(unresolved_variables=self.unresolved_variables)
|
||||
self.resolved_variables = (
|
||||
set(_DUMMY_ENTRY_VARIABLES.keys()) | set(list(overrides.initial_variables().keys()))
|
||||
) - self.unresolved_variables
|
||||
|
||||
# copy the script and mock entry variables
|
||||
self.script = copy.deepcopy(overrides.script)
|
||||
|
|
@ -153,9 +126,6 @@ class VariableValidation:
|
|||
|
||||
return self
|
||||
|
||||
def _update_script(self) -> None:
|
||||
_ = self.script.resolve(unresolvable=self.unresolved_variables, update=True)
|
||||
|
||||
def _add_subscription_override_variables(self) -> None:
|
||||
"""
|
||||
Add dummy subscription variables for script validation
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from ytdl_sub.config.plugin.preset_plugins import PresetPlugins
|
|||
from ytdl_sub.config.preset import Preset
|
||||
from ytdl_sub.config.preset_options import OutputOptions
|
||||
from ytdl_sub.config.preset_options import YTDLOptions
|
||||
from ytdl_sub.config.validators.variable_validation import VariableValidation
|
||||
from ytdl_sub.downloaders.url.validators import MultiUrlValidator
|
||||
from ytdl_sub.entries.variables.override_variables import SubscriptionVariables
|
||||
from ytdl_sub.utils.exceptions import SubscriptionPermissionError
|
||||
|
|
@ -88,9 +89,9 @@ class BaseSubscription(ABC):
|
|||
# Add post-archive variables
|
||||
self.overrides.add(
|
||||
{
|
||||
SubscriptionVariables.subscription_has_download_archive(): f"""{{
|
||||
%bool({self.download_archive.num_entries > 0})
|
||||
}}""",
|
||||
SubscriptionVariables.subscription_has_download_archive(): (
|
||||
f"{{%bool({self.download_archive.num_entries > 0})}}"
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -102,6 +103,16 @@ class BaseSubscription(ABC):
|
|||
f"{self.output_directory}"
|
||||
)
|
||||
|
||||
self._validated_dict = (
|
||||
VariableValidation(
|
||||
downloader_options=self.downloader_options,
|
||||
output_options=self.output_options,
|
||||
plugins=self.plugins,
|
||||
)
|
||||
.initialize_preset_overrides(overrides=self.overrides)
|
||||
.ensure_proper_usage()
|
||||
)
|
||||
|
||||
@property
|
||||
def download_archive(self) -> EnhancedDownloadArchive:
|
||||
"""
|
||||
|
|
@ -247,4 +258,4 @@ class BaseSubscription(ABC):
|
|||
return self._preset_options.yaml
|
||||
|
||||
def resolved_yaml(self):
|
||||
return self._preset_options.validated_dict
|
||||
return self._validated_dict
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ def validate_formatters(
|
|||
# pylint: disable=protected-access
|
||||
# Usage of protected variables in other validators is fine. The reason to keep
|
||||
# them protected is for readability when using them in subscriptions.
|
||||
for key, validator_value in validator._validator_dict.items():
|
||||
for validator_value in validator._validator_dict.values():
|
||||
resolved_dict[validator._leaf_name] |= validate_formatters(
|
||||
script=script,
|
||||
unresolved_variables=unresolved_variables,
|
||||
|
|
|
|||
Loading…
Reference in a new issue