diff --git a/src/goof.py b/src/goof.py index 49de36c..d392223 100644 --- a/src/goof.py +++ b/src/goof.py @@ -5,7 +5,8 @@ from music_kraken import ( Target, Source, Album, - Artist + Artist, + ID3Timestamp ) from music_kraken.tagging import ( @@ -16,7 +17,6 @@ from music_kraken.tagging import ( import music_kraken.database.new_database as db -import datetime import pycountry @@ -43,7 +43,7 @@ feature_artist = Artist( album_input = Album( title="One Final Action", - date=datetime.date(1986, 3, 1), + date=ID3Timestamp(year=1986, month=3, day=1), language=pycountry.languages.get(alpha_2="en"), label="cum productions" ) diff --git a/src/music_kraken/__init__.py b/src/music_kraken/__init__.py index 735db13..7094e79 100644 --- a/src/music_kraken/__init__.py +++ b/src/music_kraken/__init__.py @@ -44,6 +44,7 @@ Source = database.Source Target = database.Target Lyrics = database.Lyrics Album = database.Album +ID3Timestamp = database.ID3Timestamp MetadataSearch = metadata.MetadataSearch MetadataDownload = metadata.MetadataDownload diff --git a/src/music_kraken/database/__init__.py b/src/music_kraken/database/__init__.py index 8dd8fd4..07410fe 100644 --- a/src/music_kraken/database/__init__.py +++ b/src/music_kraken/database/__init__.py @@ -3,6 +3,7 @@ from . import ( objects ) +ID3Timestamp = objects.ID3Timestamp Song = objects.Song Source = objects.Source Target = objects.Target diff --git a/src/music_kraken/database/objects/__init__.py b/src/music_kraken/database/objects/__init__.py index 0f77c78..a14ddb3 100644 --- a/src/music_kraken/database/objects/__init__.py +++ b/src/music_kraken/database/objects/__init__.py @@ -5,6 +5,7 @@ from . import ( ) ID3_MAPPING = metadata.Mapping +ID3Timestamp = metadata.ID3Timestamp Song = song.Song Artist = song.Artist diff --git a/src/music_kraken/database/objects/metadata.py b/src/music_kraken/database/objects/metadata.py index 859f096..b764be2 100644 --- a/src/music_kraken/database/objects/metadata.py +++ b/src/music_kraken/database/objects/metadata.py @@ -1,5 +1,7 @@ from enum import Enum from typing import List, Dict, Tuple + +import dateutil.tz from mutagen import id3 import datetime @@ -98,7 +100,7 @@ class Mapping(Enum): return cls.get_url_instance(key, value) -class ID3Timestamp(datetime.datetime): +class ID3Timestamp(): def __init__( self, year: int = None, @@ -109,7 +111,6 @@ class ID3Timestamp(datetime.datetime): second: int = None, microsecond=0, tzinfo=None, - *, fold=0 ): self.has_year = year is not None @@ -126,7 +127,10 @@ class ID3Timestamp(datetime.datetime): month = 1 if not self.has_day: day = 1 - super().__init__( + + # https://stackoverflow.com/questions/399022/why-cant-i-subclass-datetime-date + super().__new__( + cls=type(self), year=year, month=month, day=day, @@ -188,15 +192,8 @@ class Metadata: Shall only be read or edited via the Song object. call it like a dict to read/write values """ - class FrameValue: - def __init__(self, values: list, modified_by: str) -> None: - """ - Parameters: - values (list): the values. - """ - pass - def __init__(self, data: dict = {}) -> None: + def __init__(self) -> None: # this is pretty self-explanatory # the key is a 4 letter key from the id3 standards like TITL @@ -251,6 +248,16 @@ class Metadata: list_data = self.id3_attributes[key] + # convert for example the time objects to timestamps + for i, element in enumerate(list_data): + # for performance’s sake I don't do other checks if it is already the right type + if type(element) == str: + continue + + if type(element) == ID3Timestamp: + list_data[i] = element.timestamp + continue + """ Version 2.4 of the specification prescribes that all text fields (the fields that start with a T, except for TXXX) can contain multiple values separated by a null character. Thus if above conditions are met, I concatenate the list, @@ -265,6 +272,9 @@ class Metadata: return Mapping.get_mutagen_instance(Mapping(key), self.get_id3_value(key)) def __iter__(self): + # set the tagging timestamp to the current time + self.__setitem__(Mapping.TAGGING_TIME.value, [ID3Timestamp.now()]) + for key in self.id3_attributes: yield key, self.get_mutagen_object(key) diff --git a/src/music_kraken/database/objects/song.py b/src/music_kraken/database/objects/song.py index bb278f9..579a98c 100644 --- a/src/music_kraken/database/objects/song.py +++ b/src/music_kraken/database/objects/song.py @@ -5,7 +5,8 @@ import pycountry from .metadata import ( Mapping as ID3_MAPPING, - Metadata + Metadata, + ID3Timestamp ) from ...utils.shared import ( MUSIC_DIR, @@ -282,7 +283,7 @@ class Album(DatabaseObject, ID3Metadata): label: str = None, album_status: str = None, language: pycountry.Languages = None, - date: datetime.date = None, + date: ID3Timestamp = None, country: str = None, barcode: str = None, is_split: bool = False, @@ -294,11 +295,12 @@ class Album(DatabaseObject, ID3Metadata): self.album_status: str = album_status self.label = label self.language: pycountry.Languages = language - self.date: datetime.date = date + self.date: ID3Timestamp = date self.country: str = country """ TODO find out the id3 tag for barcode and implement it + maybee look at how mutagen does it with easy_id3 """ self.barcode: str = barcode self.is_split: bool = is_split @@ -335,7 +337,8 @@ class Album(DatabaseObject, ID3Metadata): ID3_MAPPING.ALBUM: [self.title], ID3_MAPPING.COPYRIGHT: [self.copyright], ID3_MAPPING.LANGUAGE: [self.iso_639_2_language], - ID3_MAPPING.ALBUM_ARTIST: [a.name for a in self.artists] + ID3_MAPPING.ALBUM_ARTIST: [a.name for a in self.artists], + ID3_MAPPING.DATE: [self.date.timestamp] } def get_copyright(self) -> str: diff --git a/src/test.db b/src/test.db index 34facad..a7d8a2c 100644 Binary files a/src/test.db and b/src/test.db differ