refactored db objects
This commit is contained in:
parent
7b3f4a2b81
commit
4ecdc6d419
@ -19,9 +19,16 @@ class Reference:
|
|||||||
|
|
||||||
|
|
||||||
class DatabaseObject:
|
class DatabaseObject:
|
||||||
def __init__(self, id_: str = None, dynamic: bool = False) -> None:
|
empty: bool
|
||||||
|
|
||||||
|
def __init__(self, id_: str = None, dynamic: bool = False, empty: bool = False, **kwargs) -> None:
|
||||||
|
"""
|
||||||
|
empty means it is an placeholder.
|
||||||
|
it makes the object perform the same, it is just the same
|
||||||
|
"""
|
||||||
self.id_: str | None = id_
|
self.id_: str | None = id_
|
||||||
self.dynamic = dynamic
|
self.dynamic = dynamic
|
||||||
|
self.empty = empty
|
||||||
|
|
||||||
def get_id(self) -> str:
|
def get_id(self) -> str:
|
||||||
"""
|
"""
|
||||||
@ -29,8 +36,11 @@ class DatabaseObject:
|
|||||||
it returns a randomly generated UUID
|
it returns a randomly generated UUID
|
||||||
https://docs.python.org/3/library/uuid.html
|
https://docs.python.org/3/library/uuid.html
|
||||||
|
|
||||||
|
if the object is empty, it returns None
|
||||||
if the object is dynamic, it raises an error
|
if the object is dynamic, it raises an error
|
||||||
"""
|
"""
|
||||||
|
if self.empty:
|
||||||
|
return None
|
||||||
if self.dynamic:
|
if self.dynamic:
|
||||||
raise ValueError("Dynamic objects have no idea, because they are not in the database")
|
raise ValueError("Dynamic objects have no idea, because they are not in the database")
|
||||||
|
|
||||||
@ -63,6 +73,8 @@ class DatabaseObject:
|
|||||||
|
|
||||||
id = property(fget=get_id)
|
id = property(fget=get_id)
|
||||||
reference = property(fget=get_reference)
|
reference = property(fget=get_reference)
|
||||||
|
options = property(fget=get_options)
|
||||||
|
options_str = property(fget=get_option_string)
|
||||||
|
|
||||||
|
|
||||||
class SongAttribute:
|
class SongAttribute:
|
||||||
|
@ -114,10 +114,11 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
genre: str = None,
|
genre: str = None,
|
||||||
source_list: List[Source] = None,
|
source_list: List[Source] = None,
|
||||||
target: Target = None,
|
target: Target = None,
|
||||||
lyrics: List[Lyrics] = None,
|
lyrics_list: List[Lyrics] = None,
|
||||||
album=None,
|
album=None,
|
||||||
main_artist_list: list = None,
|
main_artist_list: list = None,
|
||||||
feature_artist_list: list = None
|
feature_artist_list: list = None,
|
||||||
|
**kwargs
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
id: is not NECESARRILY the musicbrainz id, but is DISTINCT for every song
|
id: is not NECESARRILY the musicbrainz id, but is DISTINCT for every song
|
||||||
@ -125,39 +126,36 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
target: Each Song can have exactly one target which can be either full or empty
|
target: Each Song can have exactly one target which can be either full or empty
|
||||||
lyrics: There can be multiple lyrics. Each Lyrics object can me added to multiple lyrics
|
lyrics: There can be multiple lyrics. Each Lyrics object can me added to multiple lyrics
|
||||||
"""
|
"""
|
||||||
super().__init__(id_=id_)
|
super().__init__(id_=id_, **kwargs)
|
||||||
# attributes
|
# attributes
|
||||||
# *private* attributes
|
# *private* attributes
|
||||||
self.title: str = title
|
self.title: str = title
|
||||||
self.isrc: str = isrc
|
self.isrc: str = isrc
|
||||||
self.length: int = length
|
self.length: int = length
|
||||||
self.mb_id: str | None = mb_id
|
self.mb_id: str | None = mb_id
|
||||||
self.album_name: str | None = album_name
|
self.tracksort: int = tracksort or 0
|
||||||
self.tracksort: int | None = tracksort
|
|
||||||
self.genre: str = genre
|
self.genre: str = genre
|
||||||
|
|
||||||
if source_list:
|
self.source_list = source_list or []
|
||||||
self.source_list = source_list
|
|
||||||
|
|
||||||
self.target = Target()
|
self.target = target or Target()
|
||||||
if target is not None:
|
self.lyrics_list = lyrics_list or []
|
||||||
self.target = target
|
|
||||||
self.target.add_song(self)
|
|
||||||
|
|
||||||
self.lyrics = []
|
# initialize with either a passed in album, or an empty one,
|
||||||
if lyrics is not None:
|
# so it can at least properly generate dynamic attributes
|
||||||
self.lyrics = lyrics
|
self._album = album or Album(empty=True)
|
||||||
|
|
||||||
self._album = None
|
|
||||||
self.album = album
|
self.album = album
|
||||||
|
|
||||||
self.main_artist_list = []
|
self.main_artist_collection = Collection(
|
||||||
if main_artist_list is not None:
|
data=main_artist_list or [],
|
||||||
self.main_artist_list = main_artist_list
|
map_attributes=["title"],
|
||||||
|
element_type=Artist
|
||||||
self.feature_artist_list = []
|
)
|
||||||
if feature_artist_list is not None:
|
self.feature_artist_collection = Collection(
|
||||||
self.feature_artist_list = feature_artist_list
|
data=feature_artist_list or [],
|
||||||
|
map_attributes=["title"],
|
||||||
|
element_type=Artist
|
||||||
|
)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if type(other) != type(self):
|
if type(other) != type(self):
|
||||||
@ -165,10 +163,12 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
return self.id == other.id
|
return self.id == other.id
|
||||||
|
|
||||||
def get_artist_credits(self) -> str:
|
def get_artist_credits(self) -> str:
|
||||||
feature_str = ""
|
main_artists = ", ".join([artist.name for artist in self.main_artist_collection])
|
||||||
if len(self.feature_artist_list) > 0:
|
feature_artists = ", ".join([artist.name for artist in self.feature_artist_collection])
|
||||||
feature_str = " feat. " + ", ".join([artist.name for artist in self.feature_artist_list])
|
|
||||||
return ", ".join([artist.name for artist in self.main_artist_list]) + feature_str
|
if len(feature_artists) == 0:
|
||||||
|
return main_artists
|
||||||
|
return f"{main_artists} feat. {feature_artists}"
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
artist_credit_str = ""
|
artist_credit_str = ""
|
||||||
@ -179,24 +179,14 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
return f"\"{self.title}\"{artist_credit_str}"
|
return f"\"{self.title}\"{artist_credit_str}"
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return self.__str__()
|
return f"Song(\"{self.title}\")"
|
||||||
|
|
||||||
def has_isrc(self) -> bool:
|
|
||||||
return self.isrc is not None
|
|
||||||
|
|
||||||
def get_album_id(self):
|
|
||||||
if self.album is None:
|
|
||||||
return None
|
|
||||||
return self.album.id
|
|
||||||
|
|
||||||
def get_tracksort_str(self):
|
def get_tracksort_str(self):
|
||||||
if self.tracksort is None:
|
"""
|
||||||
return None
|
if the album tracklist is empty, it sets it length to 1, this song has to be in the Album
|
||||||
|
:returns id3_tracksort: {song_position}/{album.length_of_tracklist}
|
||||||
if self.album is None:
|
"""
|
||||||
return str(self.tracksort)
|
return f"{self.tracksort}/{len(self.album.tracklist) or 1}"
|
||||||
|
|
||||||
return f"{self.tracksort}/{len(self.album.tracklist)}"
|
|
||||||
|
|
||||||
def get_metadata(self) -> MetadataAttribute.Metadata:
|
def get_metadata(self) -> MetadataAttribute.Metadata:
|
||||||
metadata = MetadataAttribute.Metadata({
|
metadata = MetadataAttribute.Metadata({
|
||||||
@ -208,36 +198,27 @@ class Song(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
})
|
})
|
||||||
|
|
||||||
metadata.merge_many([s.get_song_metadata() for s in self.source_list])
|
metadata.merge_many([s.get_song_metadata() for s in self.source_list])
|
||||||
if self.album is not None:
|
if not self.album.empty:
|
||||||
metadata.merge(self.album.metadata)
|
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.main_artist_list])
|
||||||
metadata.merge_many([a.metadata for a in self.feature_artist_list])
|
metadata.merge_many([a.metadata for a in self.feature_artist_list])
|
||||||
metadata.merge_many([l.metadata for l in self.lyrics])
|
metadata.merge_many([l.metadata for l in self.lyrics])
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def set_album(self, album):
|
|
||||||
if album is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._album = album
|
|
||||||
if self not in self._album.tracklist:
|
|
||||||
flat_copy = copy.copy(self)
|
|
||||||
flat_copy.dynamic = True
|
|
||||||
self._album.tracklist.append(flat_copy)
|
|
||||||
|
|
||||||
def get_options(self) -> list:
|
def get_options(self) -> list:
|
||||||
options = self.main_artist_list.copy()
|
options = self.main_artist_list.copy()
|
||||||
options.extend(self.feature_artist_list.copy())
|
options.extend(self.feature_artist_list.copy())
|
||||||
if self.album is not None:
|
if not self.album.empty:
|
||||||
options.append(self.album)
|
options.append(self.album)
|
||||||
options.append(self)
|
options.append(self)
|
||||||
return options
|
return options
|
||||||
|
|
||||||
def get_option_string(self) -> str:
|
def get_option_string(self) -> str:
|
||||||
return f"Song: {self.title}; Album: {self.album.title}; Artists: {self.get_artist_credits()}"
|
return f"Song({self.title}) of Album({self.album.title}) from Artists({self.get_artist_credits()})"
|
||||||
|
|
||||||
tracksort_str = property(fget=get_tracksort_str)
|
tracksort_str = property(fget=get_tracksort_str)
|
||||||
album = property(fget=lambda self: self._album, fset=set_album)
|
main_artist_list: list = property(fget=lambda self: self.main_artist_collection.copy())
|
||||||
|
feature_artist_list: list = property(fget=lambda self: self.feature_artist_collection.copy())
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -246,20 +227,6 @@ All objects dependent on Album
|
|||||||
|
|
||||||
|
|
||||||
class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
|
class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
|
||||||
"""
|
|
||||||
-------DB-FIELDS-------
|
|
||||||
title TEXT,
|
|
||||||
copyright TEXT,
|
|
||||||
album_status TEXT,
|
|
||||||
language TEXT,
|
|
||||||
year TEXT,
|
|
||||||
date TEXT,
|
|
||||||
country TEXT,
|
|
||||||
barcode TEXT,
|
|
||||||
song_id BIGINT,
|
|
||||||
is_split BOOLEAN NOT NULL DEFAULT 0
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
id_: str = None,
|
id_: str = None,
|
||||||
@ -274,11 +241,12 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
albumsort: int = None,
|
albumsort: int = None,
|
||||||
dynamic: bool = False,
|
dynamic: bool = False,
|
||||||
source_list: List[Source] = None,
|
source_list: List[Source] = None,
|
||||||
artists: list = None,
|
artist_list: list = None,
|
||||||
tracklist: List[Song] = None,
|
tracklist: List[Song] = None,
|
||||||
album_type: str = None
|
album_type: str = None,
|
||||||
|
**kwargs
|
||||||
) -> None:
|
) -> None:
|
||||||
DatabaseObject.__init__(self, id_=id_, dynamic=dynamic)
|
DatabaseObject.__init__(self, id_=id_, dynamic=dynamic, **kwargs)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
TODO
|
TODO
|
||||||
@ -290,9 +258,7 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
self.album_status: str = album_status
|
self.album_status: str = album_status
|
||||||
self.label = label
|
self.label = label
|
||||||
self.language: pycountry.Languages = language
|
self.language: pycountry.Languages = language
|
||||||
self.date: ID3Timestamp = date
|
self.date: ID3Timestamp = date or ID3Timestamp()
|
||||||
if date is None:
|
|
||||||
self.date = ID3Timestamp()
|
|
||||||
self.country: str = country
|
self.country: str = country
|
||||||
"""
|
"""
|
||||||
TODO
|
TODO
|
||||||
@ -301,6 +267,11 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
"""
|
"""
|
||||||
self.barcode: str = barcode
|
self.barcode: str = barcode
|
||||||
self.is_split: bool = is_split
|
self.is_split: bool = is_split
|
||||||
|
"""
|
||||||
|
TODO
|
||||||
|
implement a function in the Artist class,
|
||||||
|
to set albumsort with help of the release year
|
||||||
|
"""
|
||||||
self.albumsort: int | None = albumsort
|
self.albumsort: int | None = albumsort
|
||||||
|
|
||||||
|
|
||||||
@ -310,7 +281,11 @@ class Album(DatabaseObject, SourceAttribute, MetadataAttribute):
|
|||||||
element_type=Song
|
element_type=Song
|
||||||
)
|
)
|
||||||
self.source_list = source_list or []
|
self.source_list = source_list or []
|
||||||
self.artists = artists or []
|
self.artists = Collection(
|
||||||
|
data=artist_list or [],
|
||||||
|
map_attributes=["name"],
|
||||||
|
element_type=Artist
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
|
Loading…
Reference in New Issue
Block a user