[BACKEND] Disallow override names conflicting with plugin names (#1399)
Disallow override variable names conflicting with plugin names. May cause backward incompatible issues from `date_range` being an old override variable name for the `Only Recent` preset. Update this variable name to `only_recent_date_range` to resolve. More info in https://ytdl-sub.readthedocs.io/en/latest/deprecation_notices.html
This commit is contained in:
parent
157a0b59c4
commit
0f96d8e24e
7 changed files with 57 additions and 7 deletions
|
|
@ -1,6 +1,15 @@
|
||||||
Deprecation Notices
|
Deprecation Notices
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
Dec 2025
|
||||||
|
--------
|
||||||
|
|
||||||
|
Override variables names can no longer be plugin names, to avoid the common pitfall of
|
||||||
|
defining a plugin underneath ``overrides``.
|
||||||
|
|
||||||
|
In the past, there was usage of a ``date_range`` override variable in a few example configs
|
||||||
|
that complimented the ``Only Recent`` preset. This overrride variable usage needs to be
|
||||||
|
replaced with ``only_recent_date_range``.
|
||||||
|
|
||||||
Sep 2024
|
Sep 2024
|
||||||
--------
|
--------
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,6 @@ TV Show Only Recent:
|
||||||
# to set only for that subscriptions
|
# to set only for that subscriptions
|
||||||
"~BBC News":
|
"~BBC News":
|
||||||
url: "https://www.youtube.com/@BBCNews" # use url2, url3, ... for multi-url in this form
|
url: "https://www.youtube.com/@BBCNews" # use url2, url3, ... for multi-url in this form
|
||||||
date_range: "2weeks"
|
only_recent_date_range: "2weeks"
|
||||||
"Frontline PBS": "https://www.youtube.com/@frontline"
|
"Frontline PBS": "https://www.youtube.com/@frontline"
|
||||||
"Whitehouse": "https://www.bitchute.com/channel/zWsYVmCOu4JA/" # Supports non-YT sites
|
"Whitehouse": "https://www.bitchute.com/channel/zWsYVmCOu4JA/" # Supports non-YT sites
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
from typing import Iterable
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Set
|
from typing import Set
|
||||||
|
|
||||||
|
|
@ -88,6 +89,24 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def ensure_variable_names_not_a_plugin(self, plugin_names: Iterable[str]) -> None:
|
||||||
|
"""
|
||||||
|
Throws an error if an override variable or function has the same name as a
|
||||||
|
preset key. This is to avoid confusion when accidentally defining things in
|
||||||
|
overrides that are meant to be in the preset.
|
||||||
|
"""
|
||||||
|
for name in self.keys:
|
||||||
|
if name.startswith("%"):
|
||||||
|
name = name[1:]
|
||||||
|
|
||||||
|
if name in plugin_names:
|
||||||
|
raise self._validation_exception(
|
||||||
|
f"Override variable with name {name} cannot be used since it is"
|
||||||
|
" the name of a plugin. Perhaps you meant to define it as a plugin? If so,"
|
||||||
|
" indent it left to make it at the same level as overrides.",
|
||||||
|
exception_class=InvalidVariableNameException,
|
||||||
|
)
|
||||||
|
|
||||||
def ensure_variable_name_valid(self, name: str) -> None:
|
def ensure_variable_name_valid(self, name: str) -> None:
|
||||||
"""
|
"""
|
||||||
Ensures the variable name does not collide with any entry variables or built-in functions.
|
Ensures the variable name does not collide with any entry variables or built-in functions.
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,8 @@ class Preset(_PresetShell):
|
||||||
self.plugins: PresetPlugins = self._validate_and_get_plugins()
|
self.plugins: PresetPlugins = self._validate_and_get_plugins()
|
||||||
self.overrides = self._validate_key(key="overrides", validator=Overrides, default={})
|
self.overrides = self._validate_key(key="overrides", validator=Overrides, default={})
|
||||||
|
|
||||||
|
self.overrides.ensure_variable_names_not_a_plugin(plugin_names=PRESET_KEYS)
|
||||||
|
|
||||||
VariableValidation(
|
VariableValidation(
|
||||||
downloader_options=self.downloader_options,
|
downloader_options=self.downloader_options,
|
||||||
output_options=self.output_options,
|
output_options=self.output_options,
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,6 @@ from ytdl_sub.entries.script.variable_types import Variable
|
||||||
from ytdl_sub.script.functions import Functions
|
from ytdl_sub.script.functions import Functions
|
||||||
from ytdl_sub.script.utils.name_validation import is_valid_name
|
from ytdl_sub.script.utils.name_validation import is_valid_name
|
||||||
|
|
||||||
# TODO: use this
|
|
||||||
SUBSCRIPTION_ARRAY = "subscription_array"
|
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionVariables:
|
class SubscriptionVariables:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
@ -163,7 +160,7 @@ class OverrideHelpers:
|
||||||
True if the override name itself is valid. False otherwise.
|
True if the override name itself is valid. False otherwise.
|
||||||
"""
|
"""
|
||||||
if name.startswith("%"):
|
if name.startswith("%"):
|
||||||
return is_valid_name(name=name[1:])
|
name = name[1:]
|
||||||
|
|
||||||
return is_valid_name(name=name)
|
return is_valid_name(name=name)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ presets:
|
||||||
|
|
||||||
# Set the default date_range to 2 months
|
# Set the default date_range to 2 months
|
||||||
overrides:
|
overrides:
|
||||||
date_range: "2months" # keep for legacy-reasons
|
only_recent_date_range: "2months"
|
||||||
only_recent_date_range: "{date_range}"
|
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# Only Recent
|
# Only Recent
|
||||||
|
|
|
||||||
|
|
@ -435,3 +435,27 @@ class TestPreset:
|
||||||
"output_options": {"output_directory": "dir", "file_name": "acjk"},
|
"output_options": {"output_directory": "dir", "file_name": "acjk"},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_preset_error_override_name_conflicts_with_plugin(self, config_file, output_options):
|
||||||
|
with pytest.raises(
|
||||||
|
ValidationException,
|
||||||
|
match=re.escape(
|
||||||
|
"Override variable with name throttle_protection cannot be used since it is the "
|
||||||
|
"name of a plugin. Perhaps you meant to define it as a plugin? If so, indent it "
|
||||||
|
"left to make it at the same level as overrides."
|
||||||
|
),
|
||||||
|
):
|
||||||
|
_ = Preset(
|
||||||
|
config=config_file,
|
||||||
|
name="test",
|
||||||
|
value={
|
||||||
|
"download": {
|
||||||
|
"url": "youtube.com/watch?v=123abc",
|
||||||
|
},
|
||||||
|
"subtitles": {
|
||||||
|
"embed_subtitles": True,
|
||||||
|
},
|
||||||
|
"output_options": {"output_directory": "dir", "file_name": "acjk"},
|
||||||
|
"overrides": {"throttle_protection": "nope"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue