docs
This commit is contained in:
parent
f9665ff066
commit
e2e309b3ef
4 changed files with 98 additions and 28 deletions
|
|
@ -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}``
|
the `parent preset`_ to ``playlist_preset_ex``, and must define the variables ``{playlist_name}``
|
||||||
and ``{url}`` since the preset did not.
|
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
|
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
|
You can apply a preset to all subscriptions in the ``subscription.yaml`` file
|
||||||
by using the file-wide ``__preset__``:
|
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
|
This ``subscription.yaml`` is equivalent to the one above it because all
|
||||||
subscriptions automatically set ``__preset__`` as a `parent preset`_.
|
subscriptions automatically set ``__preset__`` as a `parent preset`_.
|
||||||
|
|
||||||
.. _subscription value:
|
|
||||||
|
|
||||||
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
|
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,
|
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.
|
and use the override variable ``subscription_name`` to achieve one-liner subscriptions.
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,15 @@ from ytdl_sub.config.preset import Preset
|
||||||
from ytdl_sub.subscriptions.subscription_download import SubscriptionDownload
|
from ytdl_sub.subscriptions.subscription_download import SubscriptionDownload
|
||||||
from ytdl_sub.subscriptions.subscription_validators import SubscriptionValidator
|
from ytdl_sub.subscriptions.subscription_validators import SubscriptionValidator
|
||||||
from ytdl_sub.utils.exceptions import ValidationException
|
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.utils.yaml import load_yaml
|
||||||
from ytdl_sub.validators.validators import LiteralDictValidator
|
from ytdl_sub.validators.validators import LiteralDictValidator
|
||||||
|
|
||||||
FILE_PRESET_APPLY_KEY = "__preset__"
|
FILE_PRESET_APPLY_KEY = "__preset__"
|
||||||
FILE_SUBSCRIPTION_VALUE_KEY = "__value__"
|
FILE_SUBSCRIPTION_VALUE_KEY = "__value__"
|
||||||
|
|
||||||
|
logger = Logger.get("subscription")
|
||||||
|
|
||||||
|
|
||||||
class Subscription(SubscriptionDownload):
|
class Subscription(SubscriptionDownload):
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
@ -70,15 +73,23 @@ class Subscription(SubscriptionDownload):
|
||||||
def _maybe_get_subscription_value(
|
def _maybe_get_subscription_value(
|
||||||
cls, config: ConfigFile, subscription_dict: Dict
|
cls, config: ConfigFile, subscription_dict: Dict
|
||||||
) -> Optional[str]:
|
) -> Optional[str]:
|
||||||
|
subscription_value_key: Optional[str] = config.config_options.subscription_value
|
||||||
if FILE_SUBSCRIPTION_VALUE_KEY in subscription_dict:
|
if FILE_SUBSCRIPTION_VALUE_KEY in subscription_dict:
|
||||||
if not isinstance(subscription_dict[FILE_SUBSCRIPTION_VALUE_KEY], str):
|
if not isinstance(subscription_dict[FILE_SUBSCRIPTION_VALUE_KEY], str):
|
||||||
raise ValidationException(
|
raise ValidationException(
|
||||||
f"Using {FILE_SUBSCRIPTION_VALUE_KEY} in a subscription"
|
f"Using {FILE_SUBSCRIPTION_VALUE_KEY} in a subscription"
|
||||||
f"must be a string that corresponds to an override variable"
|
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
|
@classmethod
|
||||||
def from_file_path(cls, config: ConfigFile, subscription_path: str) -> List["Subscription"]:
|
def from_file_path(cls, config: ConfigFile, subscription_path: str) -> List["Subscription"]:
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,15 @@ def subscription_indent_variable_name(index: int) -> str:
|
||||||
return f"subscription_indent_{index + 1}"
|
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]:
|
def maybe_indent_override_value(value: str) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
Returns
|
Returns
|
||||||
|
|
@ -117,7 +126,11 @@ class SubscriptionValueValidator(SubscriptionOutput, StringValidator):
|
||||||
self._leaf_name: {
|
self._leaf_name: {
|
||||||
"preset": self._presets,
|
"preset": self._presets,
|
||||||
"overrides": dict(
|
"overrides": dict(
|
||||||
{self._subscription_value: self.value}, **self._indent_overrides_dict()
|
{
|
||||||
|
self._subscription_value: self.value,
|
||||||
|
"subscription_value": self.value,
|
||||||
|
},
|
||||||
|
**self._indent_overrides_dict(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,15 +138,12 @@ def test_subscription_file_value_applies(
|
||||||
|
|
||||||
# Test __value__ worked correctly
|
# Test __value__ worked correctly
|
||||||
value_sub = subs[1]
|
value_sub = subs[1]
|
||||||
|
overrides = value_sub.overrides.dict_with_format_strings
|
||||||
assert value_sub.name == "test_value"
|
assert value_sub.name == "test_value"
|
||||||
assert (
|
|
||||||
value_sub.overrides.dict_with_format_strings.get("test_file_subscription_value")
|
assert overrides.get("test_file_subscription_value") == "is_overwritten"
|
||||||
== "is_overwritten"
|
assert overrides.get("test_file_subscription_value")
|
||||||
)
|
assert overrides.get("subscription_value") == "is_overwritten"
|
||||||
assert (
|
|
||||||
value_sub.overrides.dict_with_format_strings.get("test_config_subscription_value")
|
|
||||||
== "original"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_subscription_file_value_applies_sub_file_takes_precedence(
|
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
|
# Test __value__ worked correctly
|
||||||
value_sub = subs[1]
|
value_sub = subs[1]
|
||||||
|
overrides = value_sub.overrides.dict_with_format_strings
|
||||||
assert value_sub.name == "test_value"
|
assert value_sub.name == "test_value"
|
||||||
assert (
|
assert overrides.get("test_file_subscription_value") == "is_overwritten"
|
||||||
value_sub.overrides.dict_with_format_strings.get("test_file_subscription_value")
|
assert overrides.get("test_config_subscription_value") == "original"
|
||||||
== "is_overwritten"
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
value_sub.overrides.dict_with_format_strings.get("test_config_subscription_value")
|
|
||||||
== "original"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_subscription_file_value_applies_from_config(
|
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
|
# Test __value__ worked correctly from the config
|
||||||
value_sub = subs[1]
|
value_sub = subs[1]
|
||||||
|
overrides = value_sub.overrides.dict_with_format_strings
|
||||||
assert value_sub.name == "test_value"
|
assert value_sub.name == "test_value"
|
||||||
assert (
|
assert overrides.get("test_file_subscription_value") == "original"
|
||||||
value_sub.overrides.dict_with_format_strings.get("test_file_subscription_value")
|
assert overrides.get("test_config_subscription_value") == "is_overwritten"
|
||||||
== "original"
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
value_sub.overrides.dict_with_format_strings.get("test_config_subscription_value")
|
|
||||||
== "is_overwritten"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_subscription_file_value_applies_from_config_and_nested(
|
def test_subscription_file_value_applies_from_config_and_nested(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue