refactored, tests passing
This commit is contained in:
parent
056b111be6
commit
f2d60b3ade
4 changed files with 242 additions and 90 deletions
|
|
@ -13,12 +13,12 @@ TV Show Full Archive:
|
||||||
"Opeth": "https://www.youtube.com/channel/UCmQSJTFZaXN85gYk6W3XbdQ"
|
"Opeth": "https://www.youtube.com/channel/UCmQSJTFZaXN85gYk6W3XbdQ"
|
||||||
|
|
||||||
# Sets "Kids" for genre, "TV-Y" for content rating
|
# Sets "Kids" for genre, "TV-Y" for content rating
|
||||||
= Kids | TV-Y:
|
= Kids | = TV-Y:
|
||||||
"Jake Trains": "https://www.youtube.com/@JakeTrains"
|
"Jake Trains": "https://www.youtube.com/@JakeTrains"
|
||||||
"Kids Toys Play": "https://www.youtube.com/@KidsToysPlayChannel"
|
"Kids Toys Play": "https://www.youtube.com/@KidsToysPlayChannel"
|
||||||
|
|
||||||
|
|
||||||
# All subscriptions under this will use the `TV Show Only Recent` preset
|
# All subscriptions under this will use the `TV Show Only Recent` preset
|
||||||
TV Show Only Recent:
|
TV Show Only Recent:
|
||||||
= News | TV-14:
|
= News | = TV-14:
|
||||||
"BBC": "https://www.youtube.com/@BBCNews"
|
"BBC": "https://www.youtube.com/@BBCNews"
|
||||||
|
|
|
||||||
|
|
@ -120,45 +120,9 @@ class YTDLOptions(LiteralDictValidator):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class OverridesVariables(DictFormatterValidator):
|
|
||||||
"""
|
|
||||||
Override variables that are automatically added to every subscription.
|
|
||||||
"""
|
|
||||||
|
|
||||||
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):
|
|
||||||
super().__init__(name, value)
|
|
||||||
|
|
||||||
# Add sanitized and non-sanitized override variables
|
|
||||||
for sanitize in [True, False]:
|
|
||||||
self._add_override_variable(
|
|
||||||
key_name="subscription_name",
|
|
||||||
format_string=self.subscription_name,
|
|
||||||
sanitize=sanitize,
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def subscription_name(self) -> str:
|
|
||||||
"""
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
Name of the subscription
|
|
||||||
"""
|
|
||||||
return self._root_name
|
|
||||||
|
|
||||||
|
|
||||||
# Disable for proper docstring formatting
|
# Disable for proper docstring formatting
|
||||||
# pylint: disable=line-too-long
|
# pylint: disable=line-too-long
|
||||||
class Overrides(OverridesVariables):
|
class Overrides(DictFormatterValidator):
|
||||||
"""
|
"""
|
||||||
Optional. This section allows you to define variables that can be used in any string formatter.
|
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
|
For example, if you want your file and thumbnail files to match without copy-pasting a large
|
||||||
|
|
@ -188,6 +152,16 @@ class Overrides(OverridesVariables):
|
||||||
|
|
||||||
# pylint: enable=line-too-long
|
# 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):
|
def __init__(self, name, value):
|
||||||
super().__init__(name, value)
|
super().__init__(name, value)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
import copy
|
import copy
|
||||||
|
import dataclasses
|
||||||
from abc import ABC
|
from abc import ABC
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from typing import final
|
||||||
|
|
||||||
from ytdl_sub.config.config_file import ConfigFile
|
from ytdl_sub.config.config_file import ConfigFile
|
||||||
from ytdl_sub.config.preset_options import Overrides
|
from ytdl_sub.config.preset_options import Overrides
|
||||||
|
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
|
||||||
from ytdl_sub.validators.validators import DictValidator
|
from ytdl_sub.validators.validators import DictValidator
|
||||||
from ytdl_sub.validators.validators import StringListValidator
|
from ytdl_sub.validators.validators import StringListValidator
|
||||||
from ytdl_sub.validators.validators import StringValidator
|
from ytdl_sub.validators.validators import StringValidator
|
||||||
|
|
@ -36,18 +39,6 @@ def subscription_value_variable_name() -> str:
|
||||||
return "subscription_value"
|
return "subscription_value"
|
||||||
|
|
||||||
|
|
||||||
def maybe_indent_override_values(value: str) -> List[str]:
|
|
||||||
"""
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
Value if it is an overide [Value]. None otherwise.
|
|
||||||
"""
|
|
||||||
if value.startswith("="):
|
|
||||||
# Drop the =, split on |, and strip each indent_value (both left + right)
|
|
||||||
return [indent_value.strip() for indent_value in value[1:].split("|")]
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionOutput(Validator, ABC):
|
class SubscriptionOutput(Validator, ABC):
|
||||||
def __init__(self, name, value, presets: List[str], indent_overrides: List[str]):
|
def __init__(self, name, value, presets: List[str], indent_overrides: List[str]):
|
||||||
super().__init__(name, value)
|
super().__init__(name, value)
|
||||||
|
|
@ -75,6 +66,15 @@ class SubscriptionOutput(Validator, ABC):
|
||||||
Subscriptions in the form of ``{ subscription_name: preset_dict }``
|
Subscriptions in the form of ``{ subscription_name: preset_dict }``
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def subscription_name(self) -> str:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
The name of the subscription
|
||||||
|
"""
|
||||||
|
return self._leaf_name
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionPresetDictValidator(SubscriptionOutput, DictValidator):
|
class SubscriptionPresetDictValidator(SubscriptionOutput, DictValidator):
|
||||||
def __init__(self, name, value, presets: List[str], indent_overrides: List[str]):
|
def __init__(self, name, value, presets: List[str], indent_overrides: List[str]):
|
||||||
|
|
@ -93,12 +93,46 @@ class SubscriptionPresetDictValidator(SubscriptionOutput, DictValidator):
|
||||||
|
|
||||||
output_dict["preset"] = parent_presets + self._presets + global_presets_to_apply
|
output_dict["preset"] = parent_presets + self._presets + global_presets_to_apply
|
||||||
output_dict["overrides"] = dict(
|
output_dict["overrides"] = dict(
|
||||||
output_dict.get("overrides", {}), **self._indent_overrides_dict()
|
output_dict.get("overrides", {}),
|
||||||
|
**self._indent_overrides_dict(),
|
||||||
|
**{"subscription_name": self.subscription_name},
|
||||||
)
|
)
|
||||||
return {self._leaf_name: output_dict}
|
return {self.subscription_name: output_dict}
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionValueValidator(SubscriptionOutput, StringValidator):
|
class SubscriptionLeafValidator(SubscriptionOutput, ABC):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
config: ConfigFile,
|
||||||
|
presets: List[str],
|
||||||
|
indent_overrides: List[str],
|
||||||
|
):
|
||||||
|
super().__init__(name=name, value=value, presets=presets, indent_overrides=indent_overrides)
|
||||||
|
|
||||||
|
if self.subscription_name in config.presets.keys:
|
||||||
|
raise self._validation_exception(
|
||||||
|
f"{self.subscription_name} conflicts with an existing preset name and cannot be "
|
||||||
|
f"used as a subscription name"
|
||||||
|
)
|
||||||
|
|
||||||
|
self._overrides_to_add: Dict[str, str] = {"subscription_name": self.subscription_name}
|
||||||
|
|
||||||
|
@final
|
||||||
|
def subscription_dicts(self, global_presets_to_apply: List[str]) -> Dict[str, Dict]:
|
||||||
|
return {
|
||||||
|
self.subscription_name: {
|
||||||
|
"preset": self._presets + global_presets_to_apply,
|
||||||
|
"overrides": dict(
|
||||||
|
self._indent_overrides_dict(),
|
||||||
|
**self._overrides_to_add,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SubscriptionValueValidator(SubscriptionLeafValidator, StringValidator):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name,
|
name,
|
||||||
|
|
@ -108,30 +142,72 @@ class SubscriptionValueValidator(SubscriptionOutput, StringValidator):
|
||||||
indent_overrides: List[str],
|
indent_overrides: List[str],
|
||||||
subscription_value: Optional[str],
|
subscription_value: Optional[str],
|
||||||
):
|
):
|
||||||
super().__init__(name=name, value=value, presets=presets, indent_overrides=indent_overrides)
|
super().__init__(
|
||||||
|
name=name,
|
||||||
if self._leaf_name in config.presets.keys:
|
value=value,
|
||||||
raise self._validation_exception(
|
config=config,
|
||||||
f"{self._leaf_name} conflicts with an existing preset name and cannot be "
|
presets=presets,
|
||||||
f"used as a subscription name"
|
indent_overrides=indent_overrides,
|
||||||
)
|
)
|
||||||
self._subscription_value: Optional[str] = subscription_value
|
|
||||||
|
|
||||||
def subscription_dicts(self, global_presets_to_apply: List[str]) -> Dict[str, Dict]:
|
|
||||||
subscription_value_dict: Dict[str, str] = {"subscription_value": self.value}
|
|
||||||
# TODO: Eventually delete in favor of {subscription_value}
|
# TODO: Eventually delete in favor of {subscription_value}
|
||||||
if self._subscription_value:
|
if subscription_value:
|
||||||
subscription_value_dict[self._subscription_value] = self.value
|
self._overrides_to_add[subscription_value] = self.value
|
||||||
|
self._overrides_to_add["subscription_value"] = self.value
|
||||||
|
|
||||||
return {
|
|
||||||
self._leaf_name: {
|
class SubscriptionListValuesValidator(SubscriptionLeafValidator, StringListValidator):
|
||||||
"preset": self._presets + global_presets_to_apply,
|
def __init__(
|
||||||
"overrides": dict(
|
self,
|
||||||
subscription_value_dict,
|
name,
|
||||||
**self._indent_overrides_dict(),
|
value,
|
||||||
),
|
config: ConfigFile,
|
||||||
}
|
presets: List[str],
|
||||||
}
|
indent_overrides: List[str],
|
||||||
|
):
|
||||||
|
super().__init__(
|
||||||
|
name=name,
|
||||||
|
value=value,
|
||||||
|
config=config,
|
||||||
|
presets=presets,
|
||||||
|
indent_overrides=indent_overrides,
|
||||||
|
)
|
||||||
|
|
||||||
|
for idx, list_value in enumerate(self.list):
|
||||||
|
# Write the first list value into subscription_value as well
|
||||||
|
if idx == 0:
|
||||||
|
self._overrides_to_add["subscription_value"] = list_value.value
|
||||||
|
self._overrides_to_add[f"subscription_value_{idx + 1}"] = list_value.value
|
||||||
|
|
||||||
|
|
||||||
|
class SubscriptionWithOverridesValidator(SubscriptionLeafValidator, DictFormatterValidator):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
config: ConfigFile,
|
||||||
|
presets: List[str],
|
||||||
|
indent_overrides: List[str],
|
||||||
|
):
|
||||||
|
super().__init__(
|
||||||
|
name=name,
|
||||||
|
value=value,
|
||||||
|
config=config,
|
||||||
|
presets=presets,
|
||||||
|
indent_overrides=indent_overrides,
|
||||||
|
)
|
||||||
|
|
||||||
|
self._overrides_to_add = dict(self.dict_with_format_strings, **self._overrides_to_add)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def subscription_name(self) -> str:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Name of the subscription
|
||||||
|
"""
|
||||||
|
# drop the ~ in "~Subscription Name":
|
||||||
|
return super().subscription_name[1:]
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionValidator(SubscriptionOutput):
|
class SubscriptionValidator(SubscriptionOutput):
|
||||||
|
|
@ -139,6 +215,35 @@ class SubscriptionValidator(SubscriptionOutput):
|
||||||
Top-level subscription validator
|
Top-level subscription validator
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class PresetIndentKey:
|
||||||
|
presets: List[str] = dataclasses.field(default_factory=list)
|
||||||
|
indent_overrides: List[str] = dataclasses.field(default_factory=list)
|
||||||
|
|
||||||
|
def _preset_indent_key(self, key: str, config: ConfigFile) -> Optional[PresetIndentKey]:
|
||||||
|
presets: List[str] = []
|
||||||
|
indent_overrides: List[str] = []
|
||||||
|
|
||||||
|
stripped_split_keys = [sub_key.strip() for sub_key in key.split("|")]
|
||||||
|
for sub_key in stripped_split_keys:
|
||||||
|
if sub_key.startswith("="):
|
||||||
|
indent_overrides.append(sub_key[1:].strip())
|
||||||
|
elif sub_key in config.presets.keys:
|
||||||
|
presets.append(sub_key)
|
||||||
|
else:
|
||||||
|
if presets or indent_overrides:
|
||||||
|
raise self._validation_exception(
|
||||||
|
f"'{sub_key.strip()}' in '{key.strip()}' is not a preset name. "
|
||||||
|
f"To use as a subscription indent value, define it as '= {sub_key.strip()}'"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not presets and not indent_overrides:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return SubscriptionValidator.PresetIndentKey(
|
||||||
|
presets=presets, indent_overrides=indent_overrides
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name,
|
name,
|
||||||
|
|
@ -154,6 +259,8 @@ class SubscriptionValidator(SubscriptionOutput):
|
||||||
for key, obj in value.items():
|
for key, obj in value.items():
|
||||||
obj_name = f"{name}.{key}" if name else key
|
obj_name = f"{name}.{key}" if name else key
|
||||||
|
|
||||||
|
# Subscription defined as
|
||||||
|
# "Sub Name": "value"
|
||||||
if isinstance(obj, str):
|
if isinstance(obj, str):
|
||||||
self._children.append(
|
self._children.append(
|
||||||
SubscriptionValueValidator(
|
SubscriptionValueValidator(
|
||||||
|
|
@ -165,26 +272,45 @@ class SubscriptionValidator(SubscriptionOutput):
|
||||||
subscription_value=subscription_value,
|
subscription_value=subscription_value,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif isinstance(value, dict):
|
# Subscription defined as
|
||||||
if key in config.presets.keys:
|
# "Sub Name":
|
||||||
|
# - "value1"
|
||||||
|
# - "value2"
|
||||||
|
elif isinstance(obj, list):
|
||||||
self._children.append(
|
self._children.append(
|
||||||
SubscriptionValidator(
|
SubscriptionListValuesValidator(
|
||||||
name=obj_name,
|
|
||||||
value=obj,
|
|
||||||
config=config,
|
|
||||||
presets=presets + [key],
|
|
||||||
indent_overrides=indent_overrides,
|
|
||||||
subscription_value=subscription_value,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
elif override_values := maybe_indent_override_values(key):
|
|
||||||
self._children.append(
|
|
||||||
SubscriptionValidator(
|
|
||||||
name=obj_name,
|
name=obj_name,
|
||||||
value=obj,
|
value=obj,
|
||||||
config=config,
|
config=config,
|
||||||
presets=presets,
|
presets=presets,
|
||||||
indent_overrides=indent_overrides + override_values,
|
indent_overrides=indent_overrides,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif isinstance(obj, dict):
|
||||||
|
# Subscription defined as
|
||||||
|
# "~Sub Name":
|
||||||
|
# override_1: "abc"
|
||||||
|
# override_2: "123"
|
||||||
|
if key.startswith("~"):
|
||||||
|
self._children.append(
|
||||||
|
SubscriptionWithOverridesValidator(
|
||||||
|
name=obj_name,
|
||||||
|
value=obj,
|
||||||
|
config=config,
|
||||||
|
presets=presets,
|
||||||
|
indent_overrides=indent_overrides,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif (
|
||||||
|
preset_indent_key := self._preset_indent_key(key=key, config=config)
|
||||||
|
) is not None:
|
||||||
|
self._children.append(
|
||||||
|
SubscriptionValidator(
|
||||||
|
name=obj_name,
|
||||||
|
value=obj,
|
||||||
|
config=config,
|
||||||
|
presets=presets + preset_indent_key.presets,
|
||||||
|
indent_overrides=indent_overrides + preset_indent_key.indent_overrides,
|
||||||
subscription_value=subscription_value,
|
subscription_value=subscription_value,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -197,6 +323,10 @@ class SubscriptionValidator(SubscriptionOutput):
|
||||||
indent_overrides=indent_overrides,
|
indent_overrides=indent_overrides,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
raise self._validation_exception(
|
||||||
|
"Subscription value should either be a string, list, or object"
|
||||||
|
)
|
||||||
|
|
||||||
def subscription_dicts(self, global_presets_to_apply: List[str]) -> Dict[str, Dict]:
|
def subscription_dicts(self, global_presets_to_apply: List[str]) -> Dict[str, Dict]:
|
||||||
subscription_dicts: Dict[str, Dict] = {}
|
subscription_dicts: Dict[str, Dict] = {}
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,25 @@ def preset_with_subscription_value_nested_presets_and_indent_variables(
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def preset_with_subscription_value_nested_presets_and_indent_variables_same_line(
|
def preset_with_subscription_value_nested_presets_and_indent_variables_same_line(
|
||||||
preset_with_subscription_value: Dict,
|
preset_with_subscription_value: Dict,
|
||||||
|
):
|
||||||
|
return dict(
|
||||||
|
preset_with_subscription_value,
|
||||||
|
**{
|
||||||
|
"parent_preset_2": {
|
||||||
|
"=INDENT_1": {
|
||||||
|
"parent_preset_1": {"test_2_1": "is_2_1_overwritten"},
|
||||||
|
"= INDENT_2 | = INDENT_3 ": {
|
||||||
|
"test_1": "is_1_overwritten",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def preset_with_subscription_value_nested_presets_and_indent_variables_same_line_old_format_errors(
|
||||||
|
preset_with_subscription_value: Dict,
|
||||||
):
|
):
|
||||||
return dict(
|
return dict(
|
||||||
preset_with_subscription_value,
|
preset_with_subscription_value,
|
||||||
|
|
@ -191,6 +210,7 @@ def test_subscription_file_value_applies_sub_file_takes_precedence(
|
||||||
assert value_sub.get("test_file_subscription_value") == "is_overwritten"
|
assert value_sub.get("test_file_subscription_value") == "is_overwritten"
|
||||||
assert value_sub.get("test_config_subscription_value") == "original"
|
assert value_sub.get("test_config_subscription_value") == "original"
|
||||||
assert value_sub.get("subscription_name") == "test_value"
|
assert value_sub.get("subscription_name") == "test_value"
|
||||||
|
assert value_sub.get("subscription_name_sanitized") == "test_value"
|
||||||
assert value_sub.get("subscription_value") == "is_overwritten"
|
assert value_sub.get("subscription_value") == "is_overwritten"
|
||||||
assert value_sub.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
assert value_sub.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
||||||
|
|
||||||
|
|
@ -209,6 +229,7 @@ def test_subscription_file_value_applies_from_config(
|
||||||
assert value_sub.get("test_file_subscription_value") == "original"
|
assert value_sub.get("test_file_subscription_value") == "original"
|
||||||
assert value_sub.get("test_config_subscription_value") == "is_overwritten"
|
assert value_sub.get("test_config_subscription_value") == "is_overwritten"
|
||||||
assert value_sub.get("subscription_name") == "test_value"
|
assert value_sub.get("subscription_name") == "test_value"
|
||||||
|
assert value_sub.get("subscription_name_sanitized") == "test_value"
|
||||||
assert value_sub.get("subscription_value") == "is_overwritten"
|
assert value_sub.get("subscription_value") == "is_overwritten"
|
||||||
assert value_sub.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
assert value_sub.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
||||||
|
|
||||||
|
|
@ -229,11 +250,13 @@ def test_subscription_file_value_applies_from_config_and_nested(
|
||||||
|
|
||||||
assert sub_1.get("test_config_subscription_value") == "is_1_overwritten"
|
assert sub_1.get("test_config_subscription_value") == "is_1_overwritten"
|
||||||
assert sub_1.get("subscription_name") == "test_1"
|
assert sub_1.get("subscription_name") == "test_1"
|
||||||
|
assert sub_1.get("subscription_name_sanitized") == "test_1"
|
||||||
assert sub_1.get("subscription_value") == "is_1_overwritten"
|
assert sub_1.get("subscription_value") == "is_1_overwritten"
|
||||||
assert sub_1.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
assert sub_1.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
||||||
|
|
||||||
assert sub_2_1.get("test_config_subscription_value") == "is_2_1_overwritten"
|
assert sub_2_1.get("test_config_subscription_value") == "is_2_1_overwritten"
|
||||||
assert sub_2_1.get("subscription_name") == "test_2_1"
|
assert sub_2_1.get("subscription_name") == "test_2_1"
|
||||||
|
assert sub_2_1.get("subscription_name_sanitized") == "test_2_1"
|
||||||
assert sub_2_1.get("subscription_value") == "is_2_1_overwritten"
|
assert sub_2_1.get("subscription_value") == "is_2_1_overwritten"
|
||||||
assert sub_2_1.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
assert sub_2_1.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
||||||
|
|
||||||
|
|
@ -262,6 +285,7 @@ def test_subscription_file_value_applies_from_config_and_nested_and_indent_varia
|
||||||
|
|
||||||
assert sub_1.get("test_config_subscription_value") == "is_1_overwritten"
|
assert sub_1.get("test_config_subscription_value") == "is_1_overwritten"
|
||||||
assert sub_1.get("subscription_name") == "test_1"
|
assert sub_1.get("subscription_name") == "test_1"
|
||||||
|
assert sub_1.get("subscription_name_sanitized") == "test_1"
|
||||||
assert sub_1.get("subscription_value") == "is_1_overwritten"
|
assert sub_1.get("subscription_value") == "is_1_overwritten"
|
||||||
assert sub_1.get("subscription_indent_1") == "INDENT_1"
|
assert sub_1.get("subscription_indent_1") == "INDENT_1"
|
||||||
assert sub_1.get("subscription_indent_2") == "INDENT_2"
|
assert sub_1.get("subscription_indent_2") == "INDENT_2"
|
||||||
|
|
@ -269,6 +293,7 @@ def test_subscription_file_value_applies_from_config_and_nested_and_indent_varia
|
||||||
|
|
||||||
assert sub_2_1.get("test_config_subscription_value") == "is_2_1_overwritten"
|
assert sub_2_1.get("test_config_subscription_value") == "is_2_1_overwritten"
|
||||||
assert sub_2_1.get("subscription_name") == "test_2_1"
|
assert sub_2_1.get("subscription_name") == "test_2_1"
|
||||||
|
assert sub_2_1.get("subscription_name_sanitized") == "test_2_1"
|
||||||
assert sub_2_1.get("subscription_value") == "is_2_1_overwritten"
|
assert sub_2_1.get("subscription_value") == "is_2_1_overwritten"
|
||||||
assert sub_2_1.get("subscription_indent_1") == "INDENT_1"
|
assert sub_2_1.get("subscription_indent_1") == "INDENT_1"
|
||||||
assert sub_2_1.get("subscription_indent_2") == "original_2"
|
assert sub_2_1.get("subscription_indent_2") == "original_2"
|
||||||
|
|
@ -299,6 +324,7 @@ def test_subscription_file_value_applies_from_config_and_nested_and_indent_varia
|
||||||
|
|
||||||
assert sub_1.get("test_config_subscription_value") == "is_1_overwritten"
|
assert sub_1.get("test_config_subscription_value") == "is_1_overwritten"
|
||||||
assert sub_1.get("subscription_name") == "test_1"
|
assert sub_1.get("subscription_name") == "test_1"
|
||||||
|
assert sub_1.get("subscription_name_sanitized") == "test_1"
|
||||||
assert sub_1.get("subscription_value") == "is_1_overwritten"
|
assert sub_1.get("subscription_value") == "is_1_overwritten"
|
||||||
assert sub_1.get("subscription_indent_1") == "INDENT_1"
|
assert sub_1.get("subscription_indent_1") == "INDENT_1"
|
||||||
assert sub_1.get("subscription_indent_2") == "INDENT_2"
|
assert sub_1.get("subscription_indent_2") == "INDENT_2"
|
||||||
|
|
@ -307,6 +333,7 @@ def test_subscription_file_value_applies_from_config_and_nested_and_indent_varia
|
||||||
|
|
||||||
assert sub_2_1.get("test_config_subscription_value") == "is_2_1_overwritten"
|
assert sub_2_1.get("test_config_subscription_value") == "is_2_1_overwritten"
|
||||||
assert sub_2_1.get("subscription_name") == "test_2_1"
|
assert sub_2_1.get("subscription_name") == "test_2_1"
|
||||||
|
assert sub_2_1.get("subscription_name_sanitized") == "test_2_1"
|
||||||
assert sub_2_1.get("subscription_value") == "is_2_1_overwritten"
|
assert sub_2_1.get("subscription_value") == "is_2_1_overwritten"
|
||||||
assert sub_2_1.get("subscription_indent_1") == "INDENT_1"
|
assert sub_2_1.get("subscription_indent_1") == "INDENT_1"
|
||||||
assert sub_2_1.get("subscription_indent_2") == "original_2"
|
assert sub_2_1.get("subscription_indent_2") == "original_2"
|
||||||
|
|
@ -314,6 +341,24 @@ def test_subscription_file_value_applies_from_config_and_nested_and_indent_varia
|
||||||
assert "subscription_indent_3" not in sub_2_1
|
assert "subscription_indent_3" not in sub_2_1
|
||||||
|
|
||||||
|
|
||||||
|
def test_subscription_file_value_applies_from_config_and_nested_and_indent_variables_same_line_old_format_errors(
|
||||||
|
config_file_with_subscription_value: ConfigFile,
|
||||||
|
preset_with_subscription_value_nested_presets_and_indent_variables_same_line_old_format_errors: Dict,
|
||||||
|
):
|
||||||
|
with mock_load_yaml(
|
||||||
|
preset_dict=preset_with_subscription_value_nested_presets_and_indent_variables_same_line_old_format_errors
|
||||||
|
), pytest.raises(
|
||||||
|
ValidationException,
|
||||||
|
match=re.escape(
|
||||||
|
"Validation error in parent_preset_2.=INDENT_1: 'INDENT_3' in '= INDENT_2 | INDENT_3' is not a preset name. "
|
||||||
|
"To use as a subscription indent value, define it as '= INDENT_3'"
|
||||||
|
),
|
||||||
|
):
|
||||||
|
Subscription.from_file_path(
|
||||||
|
config=config_file_with_subscription_value, subscription_path="mocked"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_subscription_file_bad_value(config_file: ConfigFile):
|
def test_subscription_file_bad_value(config_file: ConfigFile):
|
||||||
with mock_load_yaml(preset_dict={"__value__": {"should be": "string"}}), pytest.raises(
|
with mock_load_yaml(preset_dict={"__value__": {"should be": "string"}}), pytest.raises(
|
||||||
ValidationException,
|
ValidationException,
|
||||||
|
|
@ -346,7 +391,7 @@ def test_subscription_file_using_conflicting_preset_name(config_file: ConfigFile
|
||||||
def test_subscription_file_invalid_form(config_file: ConfigFile):
|
def test_subscription_file_invalid_form(config_file: ConfigFile):
|
||||||
with mock_load_yaml(preset_dict={"sub_name": 4332}), pytest.raises(
|
with mock_load_yaml(preset_dict={"sub_name": 4332}), pytest.raises(
|
||||||
ValidationException,
|
ValidationException,
|
||||||
match=re.escape(f"Validation error in sub_name: should be of type object."),
|
match=re.escape(f"Subscription value should either be a string, list, or object"),
|
||||||
):
|
):
|
||||||
_ = Subscription.from_file_path(config=config_file, subscription_path="mocked")
|
_ = Subscription.from_file_path(config=config_file, subscription_path="mocked")
|
||||||
|
|
||||||
|
|
@ -363,6 +408,7 @@ def test_tv_show_subscriptions(
|
||||||
jake_train_overrides = subs[2].overrides.dict_with_format_strings
|
jake_train_overrides = subs[2].overrides.dict_with_format_strings
|
||||||
|
|
||||||
assert jake_train_overrides["subscription_name"] == "Jake Trains"
|
assert jake_train_overrides["subscription_name"] == "Jake Trains"
|
||||||
|
assert jake_train_overrides["subscription_name_sanitized"] == "Jake Trains"
|
||||||
assert jake_train_overrides["subscription_value"] == "https://www.youtube.com/@JakeTrains"
|
assert jake_train_overrides["subscription_value"] == "https://www.youtube.com/@JakeTrains"
|
||||||
assert jake_train_overrides["subscription_indent_1"] == "Kids"
|
assert jake_train_overrides["subscription_indent_1"] == "Kids"
|
||||||
assert jake_train_overrides["subscription_indent_2"] == "TV-Y"
|
assert jake_train_overrides["subscription_indent_2"] == "TV-Y"
|
||||||
|
|
@ -378,6 +424,7 @@ def test_music_subscriptions(default_config: ConfigFile, music_subscriptions_pat
|
||||||
monk = subs[2].overrides.dict_with_format_strings
|
monk = subs[2].overrides.dict_with_format_strings
|
||||||
|
|
||||||
assert monk["subscription_name"] == "Stan Getz"
|
assert monk["subscription_name"] == "Stan Getz"
|
||||||
|
assert monk["subscription_name_sanitized"] == "Stan Getz"
|
||||||
assert monk["subscription_value"] == "https://www.youtube.com/@stangetzofficial/releases"
|
assert monk["subscription_value"] == "https://www.youtube.com/@stangetzofficial/releases"
|
||||||
assert monk["subscription_indent_1"] == "Jazz"
|
assert monk["subscription_indent_1"] == "Jazz"
|
||||||
|
|
||||||
|
|
@ -392,6 +439,7 @@ def test_music_video_subscriptions(default_config: ConfigFile, music_video_subsc
|
||||||
monk = subs[1].overrides.dict_with_format_strings
|
monk = subs[1].overrides.dict_with_format_strings
|
||||||
|
|
||||||
assert monk["subscription_name"] == "Michael Jackson"
|
assert monk["subscription_name"] == "Michael Jackson"
|
||||||
|
assert monk["subscription_name_sanitized"] == "Michael Jackson"
|
||||||
assert (
|
assert (
|
||||||
monk["subscription_value"]
|
monk["subscription_value"]
|
||||||
== "https://www.youtube.com/playlist?list=OLAK5uy_mnY03zP6abNWH929q2XhGzWD_2uKJ_n8E"
|
== "https://www.youtube.com/playlist?list=OLAK5uy_mnY03zP6abNWH929q2XhGzWD_2uKJ_n8E"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue