docs, type-checking

This commit is contained in:
Jesse Bannon 2024-02-27 09:18:57 -08:00
parent 93c7d1a53d
commit 72c8f6ea28
3 changed files with 31 additions and 8 deletions

View file

@ -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 a full list of tags for various file types in MediaFile's
`source code <https://github.com/beetbox/mediafile/blob/v0.9.0/mediafile.py#L1770>`_. `source code <https://github.com/beetbox/mediafile/blob/v0.9.0/mediafile.py#L1770>`_.
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: :Usage:
.. code-block:: yaml .. code-block:: yaml
@ -418,6 +421,7 @@ a full list of tags for various file types in MediaFile's
albumartists: albumartists:
- "{artist}" - "{artist}"
- "ytdl-sub" - "ytdl-sub"
date: "{upload_date_standardized}"
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------

View file

@ -1,15 +1,17 @@
from collections import defaultdict from collections import defaultdict
from datetime import datetime
from typing import Any
from typing import Dict from typing import Dict
from typing import List from typing import List
import mediafile import mediafile
import datetime
from ytdl_sub.config.plugin.plugin import Plugin from ytdl_sub.config.plugin.plugin import Plugin
from ytdl_sub.config.validators.options import OptionsDictValidator from ytdl_sub.config.validators.options import OptionsDictValidator
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.entries.script.variable_definitions import VARIABLES from ytdl_sub.entries.script.variable_definitions import VARIABLES
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions 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.file_handler import FileMetadata
from ytdl_sub.utils.logger import Logger from ytdl_sub.utils.logger import Logger
from ytdl_sub.validators.audo_codec_validator import AUDIO_CODEC_EXTS 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", "mb_albumartistids",
} }
def _is_date_field(tag_name: str) -> bool: def _is_date_field(tag_name: str) -> bool:
return tag_name in { return tag_name in {
"date", "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): class MusicTagsOptions(OptionsDictValidator):
""" """
Adds tags to every download audio file using 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 a full list of tags for various file types in MediaFile's
`source code <https://github.com/beetbox/mediafile/blob/v0.9.0/mediafile.py#L1770>`_. `source code <https://github.com/beetbox/mediafile/blob/v0.9.0/mediafile.py#L1770>`_.
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: :Usage:
.. code-block:: yaml .. code-block:: yaml
@ -69,6 +79,7 @@ class MusicTagsOptions(OptionsDictValidator):
albumartists: albumartists:
- "{artist}" - "{artist}"
- "ytdl-sub" - "ytdl-sub"
date: "{upload_date_standardized}"
""" """
_optional_keys = set(list(mediafile.MediaFile.sorted_fields())) _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) tag_value = self.overrides.apply_formatter(formatter=tag_formatter, entry=entry)
tags_to_write[tag_name].append(tag_value) 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 # write the actual tags if its not a dry run
if not self.is_dry_run: if not self.is_dry_run:
audio_file = mediafile.MediaFile(entry.get_download_file_path()) audio_file = mediafile.MediaFile(entry.get_download_file_path())
for tag_name, tag_value in tags_to_write.items(): 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 the attribute is a multi-type, set it as the list type
if _is_multi_field(tag_name): if _is_multi_field(tag_name):
setattr(audio_file, tag_name, tag_value) 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 # Otherwise, set as single value
else: else:
if len(tag_value) > 1: if len(tag_value) > 1:

View file

@ -24,6 +24,7 @@ presets:
track: "{track_number}" track: "{track_number}"
tracktotal: "{track_total}" tracktotal: "{track_total}"
year: "{track_year}" year: "{track_year}"
date: "{upload_date_standardized}"
# multi-tags # multi-tags
artists: artists:
- "{track_artist}" - "{track_artist}"