diff --git a/src/create_custom_objects.py b/src/create_custom_objects.py index 35fa00f..1a280d3 100644 --- a/src/create_custom_objects.py +++ b/src/create_custom_objects.py @@ -29,39 +29,21 @@ def div(msg: str = ""): cache = music_kraken.database.new_database.Database("test.db") cache.reset() +def print_song(song_: Song): -main_artist = Artist( - name="I'm in a coffin", - sources=[ - Source(SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/bands/I%27m_in_a_Coffin/127727") - ] -) -artist_ref = main_artist.reference + print("tracksort", song_.tracksort, sep=": ") + # print("ID3", song_.metadata) + print(str(song_.metadata)) + print("----src----") + print("song:") + print(song_.source_list) + print("album:") + print(song_.album.source_list) + print("\n") -split_artist = Artist( - name="split" -) -feature_artist = Artist( - name="Ghost" -) - -album_input = Album( - title="One Final Action", - date=ID3Timestamp(year=1986, month=3, day=1), - language=pycountry.languages.get(alpha_2="en"), - label="cum productions", - sources=[ - Source(SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/albums/I%27m_in_a_Coffin/One_Final_Action/207614") - ] -) -album_input.artists = [ - main_artist, - split_artist -] - -song_input = Song( +song = Song( genre="HS Core", title="Vein Deep in the Solution", length=666, @@ -70,50 +52,48 @@ song_input = Song( target=Target(file="song.mp3", path="~/Music"), lyrics=[ Lyrics(text="these are some depressive lyrics", language="en"), - Lyrics(text="test", language="en") + Lyrics(text="Dies sind depressive Lyrics", language="de") ], - sources=[ + source_list=[ Source(SourcePages.YOUTUBE, "https://youtu.be/dfnsdajlhkjhsd"), Source(SourcePages.MUSIFY, "https://ln.topdf.de/Music-Kraken/") ], - album=album_input, - main_artist_list=[main_artist], - feature_artist_list=[feature_artist], + album=Album( + title="One Final Action", + date=ID3Timestamp(year=1986, month=3, day=1), + language=pycountry.languages.get(alpha_2="en"), + label="cum productions", + source_list=[ + Source(SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/albums/I%27m_in_a_Coffin/One_Final_Action/207614") + ] + ), + main_artist_list=[ + Artist( + name="I'm in a coffin", + source_list=[ + Source(SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/bands/I%27m_in_a_Coffin/127727") + ] + ), + Artist(name="some_split_artist") + ], + feature_artist_list=[Artist(name="Ruffiction")], ) -other_song = Song( - title="this is just another song", - main_artist_list=[feature_artist], - feature_artist_list=[main_artist] -) +print_song(song) -print(song_input) +exit() -additional_song = Song( - title="A fcking Song", - album=album_input -) +song_ref = song.reference -song_ref = song_input.reference -print(song_ref) +cache.push([song]) -lyrics = Lyrics(text="these are some Lyrics that don't belong to any Song", language="en") -cache.push([album_input, song_input, lyrics, additional_song, other_song]) # getting song by song ref div() -song_output_list = cache.pull_songs(song_ref=song_ref) -print(len(song_output_list), song_output_list, song_output_list[0].album, sep=" | ") -song = song_output_list[0] -print("tracksort", song_output_list[0].tracksort, sep=": ") -print("ID3", dict(song.metadata)) -print(str(song_output_list[0].metadata)) -print("--src--") -for source in song.sources: - print(source) +song_list = cache.pull_songs(song_ref=song_ref) +song_from_db = song_list[0] -print("album", song.album.sources) # try writing metadata write_metadata(song) diff --git a/src/music_kraken/database/__init__.py b/src/music_kraken/database/__init__.py index 067bb79..276edb1 100644 --- a/src/music_kraken/database/__init__.py +++ b/src/music_kraken/database/__init__.py @@ -11,7 +11,6 @@ SourcePages = objects.SourcePages Song = objects.Song Source = objects.Source Target = objects.Target -Metadata = objects.Metadata Lyrics = objects.Lyrics Album = objects.Album diff --git a/src/music_kraken/database/new_database.py b/src/music_kraken/database/new_database.py index 6d12a95..39e0054 100644 --- a/src/music_kraken/database/new_database.py +++ b/src/music_kraken/database/new_database.py @@ -11,7 +11,6 @@ from .objects.source import Source from .objects import ( Song, Lyrics, - Metadata, Target, Artist, Album, @@ -187,7 +186,7 @@ class Database: self.connection.commit() # add sources - for source in song.sources: + for source in song.source_list: source.add_song(song) source.type_enum = SourceTypes.SONG self.push_source(source=source) diff --git a/src/music_kraken/database/objects/__init__.py b/src/music_kraken/database/objects/__init__.py index 2fdc545..a33e3e9 100644 --- a/src/music_kraken/database/objects/__init__.py +++ b/src/music_kraken/database/objects/__init__.py @@ -7,7 +7,7 @@ from . import ( MusicObject = parents.DatabaseObject -ID3_MAPPING = metadata.Mapping +ID3Mapping = metadata.Mapping ID3Timestamp = metadata.ID3Timestamp SourceTypes = source.SourceTypes @@ -17,7 +17,6 @@ Song = song.Song Artist = song.Artist Source = source.Source Target = song.Target -Metadata = song.Metadata Lyrics = song.Lyrics Album = song.Album diff --git a/src/music_kraken/database/objects/metadata.py b/src/music_kraken/database/objects/metadata.py index 04b2d73..caba7ad 100644 --- a/src/music_kraken/database/objects/metadata.py +++ b/src/music_kraken/database/objects/metadata.py @@ -259,10 +259,11 @@ class MetadataAttribute: # the key is an enum from Mapping # the value is a list with each value # the mutagen object for each frame will be generated dynamically - id3_dict: Dict[any, list] = dict() + id3_dict: Dict[any, list] def __init__(self, id3_dict: Dict[any, list] = None) -> None: + self.id3_dict = dict() if id3_dict is not None: self.add_metadata_dict(id3_dict) @@ -284,7 +285,7 @@ class MetadataAttribute: self.id3_dict[frame] = new_val return - self.id3_attributes[frame].extend(new_val) + self.id3_dict[frame].extend(new_val) def __getitem__(self, key): if key not in self.id3_dict: @@ -298,23 +299,28 @@ class MetadataAttribute: def add_metadata_dict(self, metadata_dict: dict, override_existing: bool = True): for field_enum, value in metadata_dict.items(): - self.__setitem__(field_enum.value, value, override_existing=override_existing) + self.__setitem__(field_enum, value, override_existing=override_existing) def merge(self, other, override_existing: bool = False): """ adds the values of another metadata obj to this one + + other is a value of the type MetadataAttribute.Metadata """ + self.add_metadata_dict(other.id3_dict, override_existing=override_existing) def merge_many(self, many_other): """ adds the values of many other metadata objects to this one """ + for other in many_other: self.merge(other) + def get_id3_value(self, field): - if field not in self.id3_attributes: + if field not in self.id3_dict: return None list_data = self.id3_dict[field] @@ -335,7 +341,7 @@ class MetadataAttribute: else I take the first element """ if field.value[0].upper() == "T" and field.value.upper() != "TXXX": - return self.null_byte.join(list_data) + return self.NULL_BYTE.join(list_data) return list_data[0] @@ -344,7 +350,7 @@ class MetadataAttribute: def __str__(self) -> str: rows = [] - for key, value in self.id3_attributes.items(): + for key, value in self.id3_dict.items(): rows.append(f"{key} - {str(value)}") return "\n".join(rows) @@ -355,15 +361,15 @@ class MetadataAttribute: to directly tagg a file with id3 container. """ # set the tagging timestamp to the current time - self.__setitem__(Mapping.TAGGING_TIME.value, [ID3Timestamp.now()]) + self.__setitem__(Mapping.TAGGING_TIME, [ID3Timestamp.now()]) - for field in self.id3_attributes: + for field in self.id3_dict: yield self.get_mutagen_object(field) def get_metadata(self) -> Metadata: """ this is intendet to be overwritten by the child class """ - return self.Metadata() + return MetadataAttribute.Metadata() - metadata = property(fget=get_metadata) + metadata = property(fget=lambda self: self.get_metadata()) diff --git a/src/music_kraken/database/objects/song.py b/src/music_kraken/database/objects/song.py index 154d0a1..bba7241 100644 --- a/src/music_kraken/database/objects/song.py +++ b/src/music_kraken/database/objects/song.py @@ -5,8 +5,8 @@ import pycountry from .metadata import ( Mapping as ID3_MAPPING, - Metadata, - ID3Timestamp + ID3Timestamp, + MetadataAttribute ) from ...utils.shared import ( MUSIC_DIR, @@ -80,7 +80,7 @@ class Target(DatabaseObject, SongAttribute): exists_on_disc = property(fget=get_exists_on_disc) -class Lyrics(DatabaseObject, SongAttribute, SourceAttribute): +class Lyrics(DatabaseObject, SongAttribute, SourceAttribute, MetadataAttribute): def __init__( self, text: str, @@ -96,8 +96,11 @@ class Lyrics(DatabaseObject, SongAttribute, SourceAttribute): if source_list is not None: self.source_list = source_list + def get_metadata(self) -> MetadataAttribute.Metadata: + return super().get_metadata() -class Song(DatabaseObject, ID3Metadata, SourceAttribute): + +class Song(DatabaseObject, SourceAttribute, MetadataAttribute): def __init__( self, id_: str = None, @@ -186,26 +189,23 @@ class Song(DatabaseObject, ID3Metadata, SourceAttribute): return None return self.album.id - def get_id3_dict(self) -> dict: - return { + def get_metadata(self) -> MetadataAttribute.Metadata: + metadata = MetadataAttribute.Metadata({ ID3_MAPPING.TITLE: [self.title], ID3_MAPPING.ISRC: [self.isrc], ID3_MAPPING.LENGTH: [str(self.length)], ID3_MAPPING.GENRE: [self.genre] - } - - def get_metadata(self) -> Metadata: - metadata = Metadata(self.get_id3_dict()) + }) - metadata.add_many_metadata_dict([source.get_id3_dict() for source in self.source_list]) + metadata.merge_many([s.get_song_metadata() for s in self.source_list]) if self.album is not None: - metadata.add_metadata_dict(self.album.get_id3_dict()) - metadata.add_many_metadata_dict([artist.get_id3_dict() for artist in self.main_artist_list]) - metadata.add_many_metadata_dict([artist.get_id3_dict() for artist in self.feature_artist_list]) - + metadata.merge(self.album.metadata) + metadata.merge_many([a.metadata for a in self.main_artist_list]) + metadata.merge_many([a.metadata for a in self.feature_artist_list]) + metadata.merge_many([l.metadata for l in self.lyrics]) return metadata + - metadata = property(fget=get_metadata) """ @@ -213,7 +213,7 @@ All objects dependent on Album """ -class Album(DatabaseObject, ID3Metadata, SourceAttribute): +class Album(DatabaseObject, SourceAttribute, MetadataAttribute): """ -------DB-FIELDS------- title TEXT, @@ -292,14 +292,14 @@ class Album(DatabaseObject, ID3Metadata, SourceAttribute): song.tracksort = len(self.tracklist) self.tracklist.append(song) - def get_id3_dict(self) -> dict: - return { + def get_metadata(self) -> MetadataAttribute.Metadata: + return MetadataAttribute.Metadata({ 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.DATE: [self.date.timestamp] - } + }) def get_copyright(self) -> str: if self.date.year == 1 or self.label is None: @@ -323,7 +323,7 @@ All objects dependent on Artist """ -class Artist(DatabaseObject, ID3Metadata, SourceAttribute): +class Artist(DatabaseObject, SourceAttribute, MetadataAttribute): """ main_songs feature_song @@ -403,19 +403,17 @@ class Artist(DatabaseObject, ID3Metadata, SourceAttribute): return flat_copy_discography - def get_id3_dict(self) -> dict: + def get_metadata(self) -> MetadataAttribute.Metadata: """ TODO refactor :return: """ - id3_dict = { + metadata = MetadataAttribute.Metadata({ ID3_MAPPING.ARTIST: [self.name] - } - if len(self.sources) <= 0: - return id3_dict - id3_dict.update(self.sources[0].get_id3_dict()) + }) + metadata.merge_many([s.get_artist_metadata() for s in self.source_list]) - return id3_dict + return metadata discography: List[Album] = property(fget=get_discography) diff --git a/src/music_kraken/database/objects/source.py b/src/music_kraken/database/objects/source.py index b0a3309..717a4f8 100644 --- a/src/music_kraken/database/objects/source.py +++ b/src/music_kraken/database/objects/source.py @@ -1,7 +1,7 @@ from enum import Enum from typing import List, Dict -from .metadata import Mapping +from .metadata import Mapping, MetadataAttribute from .parents import ( DatabaseObject, SongAttribute, @@ -35,7 +35,7 @@ class SourcePages(Enum): return homepage_map[attribute] -class Source(DatabaseObject, SongAttribute, ID3Metadata): +class Source(DatabaseObject, SongAttribute, MetadataAttribute): """ create somehow like that ```python @@ -53,23 +53,32 @@ class Source(DatabaseObject, SongAttribute, ID3Metadata): self.url = url - def get_id3_dict(self) -> dict: + def get_song_metadata(self) -> MetadataAttribute.Metadata: + return MetadataAttribute.Metadata({ + Mapping.FILE_WEBPAGE_URL: [self.url], + Mapping.SOURCE_WEBPAGE_URL: [self.homepage] + }) + + def get_artist_metadata(self) -> MetadataAttribute.Metadata: + return MetadataAttribute.Metadata({ + Mapping.ARTIST_WEBPAGE_URL: [self.url] + }) + + def get_metadata(self) -> MetadataAttribute.Metadata: if self.type_enum == SourceTypes.SONG: - return { - Mapping.FILE_WEBPAGE_URL: [self.url], - Mapping.SOURCE_WEBPAGE_URL: [self.homepage] - } + return self.get_song_metadata() if self.type_enum == SourceTypes.ARTIST: - return { - Mapping.ARTIST_WEBPAGE_URL: [self.url] - } + return self.get_artist_metadata() - return {} + return super().get_metadata() def __str__(self): return f"{self.page_enum}: {self.url}" + def __repr__(self) -> str: + return f"Src({self.page_enum.value}: {self.url})" + page_str = property(fget=lambda self: self.page_enum.value) type_str = property(fget=lambda self: self.type_enum.value) homepage = property(fget=lambda self: SourcePages.get_homepage(self.page_enum)) @@ -80,7 +89,7 @@ class SourceAttribute: This is a class that is meant to be inherited from. it adds the source_list attribute to a class """ - _source_dict: Dict[any: List[Source]] = {page_enum: list() for page_enum in SourcePages} + _source_dict: Dict[object, List[Source]] = {page_enum: list() for page_enum in SourcePages} def add_source(self, source: Source): """ @@ -99,7 +108,7 @@ class SourceAttribute: """ gets all sources """ - return [item for _, item in self._source_dict.items()] + return [item for _, page_list in self._source_dict.items() for item in page_list] def set_source_list(self, source_list: List[Source]): self._source_dict = {page_enum: list() for page_enum in SourcePages} @@ -107,7 +116,7 @@ class SourceAttribute: for source in source_list: self.add_source(source) - def get_source_dict(self) -> Dict[any: List[Source]]: + def get_source_dict(self) -> Dict[object, List[Source]]: """ gets a dictionary of all Sources, where the key is a page enum, @@ -116,4 +125,4 @@ class SourceAttribute: return self._source_dict source_list: List[Source] = property(fget=get_source_list, fset=set_source_list) - source_dict: Dict[any: List[Source]] = property(fget=get_source_dict) + source_dict: Dict[object, List[Source]] = property(fget=get_source_dict) diff --git a/test.db b/test.db index 6398dff..1a13b04 100644 Binary files a/test.db and b/test.db differ