ytdl-sub/src/ytdl_sub/entries/variables/override_variables.py
Ross Patterson a642028d7b
[DOCS] Clarify the = YAML key prefix (#1297)
This is another change that touches the generated docs, so after finishing my writing, I
copied the change to `./docs/source/config_reference/scripting/static_variables.rst`
into the corresponding docstring in
`./src/ytdl_sub/entries/variables/override_variables.py` and formatted it as a
docstring. Then I ran:

    $ REGENERATE_DOCS=1 tox exec -e "py" -- pytest tests/unit/docgen/test_docgen.py

But all that did was revert the changes to
`./docs/source/config_reference/scripting/static_variables.rst`. IOW, it did *not*
update the rST from the changed docstring.
2025-08-24 09:17:38 -07:00

182 lines
5.9 KiB
Python

from typing import Dict
from typing import Set
from ytdl_sub.entries.script.function_scripts import CUSTOM_FUNCTION_SCRIPTS
from ytdl_sub.entries.script.variable_definitions import VARIABLE_SCRIPTS
from ytdl_sub.entries.script.variable_types import ArrayVariable
from ytdl_sub.entries.script.variable_types import BooleanVariable
from ytdl_sub.entries.script.variable_types import MapVariable
from ytdl_sub.entries.script.variable_types import StringVariable
from ytdl_sub.entries.script.variable_types import Variable
from ytdl_sub.script.functions import Functions
from ytdl_sub.script.utils.name_validation import is_valid_name
# TODO: use this
SUBSCRIPTION_ARRAY = "subscription_array"
class SubscriptionVariables:
@staticmethod
def subscription_name() -> StringVariable:
"""
Name of the subscription. For subscriptions types that use a prefix (``~``, ``+``),
the prefix and all whitespace afterwards is stripped from the subscription name.
"""
return StringVariable(variable_name="subscription_name", definition="{ %string('') }")
@staticmethod
def subscription_value() -> StringVariable:
"""
For subscriptions in the form of
.. code-block:: yaml
"Subscription Name": "https://..."
``subscription_value`` gets set to ``https://...``.
"""
return StringVariable(variable_name="subscription_value", definition="{ %string('') }")
@staticmethod
def subscription_array() -> ArrayVariable:
"""
For subscriptions in the form of
.. code-block:: yaml
"Subscription Name":
- "https://url1.com/..."
- "https://url2.com/..."
Store all values into an array named ``subscription_array``.
"""
return ArrayVariable(variable_name="subscription_array", definition="{ [] }")
@staticmethod
def subscription_indent_i(index: int) -> StringVariable:
"""
For subscriptions where the ancestor keys contain the ``= ...`` prefix, the
variables ``subscription_indent_1``, ``subscription_indent_2``, and so on get
set to each subsequent value. For example, given the following subscriptions
file snippet:
.. code-block:: yaml
Preset 1 | = Indent Value 1 | Preset 2:
Preset 3 | = Indent Value 2 | Preset 4:
"Subscription Name": "https://..."
The ``{subscription_indent_1}`` variable will be ``Indent Value 1`` and
``{subscription_indent_2}`` will be ``Indent Value 2``. The most common use of
these variables is to :doc:`set the genre and rating for subscriptions from the
YAML keys <../prebuilt_presets/tv_show>`.
"""
return StringVariable(
variable_name=f"subscription_indent_{index + 1}", definition="{ %string('') }"
)
@staticmethod
def subscription_value_i(index: int) -> StringVariable:
"""
For subscriptions in the form of
.. code-block:: yaml
"Subscription Name":
- "https://url1.com/..."
- "https://url2.com/..."
``subscription_value_1`` and ``subscription_value_2`` get set to ``https://url1.com/...``
and ``https://url2.com/...``. Note that ``subscription_value_1`` also gets set to
``subscription_value``.
"""
return StringVariable(
variable_name=f"subscription_value_{index + 1}", definition="{ %string('') }"
)
@staticmethod
def subscription_map() -> MapVariable:
"""
For subscriptions in the form of
.. code-block:: yaml
+ Subscription Name:
Music Videos:
- "https://url1.com/..."
Concerts:
- "https://url2.com/..."
Stores all the contents under the subscription name into the override variable
``subscription_map`` as a Map value. The above example is stored as:
.. code-block:: python
{
"Music Videos": [
"https://url1.com/..."
],
"Concerts: [
"https://url2.com/..."
]
}
"""
return MapVariable(variable_name="subscription_map", definition="{ {} }")
@staticmethod
def subscription_has_download_archive() -> BooleanVariable:
"""
Returns True if the subscription has any entries recorded in a download archive. False
otherwise.
"""
return BooleanVariable(
variable_name="subscription_has_download_archive", definition="{ %bool(True) }"
)
class OverrideHelpers:
@classmethod
def is_entry_variable_name(cls, name: str) -> bool:
"""
Returns
-------
True if the name is an entry variable name. False otherwise.
"""
return name in VARIABLE_SCRIPTS
@classmethod
def is_function_name(cls, name: str) -> bool:
"""
Returns
-------
True if the name is a function name (either built-in or script). False otherwise.
"""
if name.startswith("%"):
return name in CUSTOM_FUNCTION_SCRIPTS or Functions.is_built_in(name[1:])
return False
@classmethod
def is_valid_name(cls, name: str) -> bool:
"""
Returns
-------
True if the override name itself is valid. False otherwise.
"""
if name.startswith("%"):
return is_valid_name(name=name[1:])
return is_valid_name(name=name)
REQUIRED_OVERRIDE_VARIABLES: Set[Variable] = {
SubscriptionVariables.subscription_name(),
SubscriptionVariables.subscription_has_download_archive(),
}
REQUIRED_OVERRIDE_VARIABLE_DEFINITIONS: Dict[str, str] = {
var.variable_name: var.definition for var in REQUIRED_OVERRIDE_VARIABLES
}
REQUIRED_OVERRIDE_VARIABLE_NAMES: Set[str] = {
var.variable_name for var in REQUIRED_OVERRIDE_VARIABLES
}