This commit is contained in:
Jesse Bannon 2023-10-02 15:47:20 -07:00
parent f9665ff066
commit e2e309b3ef
4 changed files with 98 additions and 28 deletions

View file

@ -299,8 +299,66 @@ custom variables: ``{output_directory}``, ``{playlist_name}``, and ``{url}``. Th
the `parent preset`_ to ``playlist_preset_ex``, and must define the variables ``{playlist_name}``
and ``{url}`` since the preset did not.
.. _beautifying subscriptions:
Beautifying Subscriptions
^^^^^^^^^^^^^^^^^^^^^^^^^
Subscriptions support using presets as keys, and using keys to set override variables as values.
For example:
.. code-block:: yaml
:caption: subscription.yaml
tv_show:
only_recent:
[News]:
"Breaking News": "https://www.youtube.com/@SomeBreakingNews"
[Tech]:
"Two Minute Papers": "https://www.youtube.com/@TwoMinutePapers"
Will create two subscriptions named "Breaking News" and "Two Minute Papers", equivalent to:
.. code-block:: yaml
"Breaking News":
preset:
- "tv_show"
- "only_recent"
overrides:
subscription_indent_1: "News"
subscription_name: "Breaking News"
subscription_value: "https://www.youtube.com/@SomeBreakingNews"
"Two Minute Papers":
preset:
- "tv_show"
overrides:
subscription_indent_1: "Tech"
subscription_name: "Two Minute Papers"
subscription_value: "https://www.youtube.com/@TwoMinutePapers"
You can provide as many parent presets in the form of keys, and subscription indents as ``[keys]``.
This can drastically simplify subscription definitions by setting things like so in your
parent preset:
.. code-block:: yaml
presets:
tv_show_name:
overrides:
tv_show_name: "{subscription_name}"
url: "{subscription_value}"
genre: "{subscription_indent_1}"
.. _subscription value:
File Preset
^^^^^^^^^^^
NOTE: This is deprecated in favor of using the method in :ref:`beautifying subscriptions`.
You can apply a preset to all subscriptions in the ``subscription.yaml`` file
by using the file-wide ``__preset__``:
@ -318,10 +376,11 @@ by using the file-wide ``__preset__``:
This ``subscription.yaml`` is equivalent to the one above it because all
subscriptions automatically set ``__preset__`` as a `parent preset`_.
.. _subscription value:
Subscription Value
^^^^^^^^^^^^^^^^^^^
NOTE: This is deprecated in favor of using the method in :ref:`beautifying subscriptions`.
With a clever config and use of ``__preset__``, your subscriptions can typically boil
down to a name and url. You can set ``__value__`` to the name of an override variable,
and use the override variable ``subscription_name`` to achieve one-liner subscriptions.

View file

@ -9,12 +9,15 @@ from ytdl_sub.config.preset import Preset
from ytdl_sub.subscriptions.subscription_download import SubscriptionDownload
from ytdl_sub.subscriptions.subscription_validators import SubscriptionValidator
from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.logger import Logger
from ytdl_sub.utils.yaml import load_yaml
from ytdl_sub.validators.validators import LiteralDictValidator
FILE_PRESET_APPLY_KEY = "__preset__"
FILE_SUBSCRIPTION_VALUE_KEY = "__value__"
logger = Logger.get("subscription")
class Subscription(SubscriptionDownload):
@classmethod
@ -70,15 +73,23 @@ class Subscription(SubscriptionDownload):
def _maybe_get_subscription_value(
cls, config: ConfigFile, subscription_dict: Dict
) -> Optional[str]:
subscription_value_key: Optional[str] = config.config_options.subscription_value
if FILE_SUBSCRIPTION_VALUE_KEY in subscription_dict:
if not isinstance(subscription_dict[FILE_SUBSCRIPTION_VALUE_KEY], str):
raise ValidationException(
f"Using {FILE_SUBSCRIPTION_VALUE_KEY} in a subscription"
f"must be a string that corresponds to an override variable"
)
return subscription_dict[FILE_SUBSCRIPTION_VALUE_KEY]
return config.config_options.subscription_value # can be None
subscription_value_key = subscription_dict[FILE_SUBSCRIPTION_VALUE_KEY]
if subscription_value_key is not None:
logger.warning(
"Using %s in a subscription will eventually be deprecated in favor of writing "
"to the override variable `subscription_value`. Please update by Dec 2023.",
FILE_SUBSCRIPTION_VALUE_KEY,
)
return subscription_value_key
@classmethod
def from_file_path(cls, config: ConfigFile, subscription_path: str) -> List["Subscription"]:

View file

@ -27,6 +27,15 @@ def subscription_indent_variable_name(index: int) -> str:
return f"subscription_indent_{index + 1}"
def subscription_value_variable_name() -> str:
"""
Returns
-------
The override variable name containing the subscription value if present
"""
return "subscription_value"
def maybe_indent_override_value(value: str) -> Optional[str]:
"""
Returns
@ -117,7 +126,11 @@ class SubscriptionValueValidator(SubscriptionOutput, StringValidator):
self._leaf_name: {
"preset": self._presets,
"overrides": dict(
{self._subscription_value: self.value}, **self._indent_overrides_dict()
{
self._subscription_value: self.value,
"subscription_value": self.value,
},
**self._indent_overrides_dict(),
),
}
}

View file

@ -138,15 +138,12 @@ def test_subscription_file_value_applies(
# Test __value__ worked correctly
value_sub = subs[1]
overrides = value_sub.overrides.dict_with_format_strings
assert value_sub.name == "test_value"
assert (
value_sub.overrides.dict_with_format_strings.get("test_file_subscription_value")
== "is_overwritten"
)
assert (
value_sub.overrides.dict_with_format_strings.get("test_config_subscription_value")
== "original"
)
assert overrides.get("test_file_subscription_value") == "is_overwritten"
assert overrides.get("test_file_subscription_value")
assert overrides.get("subscription_value") == "is_overwritten"
def test_subscription_file_value_applies_sub_file_takes_precedence(
@ -161,15 +158,10 @@ def test_subscription_file_value_applies_sub_file_takes_precedence(
# Test __value__ worked correctly
value_sub = subs[1]
overrides = value_sub.overrides.dict_with_format_strings
assert value_sub.name == "test_value"
assert (
value_sub.overrides.dict_with_format_strings.get("test_file_subscription_value")
== "is_overwritten"
)
assert (
value_sub.overrides.dict_with_format_strings.get("test_config_subscription_value")
== "original"
)
assert overrides.get("test_file_subscription_value") == "is_overwritten"
assert overrides.get("test_config_subscription_value") == "original"
def test_subscription_file_value_applies_from_config(
@ -183,15 +175,10 @@ def test_subscription_file_value_applies_from_config(
# Test __value__ worked correctly from the config
value_sub = subs[1]
overrides = value_sub.overrides.dict_with_format_strings
assert value_sub.name == "test_value"
assert (
value_sub.overrides.dict_with_format_strings.get("test_file_subscription_value")
== "original"
)
assert (
value_sub.overrides.dict_with_format_strings.get("test_config_subscription_value")
== "is_overwritten"
)
assert overrides.get("test_file_subscription_value") == "original"
assert overrides.get("test_config_subscription_value") == "is_overwritten"
def test_subscription_file_value_applies_from_config_and_nested(