From 72c8f6ea28ce4c7265afada7b11f17be4afafa12 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Tue, 27 Feb 2024 09:18:57 -0800 Subject: [PATCH] docs, type-checking --- docs/source/config_reference/plugins.rst | 4 +++ src/ytdl_sub/plugins/music_tags.py | 34 ++++++++++++++----- .../prebuilt_presets/music/singles.yaml | 1 + 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/docs/source/config_reference/plugins.rst b/docs/source/config_reference/plugins.rst index 7e9d1688..52010d57 100644 --- a/docs/source/config_reference/plugins.rst +++ b/docs/source/config_reference/plugins.rst @@ -402,6 +402,9 @@ It supports basic tags like ``title``, ``album``, ``artist`` and ``albumartist`` a full list of tags for various file types in MediaFile's `source code `_. +Note that the date fields ``date`` and ``original_date`` expected a standardized date in the +form of YYYY-MM-DD. The variable ``upload_date_standardized`` returns a compatible format. + :Usage: .. code-block:: yaml @@ -418,6 +421,7 @@ a full list of tags for various file types in MediaFile's albumartists: - "{artist}" - "ytdl-sub" + date: "{upload_date_standardized}" ---------------------------------------------------------------------------------------------------- diff --git a/src/ytdl_sub/plugins/music_tags.py b/src/ytdl_sub/plugins/music_tags.py index 9221f228..e8439a98 100644 --- a/src/ytdl_sub/plugins/music_tags.py +++ b/src/ytdl_sub/plugins/music_tags.py @@ -1,15 +1,17 @@ from collections import defaultdict +from datetime import datetime +from typing import Any from typing import Dict from typing import List import mediafile -import datetime from ytdl_sub.config.plugin.plugin import Plugin from ytdl_sub.config.validators.options import OptionsDictValidator from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.script.variable_definitions import VARIABLES from ytdl_sub.entries.script.variable_definitions import VariableDefinitions +from ytdl_sub.utils.exceptions import ValidationException from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.logger import Logger from ytdl_sub.validators.audo_codec_validator import AUDIO_CODEC_EXTS @@ -36,6 +38,7 @@ def _is_multi_field(tag_name: str) -> bool: "mb_albumartistids", } + def _is_date_field(tag_name: str) -> bool: return tag_name in { "date", @@ -43,6 +46,10 @@ def _is_date_field(tag_name: str) -> bool: } +def _to_datetime(tag_value: str) -> Any: + return datetime.strptime(tag_value, "%Y-%m-%d") + + class MusicTagsOptions(OptionsDictValidator): """ Adds tags to every download audio file using @@ -53,6 +60,9 @@ class MusicTagsOptions(OptionsDictValidator): a full list of tags for various file types in MediaFile's `source code `_. + Note that the date fields ``date`` and ``original_date`` expected a standardized date in the + form of YYYY-MM-DD. The variable ``upload_date_standardized`` returns a compatible format. + :Usage: .. code-block:: yaml @@ -69,6 +79,7 @@ class MusicTagsOptions(OptionsDictValidator): albumartists: - "{artist}" - "ytdl-sub" + date: "{upload_date_standardized}" """ _optional_keys = set(list(mediafile.MediaFile.sorted_fields())) @@ -111,20 +122,27 @@ class MusicTagsPlugin(Plugin[MusicTagsOptions]): tag_value = self.overrides.apply_formatter(formatter=tag_formatter, entry=entry) tags_to_write[tag_name].append(tag_value) + if _is_date_field(tag_name): + try: + if len(tags_to_write[tag_name]) != 1: + raise ValueError("caught below") + + _ = _to_datetime(tags_to_write[tag_name][0]) + except Exception as exc: + raise ValidationException( + "Date-based music tags must be a single tag in the form of YYYY-MM-DD" + ) from exc + # write the actual tags if its not a dry run if not self.is_dry_run: audio_file = mediafile.MediaFile(entry.get_download_file_path()) for tag_name, tag_value in tags_to_write.items(): + # If the attribute is a date-type, set it as a datetime type + if _is_date_field(tag_name): + setattr(audio_file, tag_name, _to_datetime(tag_value[0])) # If the attribute is a multi-type, set it as the list type if _is_multi_field(tag_name): setattr(audio_file, tag_name, tag_value) - # If the attribute is a date-type, set it as a datetime type - elif _is_date_field(tag_name): - if len(tag_value) == 3: - date = datetime.date(int(tag_value[0]),int(tag_value[1]),int(tag_value[2])) - else: - date = datetime.fromisoformat(tag_value[0]) - setattr(audio_file, tag_name, date) # Otherwise, set as single value else: if len(tag_value) > 1: diff --git a/src/ytdl_sub/prebuilt_presets/music/singles.yaml b/src/ytdl_sub/prebuilt_presets/music/singles.yaml index 634fd43f..e018a1b8 100644 --- a/src/ytdl_sub/prebuilt_presets/music/singles.yaml +++ b/src/ytdl_sub/prebuilt_presets/music/singles.yaml @@ -24,6 +24,7 @@ presets: track: "{track_number}" tracktotal: "{track_total}" year: "{track_year}" + date: "{upload_date_standardized}" # multi-tags artists: - "{track_artist}"