This reverts commit 60cdbad8c7.
Caused a breaking change to ytdl_options
This commit is contained in:
parent
60cdbad8c7
commit
c1431c8d55
15 changed files with 100 additions and 74 deletions
|
|
@ -3,8 +3,6 @@ from typing import Dict
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Set
|
from typing import Set
|
||||||
from typing import Type
|
|
||||||
from typing import TypeVar
|
|
||||||
|
|
||||||
from ytdl_sub.entries.entry import Entry
|
from ytdl_sub.entries.entry import Entry
|
||||||
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
||||||
|
|
@ -22,11 +20,10 @@ from ytdl_sub.utils.exceptions import StringFormattingException
|
||||||
from ytdl_sub.utils.exceptions import ValidationException
|
from ytdl_sub.utils.exceptions import ValidationException
|
||||||
from ytdl_sub.utils.script import ScriptUtils
|
from ytdl_sub.utils.script import ScriptUtils
|
||||||
from ytdl_sub.utils.scriptable import Scriptable
|
from ytdl_sub.utils.scriptable import Scriptable
|
||||||
|
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
|
||||||
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
|
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
|
||||||
from ytdl_sub.validators.string_formatter_validators import UnstructuredDictFormatterValidator
|
from ytdl_sub.validators.string_formatter_validators import UnstructuredDictFormatterValidator
|
||||||
|
|
||||||
ExpectedT = TypeVar("ExpectedT")
|
|
||||||
|
|
||||||
|
|
||||||
class Overrides(UnstructuredDictFormatterValidator, Scriptable):
|
class Overrides(UnstructuredDictFormatterValidator, Scriptable):
|
||||||
"""
|
"""
|
||||||
|
|
@ -210,8 +207,7 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
|
||||||
formatter: StringFormatterValidator,
|
formatter: StringFormatterValidator,
|
||||||
entry: Optional[Entry] = None,
|
entry: Optional[Entry] = None,
|
||||||
function_overrides: Optional[Dict[str, str]] = None,
|
function_overrides: Optional[Dict[str, str]] = None,
|
||||||
expected_type: Type[ExpectedT] = str,
|
) -> str:
|
||||||
) -> ExpectedT:
|
|
||||||
"""
|
"""
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
|
@ -221,8 +217,6 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
|
||||||
Optional. Entry to add source variables to the formatter
|
Optional. Entry to add source variables to the formatter
|
||||||
function_overrides
|
function_overrides
|
||||||
Optional. Explicit values to override the overrides themselves and source variables
|
Optional. Explicit values to override the overrides themselves and source variables
|
||||||
expected_type
|
|
||||||
The expected type that should return. Defaults to string.
|
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
|
|
@ -233,15 +227,42 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
|
||||||
StringFormattingException
|
StringFormattingException
|
||||||
If the formatter that is trying to be resolved cannot
|
If the formatter that is trying to be resolved cannot
|
||||||
"""
|
"""
|
||||||
out = formatter.post_process(
|
return formatter.post_process(
|
||||||
|
str(
|
||||||
|
self._apply_to_resolvable(
|
||||||
|
formatter=formatter, entry=entry, function_overrides=function_overrides
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def apply_overrides_formatter_to_native(
|
||||||
|
self,
|
||||||
|
formatter: OverridesStringFormatterValidator,
|
||||||
|
function_overrides: Optional[Dict[str, str]] = None,
|
||||||
|
) -> Any:
|
||||||
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
formatter
|
||||||
|
Overrides formatter to apply
|
||||||
|
function_overrides
|
||||||
|
Optional. Explicit values to override the overrides themselves and source variables
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
The native python form of the resolved variable
|
||||||
|
"""
|
||||||
|
return formatter.post_process_native(
|
||||||
self._apply_to_resolvable(
|
self._apply_to_resolvable(
|
||||||
formatter=formatter, entry=entry, function_overrides=function_overrides
|
formatter=formatter, entry=None, function_overrides=function_overrides
|
||||||
).native
|
).native
|
||||||
)
|
)
|
||||||
|
|
||||||
if not isinstance(out, expected_type):
|
def evaluate_boolean(
|
||||||
raise StringFormattingException(
|
self, formatter: StringFormatterValidator, entry: Optional[Entry] = None
|
||||||
f"Expected type {expected_type.__name__}, but received '{out.__class__.__name__}'"
|
) -> bool:
|
||||||
)
|
"""
|
||||||
|
Apply a formatter, and evaluate it to a boolean
|
||||||
return out
|
"""
|
||||||
|
output = self.apply_formatter(formatter=formatter, entry=entry)
|
||||||
|
return ScriptUtils.bool_formatter_output(output)
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ class Plugin(BasePlugin[OptionsValidatorT], Generic[OptionsValidatorT], ABC):
|
||||||
Returns True if enabled, False if disabled.
|
Returns True if enabled, False if disabled.
|
||||||
"""
|
"""
|
||||||
if isinstance(self.plugin_options, ToggleableOptionsDictValidator):
|
if isinstance(self.plugin_options, ToggleableOptionsDictValidator):
|
||||||
return self.overrides.apply_formatter(self.plugin_options.enable, expected_type=bool)
|
return self.overrides.evaluate_boolean(self.plugin_options.enable)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def ytdl_options_match_filters(self) -> Tuple[List[str], List[str]]:
|
def ytdl_options_match_filters(self) -> Tuple[List[str], List[str]]:
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,10 @@ class YTDLOptions(UnstructuredOverridesDictFormatterValidator):
|
||||||
Materializes the entire ytdl-options dict from OverrideStringFormatters into
|
Materializes the entire ytdl-options dict from OverrideStringFormatters into
|
||||||
native python.
|
native python.
|
||||||
"""
|
"""
|
||||||
out = {key: overrides.apply_formatter(val) for key, val in self.dict.items()}
|
out = {
|
||||||
|
key: overrides.apply_overrides_formatter_to_native(val)
|
||||||
|
for key, val in self.dict.items()
|
||||||
|
}
|
||||||
if "cookiefile" in out:
|
if "cookiefile" in out:
|
||||||
if not FileHandler.is_file_existent(out["cookiefile"]):
|
if not FileHandler.is_file_existent(out["cookiefile"]):
|
||||||
raise ValidationException(
|
raise ValidationException(
|
||||||
|
|
|
||||||
|
|
@ -52,12 +52,12 @@ class UrlDownloaderBasePluginExtension(SourcePluginExtension[MultiUrlValidator])
|
||||||
|
|
||||||
if 0 <= input_url_idx < len(self.plugin_options.urls.list):
|
if 0 <= input_url_idx < len(self.plugin_options.urls.list):
|
||||||
validator = self.plugin_options.urls.list[input_url_idx]
|
validator = self.plugin_options.urls.list[input_url_idx]
|
||||||
if entry_input_url in self.overrides.apply_formatter(validator.url, expected_type=list):
|
if entry_input_url in self.overrides.apply_overrides_formatter_to_native(validator.url):
|
||||||
return validator
|
return validator
|
||||||
|
|
||||||
# Match the first validator based on the URL, if one exists
|
# Match the first validator based on the URL, if one exists
|
||||||
for validator in self.plugin_options.urls.list:
|
for validator in self.plugin_options.urls.list:
|
||||||
if entry_input_url in self.overrides.apply_formatter(validator.url, expected_type=list):
|
if entry_input_url in self.overrides.apply_overrides_formatter_to_native(validator.url):
|
||||||
return validator
|
return validator
|
||||||
|
|
||||||
# Return the first validator if none exist
|
# Return the first validator if none exist
|
||||||
|
|
@ -382,7 +382,7 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
|
||||||
entries_to_iter: List[Optional[Entry]] = entries
|
entries_to_iter: List[Optional[Entry]] = entries
|
||||||
|
|
||||||
indices = list(range(len(entries_to_iter)))
|
indices = list(range(len(entries_to_iter)))
|
||||||
if self.overrides.apply_formatter(validator.download_reverse, expected_type=bool):
|
if self.overrides.evaluate_boolean(validator.download_reverse):
|
||||||
indices = reversed(indices)
|
indices = reversed(indices)
|
||||||
|
|
||||||
for idx in indices:
|
for idx in indices:
|
||||||
|
|
@ -461,8 +461,8 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
|
||||||
ytdl_option_overrides=validator.ytdl_options.to_native_dict(self.overrides)
|
ytdl_option_overrides=validator.ytdl_options.to_native_dict(self.overrides)
|
||||||
)
|
)
|
||||||
|
|
||||||
include_sibling_metadata = self.overrides.apply_formatter(
|
include_sibling_metadata = self.overrides.evaluate_boolean(
|
||||||
validator.include_sibling_metadata, expected_type=bool
|
validator.include_sibling_metadata
|
||||||
)
|
)
|
||||||
|
|
||||||
parents, orphan_entries = self._download_url_metadata(
|
parents, orphan_entries = self._download_url_metadata(
|
||||||
|
|
@ -487,9 +487,11 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
|
||||||
# download the bottom-most urls first since they are top-priority
|
# download the bottom-most urls first since they are top-priority
|
||||||
for idx, url_validator in reversed(list(enumerate(self.collection.urls.list))):
|
for idx, url_validator in reversed(list(enumerate(self.collection.urls.list))):
|
||||||
# URLs can be empty. If they are, then skip
|
# URLs can be empty. If they are, then skip
|
||||||
if not (urls := self.overrides.apply_formatter(url_validator.url, expected_type=list)):
|
if not (urls := self.overrides.apply_overrides_formatter_to_native(url_validator.url)):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
assert isinstance(urls, list)
|
||||||
|
|
||||||
for url in reversed(urls):
|
for url in reversed(urls):
|
||||||
assert isinstance(url, str)
|
assert isinstance(url, str)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import List
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Set
|
from typing import Set
|
||||||
|
|
||||||
|
|
@ -45,7 +44,7 @@ class UrlThumbnailListValidator(ListValidator[UrlThumbnailValidator]):
|
||||||
|
|
||||||
|
|
||||||
class OverridesOneOrManyUrlValidator(OverridesStringFormatterValidator):
|
class OverridesOneOrManyUrlValidator(OverridesStringFormatterValidator):
|
||||||
def post_process(self, resolved: Any) -> List[str]:
|
def post_process_native(self, resolved: Any) -> Any:
|
||||||
if isinstance(resolved, str):
|
if isinstance(resolved, str):
|
||||||
return [resolved]
|
return [resolved]
|
||||||
if isinstance(resolved, list):
|
if isinstance(resolved, list):
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ class DateRangePlugin(Plugin[DateRangeOptions]):
|
||||||
date_validator=self.plugin_options.after, overrides=self.overrides
|
date_validator=self.plugin_options.after, overrides=self.overrides
|
||||||
)
|
)
|
||||||
after_filter = f"{date_type} >= {after_str}"
|
after_filter = f"{date_type} >= {after_str}"
|
||||||
if self.overrides.apply_formatter(self.plugin_options.breaks, expected_type=bool):
|
if self.overrides.evaluate_boolean(self.plugin_options.breaks):
|
||||||
breaking_match_filters.append(after_filter)
|
breaking_match_filters.append(after_filter)
|
||||||
else:
|
else:
|
||||||
match_filters.append(after_filter)
|
match_filters.append(after_filter)
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class EmbedThumbnailPlugin(Plugin[EmbedThumbnailOptions]):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _embed_thumbnail(self) -> bool:
|
def _embed_thumbnail(self) -> bool:
|
||||||
return self.overrides.apply_formatter(self.plugin_options, expected_type=bool)
|
return self.overrides.evaluate_boolean(self.plugin_options)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _embed_video_thumbnail(cls, entry: Entry) -> None:
|
def _embed_video_thumbnail(cls, entry: Entry) -> None:
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,13 @@ from ytdl_sub.config.validators.options import OptionsValidator
|
||||||
from ytdl_sub.entries.entry import Entry
|
from ytdl_sub.entries.entry import Entry
|
||||||
from ytdl_sub.utils.exceptions import StringFormattingException
|
from ytdl_sub.utils.exceptions import StringFormattingException
|
||||||
from ytdl_sub.utils.logger import Logger
|
from ytdl_sub.utils.logger import Logger
|
||||||
from ytdl_sub.validators.string_formatter_validators import BooleanFormatterValidator
|
from ytdl_sub.validators.string_formatter_validators import ListFormatterValidator
|
||||||
from ytdl_sub.validators.validators import ListValidator
|
|
||||||
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
|
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
|
||||||
|
|
||||||
logger = Logger.get("filter-exclude")
|
logger = Logger.get("filter-exclude")
|
||||||
|
|
||||||
|
|
||||||
class FilterExcludeOptions(ListValidator[BooleanFormatterValidator], OptionsValidator):
|
class FilterExcludeOptions(ListFormatterValidator, OptionsValidator):
|
||||||
"""
|
"""
|
||||||
Applies a conditional OR on any number of filters comprised of either variables or scripts.
|
Applies a conditional OR on any number of filters comprised of either variables or scripts.
|
||||||
If any filter evaluates to True, the entry will be excluded.
|
If any filter evaluates to True, the entry will be excluded.
|
||||||
|
|
@ -30,8 +29,6 @@ class FilterExcludeOptions(ListValidator[BooleanFormatterValidator], OptionsVali
|
||||||
{ %contains( %lower(description), '#short' ) }
|
{ %contains( %lower(description), '#short' ) }
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_inner_list_type = BooleanFormatterValidator
|
|
||||||
|
|
||||||
|
|
||||||
class FilterExcludePlugin(Plugin[FilterExcludeOptions]):
|
class FilterExcludePlugin(Plugin[FilterExcludeOptions]):
|
||||||
plugin_options_type = FilterExcludeOptions
|
plugin_options_type = FilterExcludeOptions
|
||||||
|
|
@ -55,9 +52,7 @@ class FilterExcludePlugin(Plugin[FilterExcludeOptions]):
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
for formatter in self.plugin_options.list:
|
for formatter in self.plugin_options.list:
|
||||||
should_exclude = self.overrides.apply_formatter(
|
should_exclude = self.overrides.evaluate_boolean(formatter=formatter, entry=entry)
|
||||||
formatter=formatter, entry=entry, expected_type=bool
|
|
||||||
)
|
|
||||||
|
|
||||||
if should_exclude:
|
if should_exclude:
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,14 @@ from ytdl_sub.config.validators.options import OptionsValidator
|
||||||
from ytdl_sub.entries.entry import Entry
|
from ytdl_sub.entries.entry import Entry
|
||||||
from ytdl_sub.utils.exceptions import StringFormattingException
|
from ytdl_sub.utils.exceptions import StringFormattingException
|
||||||
from ytdl_sub.utils.logger import Logger
|
from ytdl_sub.utils.logger import Logger
|
||||||
from ytdl_sub.validators.string_formatter_validators import BooleanFormatterValidator
|
from ytdl_sub.utils.script import ScriptUtils
|
||||||
from ytdl_sub.validators.validators import ListValidator
|
from ytdl_sub.validators.string_formatter_validators import ListFormatterValidator
|
||||||
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
|
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
|
||||||
|
|
||||||
logger = Logger.get("filter-include")
|
logger = Logger.get("filter-include")
|
||||||
|
|
||||||
|
|
||||||
class FilterIncludeOptions(ListValidator[BooleanFormatterValidator], OptionsValidator):
|
class FilterIncludeOptions(ListFormatterValidator, OptionsValidator):
|
||||||
"""
|
"""
|
||||||
Applies a conditional AND on any number of filters comprised of either variables or scripts.
|
Applies a conditional AND on any number of filters comprised of either variables or scripts.
|
||||||
If all filters evaluate to True, the entry will be included.
|
If all filters evaluate to True, the entry will be included.
|
||||||
|
|
@ -38,8 +38,6 @@ class FilterIncludeOptions(ListValidator[BooleanFormatterValidator], OptionsVali
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_inner_list_type = BooleanFormatterValidator
|
|
||||||
|
|
||||||
|
|
||||||
class FilterIncludePlugin(Plugin[FilterIncludeOptions]):
|
class FilterIncludePlugin(Plugin[FilterIncludeOptions]):
|
||||||
plugin_options_type = FilterIncludeOptions
|
plugin_options_type = FilterIncludeOptions
|
||||||
|
|
@ -63,8 +61,8 @@ class FilterIncludePlugin(Plugin[FilterIncludeOptions]):
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
for formatter in self.plugin_options.list:
|
for formatter in self.plugin_options.list:
|
||||||
should_exclude = self.overrides.apply_formatter(
|
should_exclude = ScriptUtils.bool_formatter_output(
|
||||||
formatter=formatter, entry=entry, expected_type=bool
|
self.overrides.apply_formatter(formatter=formatter, entry=entry)
|
||||||
)
|
)
|
||||||
if not should_exclude:
|
if not should_exclude:
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ class SharedNfoTagsPlugin(Plugin[SharedNfoTagsOptions], ABC):
|
||||||
if not nfo_tags:
|
if not nfo_tags:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.overrides.apply_formatter(self.plugin_options.kodi_safe, expected_type=bool):
|
if self.overrides.evaluate_boolean(self.plugin_options.kodi_safe):
|
||||||
nfo_root = to_max_3_byte_utf8_string(nfo_root)
|
nfo_root = to_max_3_byte_utf8_string(nfo_root)
|
||||||
nfo_tags = {
|
nfo_tags = {
|
||||||
to_max_3_byte_utf8_string(key): [
|
to_max_3_byte_utf8_string(key): [
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ class SquareThumbnailPlugin(Plugin[SquareThumbnailOptions]):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _square_thumbnail(self) -> bool:
|
def _square_thumbnail(self) -> bool:
|
||||||
return self.overrides.apply_formatter(self.plugin_options, expected_type=bool)
|
return self.overrides.evaluate_boolean(self.plugin_options)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _convert_to_square_thumbnail(cls, entry: Entry) -> None:
|
def _convert_to_square_thumbnail(cls, entry: Entry) -> None:
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ class _RandomizedRangeValidator(StrictDictValidator, ABC):
|
||||||
)
|
)
|
||||||
|
|
||||||
def _randomized_float(self, overrides: Overrides, entry: Optional[Entry] = None) -> float:
|
def _randomized_float(self, overrides: Overrides, entry: Optional[Entry] = None) -> float:
|
||||||
actualized_min = overrides.apply_formatter(self._min, entry=entry, expected_type=float)
|
actualized_min = float(overrides.apply_formatter(self._min, entry=entry))
|
||||||
actualized_max = overrides.apply_formatter(self._max, entry=entry, expected_type=float)
|
actualized_max = float(overrides.apply_formatter(self._max, entry=entry))
|
||||||
|
|
||||||
if actualized_min < 0:
|
if actualized_min < 0:
|
||||||
raise self._validation_exception(
|
raise self._validation_exception(
|
||||||
|
|
@ -70,7 +70,7 @@ class _RandomizedRangeValidator(StrictDictValidator, ABC):
|
||||||
-------
|
-------
|
||||||
Max possible value
|
Max possible value
|
||||||
"""
|
"""
|
||||||
actualized_max = overrides.apply_formatter(self._max, entry=entry, expected_type=float)
|
actualized_max = float(overrides.apply_formatter(self._max, entry=entry))
|
||||||
if actualized_max < 0:
|
if actualized_max < 0:
|
||||||
raise self._validation_exception(
|
raise self._validation_exception(
|
||||||
f"max must be greater than zero, received {actualized_max}"
|
f"max must be greater than zero, received {actualized_max}"
|
||||||
|
|
|
||||||
|
|
@ -82,27 +82,35 @@ class StringFormatterValidator(StringValidator):
|
||||||
"""
|
"""
|
||||||
return self._parsed
|
return self._parsed
|
||||||
|
|
||||||
def post_process(self, resolved: Any) -> Any:
|
def post_process(self, resolved: str) -> str:
|
||||||
"""
|
"""
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
Apply any post processing to the resolved value. Defaults to casting it to string.
|
Apply any post processing to the resolved value
|
||||||
"""
|
"""
|
||||||
return str(resolved)
|
return resolved
|
||||||
|
|
||||||
|
def post_process_native(self, resolved: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Apply any post processing to the resolved native value.
|
||||||
|
"""
|
||||||
|
return resolved
|
||||||
|
|
||||||
|
|
||||||
class FloatFormatterValidator(StringFormatterValidator):
|
class FloatFormatterValidator(StringFormatterValidator):
|
||||||
_expected_value_type_name = "float"
|
_expected_value_type_name = "float"
|
||||||
|
|
||||||
def post_process(self, resolved: str) -> float:
|
def post_process(self, resolved: str) -> str:
|
||||||
try:
|
try:
|
||||||
out = float(resolved)
|
float(resolved)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise self._validation_exception(
|
raise self._validation_exception(
|
||||||
f"Expected a float, but received '{resolved}'"
|
f"Expected a float, but received '{resolved}'"
|
||||||
) from exc
|
) from exc
|
||||||
|
|
||||||
return out
|
return resolved
|
||||||
|
|
||||||
|
|
||||||
class StandardizedDateValidator(StringFormatterValidator):
|
class StandardizedDateValidator(StringFormatterValidator):
|
||||||
|
|
@ -119,13 +127,6 @@ class StandardizedDateValidator(StringFormatterValidator):
|
||||||
return resolved
|
return resolved
|
||||||
|
|
||||||
|
|
||||||
class BooleanFormatterValidator(StringFormatterValidator):
|
|
||||||
_expected_value_type_name = "boolean"
|
|
||||||
|
|
||||||
def post_process(self, resolved: Any) -> bool:
|
|
||||||
return ScriptUtils.bool_formatter_output(output=str(resolved))
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=line-too-long
|
# pylint: disable=line-too-long
|
||||||
class OverridesStringFormatterValidator(StringFormatterValidator):
|
class OverridesStringFormatterValidator(StringFormatterValidator):
|
||||||
"""
|
"""
|
||||||
|
|
@ -145,14 +146,15 @@ class OverridesStringFormatterValidator(StringFormatterValidator):
|
||||||
class OverridesIntegerFormatterValidator(OverridesStringFormatterValidator):
|
class OverridesIntegerFormatterValidator(OverridesStringFormatterValidator):
|
||||||
_expected_value_type_name = "integer"
|
_expected_value_type_name = "integer"
|
||||||
|
|
||||||
def post_process(self, resolved: str) -> int:
|
def post_process(self, resolved: str) -> str:
|
||||||
try:
|
try:
|
||||||
out = int(resolved)
|
int(resolved)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise self._validation_exception(
|
raise self._validation_exception(
|
||||||
f"Expected an integer, but received '{resolved}'"
|
f"Expected an integer, but received '{resolved}'"
|
||||||
) from exc
|
) from exc
|
||||||
return out
|
|
||||||
|
return resolved
|
||||||
|
|
||||||
|
|
||||||
class OverridesFloatFormatterValidator(FloatFormatterValidator, OverridesStringFormatterValidator):
|
class OverridesFloatFormatterValidator(FloatFormatterValidator, OverridesStringFormatterValidator):
|
||||||
|
|
@ -161,14 +163,9 @@ class OverridesFloatFormatterValidator(FloatFormatterValidator, OverridesStringF
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class OverridesBooleanFormatterValidator(
|
class OverridesBooleanFormatterValidator(OverridesStringFormatterValidator):
|
||||||
BooleanFormatterValidator, OverridesStringFormatterValidator
|
|
||||||
):
|
|
||||||
_expected_value_type_name = "boolean"
|
_expected_value_type_name = "boolean"
|
||||||
|
|
||||||
def post_process(self, resolved: Any) -> bool:
|
|
||||||
return ScriptUtils.bool_formatter_output(output=str(resolved))
|
|
||||||
|
|
||||||
|
|
||||||
class ListFormatterValidator(ListValidator[StringFormatterValidator]):
|
class ListFormatterValidator(ListValidator[StringFormatterValidator]):
|
||||||
_inner_list_type = StringFormatterValidator
|
_inner_list_type = StringFormatterValidator
|
||||||
|
|
|
||||||
|
|
@ -475,6 +475,19 @@ def test_advanced_tv_show_subscriptions(
|
||||||
|
|
||||||
assert overrides.script.get("subscription_name").native == "Gardening with Ciscoe"
|
assert overrides.script.get("subscription_name").native == "Gardening with Ciscoe"
|
||||||
|
|
||||||
|
assert overrides.apply_overrides_formatter_to_native(overrides.dict["subscription_array"]) == [
|
||||||
|
"https://www.youtube.com/@gardeningwithciscoe4430",
|
||||||
|
"https://www.youtube.com/playlist?list=PLi8V8UemxeG6lo5if5H5g5EbsteELcb0_",
|
||||||
|
"https://www.youtube.com/playlist?list=PLsJlQSR-KjmaQqqJ9jq18cF6XXXAR4kyn",
|
||||||
|
"https://www.youtube.com/watch?v=2vq-vPubS5I",
|
||||||
|
]
|
||||||
|
assert overrides.apply_overrides_formatter_to_native(overrides.dict["urls"]) == [
|
||||||
|
"https://www.youtube.com/@gardeningwithciscoe4430",
|
||||||
|
"https://www.youtube.com/playlist?list=PLi8V8UemxeG6lo5if5H5g5EbsteELcb0_",
|
||||||
|
"https://www.youtube.com/playlist?list=PLsJlQSR-KjmaQqqJ9jq18cF6XXXAR4kyn",
|
||||||
|
"https://www.youtube.com/watch?v=2vq-vPubS5I",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_music_subscriptions(default_config: ConfigFile, music_subscriptions_path: Path):
|
def test_music_subscriptions(default_config: ConfigFile, music_subscriptions_path: Path):
|
||||||
subs = Subscription.from_file_path(
|
subs = Subscription.from_file_path(
|
||||||
|
|
|
||||||
|
|
@ -57,13 +57,12 @@ class TestTvShowCollectionPreset:
|
||||||
|
|
||||||
# is_bilateral
|
# is_bilateral
|
||||||
if i == 0:
|
if i == 0:
|
||||||
url = sub.overrides.apply_formatter(
|
url = sub.overrides.apply_overrides_formatter_to_native(
|
||||||
url_list[itr].url,
|
url_list[itr].url,
|
||||||
function_overrides={
|
function_overrides={
|
||||||
# mock so bilateral url gets enabled
|
# mock so bilateral url gets enabled
|
||||||
"subscription_has_download_archive": "True"
|
"subscription_has_download_archive": "True"
|
||||||
},
|
},
|
||||||
expected_type=list,
|
|
||||||
)
|
)
|
||||||
assert url == [
|
assert url == [
|
||||||
f"youtube.com/playlist?url_{season_num}_{i}"
|
f"youtube.com/playlist?url_{season_num}_{i}"
|
||||||
|
|
@ -82,13 +81,12 @@ class TestTvShowCollectionPreset:
|
||||||
# not bilateral
|
# not bilateral
|
||||||
else:
|
else:
|
||||||
for j in range(2):
|
for j in range(2):
|
||||||
url = sub.overrides.apply_formatter(
|
url = sub.overrides.apply_overrides_formatter_to_native(
|
||||||
url_list[itr + j].url,
|
url_list[itr + j].url,
|
||||||
function_overrides={
|
function_overrides={
|
||||||
# mock so bilateral url gets enabled
|
# mock so bilateral url gets enabled
|
||||||
"subscription_has_download_archive": "True"
|
"subscription_has_download_archive": "True"
|
||||||
},
|
},
|
||||||
expected_type=list,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# First instance is the first url to get thumbnails
|
# First instance is the first url to get thumbnails
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue