diff --git a/docs/config.rst b/docs/config.rst index adb05693..7a9736e0 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -250,8 +250,6 @@ subtitles video_tags '''''''''' .. autoclass:: ytdl_sub.plugins.video_tags.VideoTagsOptions() - :members: - :exclude-members: partial_validate ------------------------------------------------------------------------------- diff --git a/src/ytdl_sub/plugins/video_tags.py b/src/ytdl_sub/plugins/video_tags.py index 07b57e07..ebc4607d 100644 --- a/src/ytdl_sub/plugins/video_tags.py +++ b/src/ytdl_sub/plugins/video_tags.py @@ -7,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): """ @@ -21,10 +24,9 @@ class VideoTagsOptions(OptionsDictValidator): presets: my_example_preset: video_tags: - tags: - title: "{title}" - date: "{upload_date}" - description: "{description}" + title: "{title}" + date: "{upload_date}" + description: "{description}" """ _optional_keys = {"tags"} @@ -41,12 +43,12 @@ class VideoTagsOptions(OptionsDictValidator): def __init__(self, name, value): super().__init__(name, value) - old_tags = self._validate_key(key="tags", validator=DictFormatterValidator, default={}) new_tags_dict: Dict[str, Any] = copy.deepcopy(value) - new_tags_dict.pop("tags", None) + old_tags_dict = new_tags_dict.pop("tags", {}) - self._tags = DictFormatterValidator(name=name, value=dict(old_tags._dict, **new_tags_dict)) + 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: @@ -63,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/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,