[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:
parent
c95c0f6aa4
commit
6020f27f12
3 changed files with 77 additions and 0 deletions
|
|
@ -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():
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
51
tests/e2e/plugins/test_music_tags.py
Normal file
51
tests/e2e/plugins/test_music_tags.py
Normal 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)
|
||||||
Loading…
Reference in a new issue