This commit is contained in:
Jesse Bannon 2025-12-27 12:02:49 -08:00
parent a6702dc723
commit 4b7d6ae12b
7 changed files with 39 additions and 36 deletions

3
.gitignore vendored
View file

@ -146,8 +146,9 @@ docker/testing/volumes
.local/
.ytdl-sub-working-directory
.ytdl-sub-lock
ffmpeg.exe
ffprobe.exe
tools/docgen/out
tools/docgen/out

View file

@ -220,6 +220,9 @@ class PluginMapping:
@classmethod
def name_of(cls, plugin_options: OptionsValidator) -> str:
"""
Returns plugin definition's name.
"""
for name, plugin_type in cls._MAPPING.items():
if plugin_type.plugin_options_type == plugin_options.__class__:
return name

View file

@ -68,6 +68,9 @@ class PresetPlugins:
yield plugin_options, added_variables, modified_variables
def get_all_variables(self, additional_options: List[OptionsValidator]) -> Set[str]:
"""
Returns set of all added and modified variables' names.
"""
all_variables: Set[str] = set()
for _, added, modified in self.get_added_and_modified_variables(additional_options):
all_variables.update(added)

View file

@ -88,10 +88,12 @@ def _override_variables(overrides: Overrides) -> Set[str]:
class VariableValidation:
def __init__(
self,
overrides: Overrides,
downloader_options: MultiUrlValidator,
output_options: OutputOptions,
plugins: PresetPlugins,
):
self.overrides = overrides
self.downloader_options = downloader_options
self.output_options = output_options
self.plugins = plugins
@ -100,9 +102,10 @@ class VariableValidation:
self.resolved_variables: Set[str] = set()
self.unresolved_variables: Set[str] = set()
def initialize_preset_overrides(
self._initialize_mock_script()
def _initialize_mock_script(
self,
overrides: Overrides,
) -> "VariableValidation":
plugin_variables = self.plugins.get_all_variables(
additional_options=[self.output_options, self.downloader_options]
@ -113,13 +116,14 @@ class VariableValidation:
# 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()) | set(list(overrides.initial_variables().keys()))
set(_DUMMY_ENTRY_VARIABLES.keys())
| set(list(self.overrides.initial_variables().keys()))
) - self.unresolved_variables
# copy the script and mock entry variables
self.script = copy.deepcopy(overrides.script)
self.script = copy.deepcopy(self.overrides.script)
self.script.add(
variables=_add_dummy_overrides(overrides=overrides)
variables=_add_dummy_overrides(overrides=self.overrides)
| _add_dummy_variables(variables=plugin_variables)
| _DUMMY_ENTRY_VARIABLES
)

View file

@ -103,15 +103,12 @@ 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()
)
self._validated_dict = VariableValidation(
overrides=self.overrides,
downloader_options=self.downloader_options,
output_options=self.output_options,
plugins=self.plugins,
).ensure_proper_usage()
@property
def download_archive(self) -> EnhancedDownloadArchive:
@ -258,4 +255,9 @@ class BaseSubscription(ABC):
return self._preset_options.yaml
def resolved_yaml(self):
"""
Returns
-------
Human-readable, condensed YAML definition of the subscription.
"""
return self._validated_dict

View file

@ -268,21 +268,21 @@ def validate_formatters(
"""
resolved_dict: Dict = {}
if isinstance(validator, DictValidator):
resolved_dict[validator._leaf_name] = {}
resolved_dict[validator.leaf_name] = {}
# 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 validator_value in validator._validator_dict.values():
resolved_dict[validator._leaf_name] |= validate_formatters(
resolved_dict[validator.leaf_name] |= validate_formatters(
script=script,
unresolved_variables=unresolved_variables,
validator=validator_value,
)
# pylint: enable=protected-access
elif isinstance(validator, ListValidator):
resolved_dict[validator._leaf_name] = []
resolved_dict[validator.leaf_name] = []
for list_value in validator.list:
resolved_dict[validator._leaf_name].append(
resolved_dict[validator.leaf_name].append(
validate_formatters(
script=script,
unresolved_variables=unresolved_variables,
@ -290,20 +290,20 @@ def validate_formatters(
)
)
elif isinstance(validator, (StringFormatterValidator, OverridesStringFormatterValidator)):
resolved_dict[validator._leaf_name] = _validate_formatter(
resolved_dict[validator.leaf_name] = _validate_formatter(
mock_script=script,
unresolved_variables=unresolved_variables,
formatter_validator=validator,
)
elif isinstance(validator, (DictFormatterValidator, OverridesDictFormatterValidator)):
resolved_dict[validator._leaf_name] = {}
for key, validator_value in validator.dict.items():
resolved_dict[validator._leaf_name] |= _validate_formatter(
resolved_dict[validator.leaf_name] = {}
for validator_value in validator.dict.values():
resolved_dict[validator.leaf_name] |= _validate_formatter(
mock_script=script,
unresolved_variables=unresolved_variables,
formatter_validator=validator_value,
)
else:
resolved_dict[validator._leaf_name] = validator._value
resolved_dict[validator.leaf_name] = validator._value
return resolved_dict

View file

@ -95,21 +95,11 @@ class Validator(ABC):
@final
@property
def _root_name(self) -> str:
def leaf_name(self) -> str:
"""
Returns
-------
"first" from the first.element.of.the.name
"""
return self._name.split(".")[0]
@final
@property
def _leaf_name(self) -> str:
"""
Returns
-------
"first" from the first.element.of.the.name
"name" from the first.element.of.the.name
"""
return self._name.split(".")[-1]