[BACKEND] Better error message for music_tags recieving a video (#413)

* [BACKEND] Better error message for music_tags recieving a video

* test and better message
This commit is contained in:
Jesse Bannon 2023-01-13 10:25:17 -08:00 committed by GitHub
parent c95c0f6aa4
commit 6020f27f12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 0 deletions

View file

@ -11,6 +11,7 @@ from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.file_handler import FileMetadata
from ytdl_sub.utils.logger import Logger from ytdl_sub.utils.logger import Logger
from ytdl_sub.utils.thumbnail import convert_download_thumbnail from ytdl_sub.utils.thumbnail import convert_download_thumbnail
from ytdl_sub.validators.audo_codec_validator import AUDIO_CODEC_EXTS
from ytdl_sub.validators.strict_dict_validator import StrictDictValidator from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
from ytdl_sub.validators.string_formatter_validators import ListFormatterValidator from ytdl_sub.validators.string_formatter_validators import ListFormatterValidator
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
@ -116,6 +117,13 @@ class MusicTagsPlugin(Plugin[MusicTagsOptions]):
""" """
Tags the entry's audio file using values defined in the metadata options Tags the entry's audio file using values defined in the metadata options
""" """
if entry.ext not in AUDIO_CODEC_EXTS:
raise self.plugin_options.validation_exception(
f"music_tags plugin received a video with the extension '{entry.ext}'. Only audio "
f"files are supported for setting music tags. Ensure you are converting the video "
f"to audio using the audio_extract plugin."
)
# Resolve the tags into this dict # Resolve the tags into this dict
tags_to_write: Dict[str, List[str]] = defaultdict(list) tags_to_write: Dict[str, List[str]] = defaultdict(list)
for tag_name, tag_formatters in self.plugin_options.tags.as_lists.items(): for tag_name, tag_formatters in self.plugin_options.tags.as_lists.items():

View file

@ -10,6 +10,7 @@ from typing import TypeVar
from ytdl_sub.config.preset_options import AddsVariablesMixin from ytdl_sub.config.preset_options import AddsVariablesMixin
from ytdl_sub.config.preset_options import Overrides from ytdl_sub.config.preset_options import Overrides
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.file_handler import FileMetadata
from ytdl_sub.utils.logger import Logger from ytdl_sub.utils.logger import Logger
from ytdl_sub.validators.strict_dict_validator import StrictDictValidator from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
@ -44,6 +45,23 @@ class PluginOptions(StrictDictValidator, AddsVariablesMixin, ABC):
Class that defines the parameters to a plugin Class that defines the parameters to a plugin
""" """
def validation_exception(
self,
error_message: str | Exception,
) -> ValidationException:
"""
Parameters
----------
error_message
Error message to include in the validation exception
Returns
-------
Validation exception that points to the location in the config. To be used for plugins
to throw good validation exceptions at runtime.
"""
return self._validation_exception(error_message=error_message)
PluginOptionsT = TypeVar("PluginOptionsT", bound=PluginOptions) PluginOptionsT = TypeVar("PluginOptionsT", bound=PluginOptions)

View file

@ -0,0 +1,51 @@
import re
import pytest
from expected_download import assert_expected_downloads
from expected_transaction_log import assert_transaction_log_matches
from ytdl_sub.subscriptions.subscription import Subscription
from ytdl_sub.utils.exceptions import ValidationException
@pytest.fixture
def single_song_video_dict(output_directory):
return {
"download": {
"download_strategy": "url",
"url": "https://www.youtube.com/watch?v=2lAe1cqCOXo",
},
"output_options": {"output_directory": output_directory, "file_name": "will_error.mp4"},
# test multi-tags
"music_tags": {"embed_thumbnail": True, "tags": {"genres": ["multi_tag_1", "multi_tag_2"]}},
# download the worst format so it is fast
"ytdl_options": {
"format": "worst[ext=mp4]",
"postprocessor_args": {"ffmpeg": ["-bitexact"]}, # Must add this for reproducibility
},
}
class TestMusicTags:
def test_music_tags_errors_on_video(
self,
youtube_audio_config,
single_song_video_dict,
output_directory,
):
subscription = Subscription.from_dict(
config=youtube_audio_config,
preset_name="single_song_test",
preset_dict=single_song_video_dict,
)
with pytest.raises(
ValidationException,
match=re.escape(
"Validation error in single_song_test.music_tags: music_tags plugin received a "
"video with the extension 'mp4'. Only audio files are supported for setting music "
"tags. Ensure you are converting the video to audio using the audio_extract "
"plugin."
),
):
subscription.download(dry_run=True)