optionally resolve entry formatters

This commit is contained in:
Jesse Bannon 2026-01-23 11:39:27 -08:00
parent 667b8073a1
commit 95a1b9f4f9
4 changed files with 15 additions and 10 deletions

View file

@ -108,7 +108,7 @@ class VariableValidation:
self.unresolved_runtime_variables -= added_variables | modified_variables self.unresolved_runtime_variables -= added_variables | modified_variables
def ensure_proper_usage(self) -> Dict: def ensure_proper_usage(self, partial_resolve_formatters: bool = False) -> Dict:
""" """
Validate variables resolve as plugins are executed, and return Validate variables resolve as plugins are executed, and return
a mock script which contains actualized added variables from the plugins a mock script which contains actualized added variables from the plugins
@ -141,6 +141,7 @@ class VariableValidation:
unresolved_variables=self.unresolved_variables, unresolved_variables=self.unresolved_variables,
unresolved_runtime_variables=self.unresolved_runtime_variables, unresolved_runtime_variables=self.unresolved_runtime_variables,
validator=plugin_options, validator=plugin_options,
partial_resolve_formatters=partial_resolve_formatters,
) )
resolved_subscription |= validate_formatters( resolved_subscription |= validate_formatters(
@ -148,6 +149,7 @@ class VariableValidation:
unresolved_variables=self.unresolved_variables, unresolved_variables=self.unresolved_variables,
unresolved_runtime_variables=self.unresolved_runtime_variables, unresolved_runtime_variables=self.unresolved_runtime_variables,
validator=self.output_options, validator=self.output_options,
partial_resolve_formatters=partial_resolve_formatters,
) )
# TODO: make this a function # TODO: make this a function
@ -156,6 +158,7 @@ class VariableValidation:
unresolved_variables=self.unresolved_variables, unresolved_variables=self.unresolved_variables,
unresolved_runtime_variables=self.unresolved_runtime_variables, unresolved_runtime_variables=self.unresolved_runtime_variables,
validator=self.downloader_options.urls, validator=self.downloader_options.urls,
partial_resolve_formatters=partial_resolve_formatters,
) )
resolved_subscription["download"] = [] resolved_subscription["download"] = []
for url_output in raw_download_output["download"]: for url_output in raw_download_output["download"]:

View file

@ -272,5 +272,5 @@ class BaseSubscription(ABC):
output_options=self.output_options, output_options=self.output_options,
plugins=self.plugins, plugins=self.plugins,
resolution_level=resolution_level, resolution_level=resolution_level,
).ensure_proper_usage() ).ensure_proper_usage(partial_resolve_formatters=True)
return dump_yaml(out) return dump_yaml(out)

View file

