134 lines
4.6 KiB
Python
134 lines
4.6 KiB
Python
import copy
|
|
from typing import Any
|
|
from typing import Dict
|
|
from typing import Optional
|
|
from typing import Set
|
|
|
|
from yt_dlp.utils import sanitize_filename
|
|
|
|
from ytdl_sub.entries.entry import Entry
|
|
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
|
from ytdl_sub.entries.variables.override_variables import SUBSCRIPTION_NAME
|
|
from ytdl_sub.script.parser import parse
|
|
from ytdl_sub.utils.scriptable import Scriptable
|
|
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
|
|
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
|
|
|
|
|
|
class Overrides(DictFormatterValidator, Scriptable):
|
|
"""
|
|
Optional. This section allows you to define variables that can be used in any string formatter.
|
|
For example, if you want your file and thumbnail files to match without copy-pasting a large
|
|
format string, you can define something like:
|
|
|
|
.. code-block:: yaml
|
|
|
|
presets:
|
|
my_example_preset:
|
|
overrides:
|
|
output_directory: "/path/to/media"
|
|
custom_file_name: "{upload_year}.{upload_month_padded}.{upload_day_padded}.{title_sanitized}"
|
|
|
|
# Then use the override variables in the output options
|
|
output_options:
|
|
output_directory: "{output_directory}"
|
|
file_name: "{custom_file_name}.{ext}"
|
|
thumbnail_name: "{custom_file_name}.{thumbnail_ext}"
|
|
|
|
Override variables can contain explicit values and other variables, including both override
|
|
and source variables.
|
|
|
|
In addition, any override variable defined will automatically create a ``sanitized`` variable
|
|
for use. In the example above, ``output_directory_sanitized`` will exist and perform
|
|
sanitization on the value when used.
|
|
"""
|
|
|
|
@classmethod
|
|
def partial_validate(cls, name: str, value: Any) -> None:
|
|
dict_formatter = DictFormatterValidator(name=name, value=value)
|
|
_ = [parse(format_string) for format_string in dict_formatter.dict_with_format_strings]
|
|
|
|
# pylint: enable=line-too-long
|
|
|
|
def _add_override_variable(self, key_name: str, format_string: str, sanitize: bool = False):
|
|
if sanitize:
|
|
key_name = f"{key_name}_sanitized"
|
|
format_string = sanitize_filename(format_string)
|
|
|
|
self._value[key_name] = StringFormatterValidator(
|
|
name="__should_never_fail__",
|
|
value=format_string,
|
|
)
|
|
|
|
def __init__(self, name, value):
|
|
DictFormatterValidator.__init__(self, name, value)
|
|
Scriptable.__init__(self)
|
|
|
|
# Add sanitized overrides
|
|
for key in self._keys:
|
|
self._add_override_variable(
|
|
key_name=key,
|
|
format_string=self._value[key].format_string,
|
|
sanitize=True,
|
|
)
|
|
|
|
if SUBSCRIPTION_NAME not in self._value:
|
|
for sanitized in [True, False]:
|
|
self._add_override_variable(
|
|
key_name=SUBSCRIPTION_NAME,
|
|
format_string=self.subscription_name,
|
|
sanitize=sanitized,
|
|
)
|
|
|
|
self.unresolvable.add(VARIABLES.entry_metadata.variable_name)
|
|
|
|
def initialize_script(self, unresolved_variables: Dict[str, str]) -> None:
|
|
self.script.add(dict(self.dict_with_format_strings, **unresolved_variables))
|
|
self.unresolvable.update(set(unresolved_variables.keys()))
|
|
|
|
self.update_script()
|
|
|
|
@property
|
|
def subscription_name(self) -> str:
|
|
"""
|
|
Returns
|
|
-------
|
|
Name of the subscription
|
|
"""
|
|
return self._root_name
|
|
|
|
def apply_formatter(
|
|
self,
|
|
formatter: StringFormatterValidator,
|
|
entry: Optional[Entry] = None,
|
|
function_overrides: Dict[str, str] = None,
|
|
) -> str:
|
|
"""
|
|
Parameters
|
|
----------
|
|
formatter
|
|
Formatter to apply
|
|
entry
|
|
Optional. Entry to add source variables to the formatter
|
|
function_overrides
|
|
Optional. Explicit values to override the overrides themselves and source variables
|
|
|
|
Returns
|
|
-------
|
|
The format_string after .format has been called
|
|
"""
|
|
if entry:
|
|
script = copy.deepcopy(entry.script)
|
|
unresolvable = entry.unresolvable
|
|
else:
|
|
script = copy.deepcopy(self.script)
|
|
unresolvable = self.unresolvable
|
|
|
|
if function_overrides:
|
|
script.add(function_overrides)
|
|
|
|
return str(
|
|
script.add({"tmp_var": formatter.format_string}).resolve(unresolvable=unresolvable)[
|
|
"tmp_var"
|
|
]
|
|
)
|