From 77487aee86ff8b80129f1a4df6c38e04f90f8cf9 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Mon, 24 Jul 2023 18:18:53 -0700 Subject: [PATCH] [FEATURE] Simplify ``video_tags`` (#661) * [FEATURE] Simplify ``video_tags`` * video tags old * change for episode * deprecation notice --- docs/config.rst | 2 - docs/deprecation_notices.rst | 23 ++++++++- src/ytdl_sub/plugins/video_tags.py | 28 ++++++++--- .../prebuilt_presets/tv_show/episode.yaml | 17 +++---- tests/e2e/youtube/test_video.py | 49 +++++++++++++++++-- 5 files changed, 98 insertions(+), 21 deletions(-) diff --git a/docs/config.rst b/docs/config.rst index 273328e7..71805d2d 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -248,8 +248,6 @@ subtitles video_tags '''''''''' .. autoclass:: ytdl_sub.plugins.video_tags.VideoTagsOptions() - :members: - :exclude-members: partial_validate ------------------------------------------------------------------------------- diff --git a/docs/deprecation_notices.rst b/docs/deprecation_notices.rst index e9875915..212beea0 100644 --- a/docs/deprecation_notices.rst +++ b/docs/deprecation_notices.rst @@ -7,7 +7,7 @@ July 2023 music_tags ^^^^^^^^^^ -Music tags is getting simplified. ``tags`` will now reside directly under music_tags, and +Music tags are getting simplified. ``tags`` will now reside directly under music_tags, and ``embed_thumbnail`` is getting moved to its own plugin (supports video files as well). Convert from: .. code-block:: yaml @@ -28,3 +28,24 @@ To the following: artist: "Elvis Presley" The old format will be removed in October 2023. + +video_tags +^^^^^^^^^^ + +Video tags are getting simplified as well. ``tags`` will now reside directly under video_tags. +Convert from: + +.. code-block:: yaml + + my_example_preset: + video_tags: + tags: + title: "Elvis Presley Documentary" + +To the following: + +.. code-block:: yaml + + my_example_preset: + video_tags: + title: "Elvis Presley Documentary" diff --git a/src/ytdl_sub/plugins/video_tags.py b/src/ytdl_sub/plugins/video_tags.py index fc5366f6..ebc4607d 100644 --- a/src/ytdl_sub/plugins/video_tags.py +++ b/src/ytdl_sub/plugins/video_tags.py @@ -1,3 +1,4 @@ +import copy from typing import Any from typing import Dict @@ -6,8 +7,11 @@ from ytdl_sub.entries.entry import Entry from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.utils.ffmpeg import add_ffmpeg_metadata_key_values from ytdl_sub.utils.file_handler import FileMetadata +from ytdl_sub.utils.logger import Logger from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator +logger = Logger.get("video_tags") + class VideoTagsOptions(OptionsDictValidator): """ @@ -20,13 +24,13 @@ class VideoTagsOptions(OptionsDictValidator): presets: my_example_preset: video_tags: - tags: - title: "{title}" - date: "{upload_date}" - description: "{description}" + title: "{title}" + date: "{upload_date}" + description: "{description}" """ - _required_keys = {"tags"} + _optional_keys = {"tags"} + _allow_extra_keys = True @classmethod def partial_validate(cls, name: str, value: Any) -> None: @@ -39,7 +43,12 @@ class VideoTagsOptions(OptionsDictValidator): def __init__(self, name, value): super().__init__(name, value) - self._tags = self._validate_key(key="tags", validator=DictFormatterValidator) + + new_tags_dict: Dict[str, Any] = copy.deepcopy(value) + old_tags_dict = new_tags_dict.pop("tags", {}) + + self._is_old_format = len(old_tags_dict) > 0 + self._tags = DictFormatterValidator(name=name, value=dict(old_tags_dict, **new_tags_dict)) @property def tags(self) -> DictFormatterValidator: @@ -56,6 +65,13 @@ class VideoTagsPlugin(Plugin[VideoTagsOptions]): """ Tags the entry's audio file using values defined in the metadata options """ + # pylint: disable=protected-access + if self.plugin_options._is_old_format: + logger.warning( + "video_tags.tags is now deprecated. Place your tags directly under video_tags " + "instead. The old format will be removed in October of 2023." + ) + tags_to_write: Dict[str, str] = {} for tag_name, tag_formatter in self.plugin_options.tags.dict.items(): tag_value = self.overrides.apply_formatter(formatter=tag_formatter, entry=entry) diff --git a/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml b/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml index c50ca842..2aec4ab5 100644 --- a/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml +++ b/src/ytdl_sub/prebuilt_presets/tv_show/episode.yaml @@ -38,15 +38,14 @@ presets: _episode_video_tags: video_tags: - tags: - show: "{tv_show_name}" - genre: "{tv_show_genre}" - episode_id: "{episode_number}" - title: "{episode_title}" - synopsis: "{episode_plot}" - year: "{episode_year}" - date: "{episode_date_standardized}" - contentRating: "{episode_content_rating}" + show: "{tv_show_name}" + genre: "{tv_show_genre}" + episode_id: "{episode_number}" + title: "{episode_title}" + synopsis: "{episode_plot}" + year: "{episode_year}" + date: "{episode_date_standardized}" + contentRating: "{episode_content_rating}" _episode_nfo_tags: nfo_tags: diff --git a/tests/e2e/youtube/test_video.py b/tests/e2e/youtube/test_video.py index 3219692d..7916eab4 100644 --- a/tests/e2e/youtube/test_video.py +++ b/tests/e2e/youtube/test_video.py @@ -7,6 +7,32 @@ from expected_transaction_log import assert_transaction_log_matches from ytdl_sub.subscriptions.subscription import Subscription +@pytest.fixture +def single_video_preset_dict_old_video_tags_format(output_directory): + return { + "preset": "music_video", + "download": {"url": "https://youtube.com/watch?v=HKTNxEqsN3Q"}, + # override the output directory with our fixture-generated dir + "output_options": { + "output_directory": output_directory, + "maintain_download_archive": False, + }, + # embed thumb into the video + "embed_thumbnail": True, + # download the worst format so it is fast + "ytdl_options": { + "format": "worst[ext=mp4]", + }, + # also test video tags + "video_tags": { + "tags": { + "title": "{title}", + } + }, + "overrides": {"artist": "JMC"}, + } + + @pytest.fixture def single_video_preset_dict(output_directory): return { @@ -25,9 +51,7 @@ def single_video_preset_dict(output_directory): }, # also test video tags "video_tags": { - "tags": { - "title": "{title}", - } + "title": "{title}", }, "overrides": {"artist": "JMC"}, } @@ -71,6 +95,25 @@ def single_video_preset_dict_dl_args(single_video_preset_dict): class TestYoutubeVideo: + def test_single_video_old_video_tags_format_download( + self, + music_video_config, + single_video_preset_dict_old_video_tags_format, + output_directory, + ): + single_video_subscription = Subscription.from_dict( + config=music_video_config, + preset_name="music_video_single_video_test", + preset_dict=single_video_preset_dict_old_video_tags_format, + ) + + transaction_log = single_video_subscription.download(dry_run=True) + assert_transaction_log_matches( + output_directory=output_directory, + transaction_log=transaction_log, + transaction_log_summary_file_name="youtube/test_video.txt", + ) + @pytest.mark.parametrize("dry_run", [True, False]) def test_single_video_download( self,