@ -13,7 +13,6 @@ from ytdl_sub.script.utils.exceptions import ScriptVariableNotResolved
from ytdl_sub.script.utils.exceptions import UserException from ytdl_sub.script.utils.exceptions import UserException
from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError
from ytdl_sub.utils.exceptions import StringFormattingVariableNotFoundException from ytdl_sub.utils.exceptions import StringFormattingVariableNotFoundException
from ytdl_sub.utils.file_handler import get_md5_hash
from ytdl_sub.utils.script import ScriptUtils from ytdl_sub.utils.script import ScriptUtils
from ytdl_sub.validators.validators import DictValidator from ytdl_sub.validators.validators import DictValidator
from ytdl_sub.validators.validators import ListValidator from ytdl_sub.validators.validators import ListValidator
@ -240,7 +239,7 @@ def _validate_formatter(
unresolved_variables: Set[str], unresolved_variables: Set[str],
unresolved_runtime_variables: Set[str], unresolved_runtime_variables: Set[str],
formatter_validator: Union[StringFormatterValidator, OverridesStringFormatterValidator], formatter_validator: Union[StringFormatterValidator, OverridesStringFormatterValidator],
resolve_partial: bool = True, partial_resolve_entry_formatters: bool,
) -> str: ) -> str:
parsed = formatter_validator.parsed parsed = formatter_validator.parsed
if resolved := parsed.maybe_resolvable: if resolved := parsed.maybe_resolvable:
@ -272,13 +271,11 @@ def _validate_formatter(
f"formatter: {', '.join(sorted(unresolved))}" f"formatter: {', '.join(sorted(unresolved))}"
) )
if resolve_partial and not is_static_formatter: if partial_resolve_entry_formatters and not is_static_formatter:
formatter_hash = get_md5_hash(formatter_validator.format_string)
parsed = mock_script.resolve_partial_once( parsed = mock_script.resolve_partial_once(
variable_definitions={formatter_hash: formatter_validator.parsed}, variable_definitions={"tmp_var": formatter_validator.parsed},
unresolvable=unresolved_variables, unresolvable=unresolved_variables,
)[formatter_hash] )["tmp_var"]
try: try:
if is_static_formatter: if is_static_formatter:
@ -309,6 +306,7 @@ def validate_formatters(
unresolved_variables: Set[str], unresolved_variables: Set[str],
unresolved_runtime_variables: Set[str], unresolved_runtime_variables: Set[str],
validator: Validator, validator: Validator,
partial_resolve_formatters: bool,
) -> Dict: ) -> Dict:
""" """
Ensure all OverridesStringFormatterValidator's only contain variables from the overrides Ensure all OverridesStringFormatterValidator's only contain variables from the overrides
@ -326,6 +324,7 @@ def validate_formatters(
unresolved_variables=unresolved_variables, unresolved_variables=unresolved_variables,
unresolved_runtime_variables=unresolved_runtime_variables, unresolved_runtime_variables=unresolved_runtime_variables,
validator=validator_value, validator=validator_value,
partial_resolve_formatters=partial_resolve_formatters,
) )
elif isinstance(validator, ListValidator): elif isinstance(validator, ListValidator):
resolved_dict[validator.leaf_name] = [] resolved_dict[validator.leaf_name] = []
@ -335,6 +334,7 @@ def validate_formatters(
unresolved_variables=unresolved_variables, unresolved_variables=unresolved_variables,
unresolved_runtime_variables=unresolved_runtime_variables, unresolved_runtime_variables=unresolved_runtime_variables,
validator=list_value, validator=list_value,
partial_resolve_formatters=partial_resolve_formatters,
) )
assert len(list_output) == 1 assert len(list_output) == 1
resolved_dict[validator.leaf_name].append(list(list_output.values())[0]) resolved_dict[validator.leaf_name].append(list(list_output.values())[0])
@ -344,6 +344,7 @@ def validate_formatters(
unresolved_variables=unresolved_variables, unresolved_variables=unresolved_variables,
unresolved_runtime_variables=unresolved_runtime_variables, unresolved_runtime_variables=unresolved_runtime_variables,
formatter_validator=validator, formatter_validator=validator,
partial_resolve_entry_formatters=partial_resolve_formatters,
) )
elif isinstance(validator, (DictFormatterValidator, OverridesDictFormatterValidator)): elif isinstance(validator, (DictFormatterValidator, OverridesDictFormatterValidator)):
resolved_dict[validator.leaf_name] = {} resolved_dict[validator.leaf_name] = {}
@ -353,6 +354,7 @@ def validate_formatters(
unresolved_variables=unresolved_variables, unresolved_variables=unresolved_variables,
unresolved_runtime_variables=unresolved_runtime_variables, unresolved_runtime_variables=unresolved_runtime_variables,
formatter_validator=validator_value, formatter_validator=validator_value,
partial_resolve_entry_formatters=partial_resolve_formatters,
) )
else: else:
resolved_dict[validator.leaf_name] = validator._value resolved_dict[validator.leaf_name] = validator._value

View file

@ -23,7 +23,7 @@ def _ensure_resolved_yaml(
if resolution_level > ResolutionLevel.ORIGINAL: if resolution_level > ResolutionLevel.ORIGINAL:
expected_out["output_options"]["output_directory"] = FilePathTruncater.to_native_filepath( expected_out["output_options"]["output_directory"] = FilePathTruncater.to_native_filepath(
expected_out["output_options"]["output_directory"] str(Path(output_directory) / sub.name)
) )
if "tv_show_directory" in expected_out["overrides"]: if "tv_show_directory" in expected_out["overrides"]: