doesn't throw exceptions

This commit is contained in:
Hellow 2023-03-10 10:54:15 +01:00
parent 809ba07acc
commit 53f1254231
4 changed files with 119 additions and 138 deletions

View File

@ -209,10 +209,10 @@ Label }o--o{ Artist : LabelSong
``` ```
Looks way more managebal, doesn't it? Looks way more manageable, doesn't it?
The reason every relation here is a `n:m` *(many to many)* relation is not, that it makes sense in the aspekt of modeling reality, but to be able to put data from many Sources in the same Data Model. The reason every relation here is a `n:m` *(many to many)* relation is not, that it makes sense in the aspekt of modeling reality, but to be able to put data from many Sources in the same Data Model.
Every Service models Data a bit different, and projecting a one to many relationship to a many to many relationship without data loss is easy. The other way around it is basically impossible Every Service models Data a bit different, and projecting a one-to-many relationship to a many to many relationship without data loss is easy. The other way around it is basically impossible
## Data Objects ## Data Objects
@ -222,60 +222,68 @@ Every Service models Data a bit different, and projecting a one to many relation
```python ```python
# importing the libraries I build on # importing the libraries I build on
from music_kraken import objects
import pycountry import pycountry
# importing the custom dataclasses
from music_kraken import (
Song,
Lyrics,
Target,
Source,
Album,
Artist,
# the custom date class song = objects.Song(
ID3Timestamp,
# the enums (I will elaborate on later)
SourcePages,
SourceTypes
)
song_object = Song(
genre="HS Core", genre="HS Core",
title="Vein Deep in the Solution", title="Vein Deep in the Solution",
length=666, length=666,
isrc="US-S1Z-99-00001", isrc="US-S1Z-99-00001",
tracksort=2, tracksort=2,
target=Target(file="song.mp3", path="~/Music"), target=[
lyrics=[ objects.Target(file="song.mp3", path="example")
Lyrics(text="these are some depressive lyrics", language="en"),
Lyrics(text="test", language="en")
], ],
sources=[ lyrics_list=[
Source(SourcePages.YOUTUBE, "https://youtu.be/dfnsdajlhkjhsd"), objects.Lyrics(text="these are some depressive lyrics", language="en"),
Source(SourcePages.MUSIFY, "https://ln.topdf.de/Music-Kraken/") objects.Lyrics(text="Dies sind depressive Lyrics", language="de")
],
source_list=[
objects.Source(objects.SourcePages.YOUTUBE, "https://youtu.be/dfnsdajlhkjhsd"),
objects.Source(objects.SourcePages.MUSIFY, "https://ln.topdf.de/Music-Kraken/")
],
album_list=[
objects.Album(
title="One Final Action",
date=objects.ID3Timestamp(year=1986, month=3, day=1),
language=pycountry.languages.get(alpha_2="en"),
label_list=[
objects.Label(name="an album label")
],
source_list=[
objects.Source(objects.SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/albums/I%27m_in_a_Coffin/One_Final_Action/207614")
]
),
], ],
album=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")
]
),
main_artist_list=[ main_artist_list=[
Artist( objects.Artist(
name="I'm in a coffin", name="I'm in a coffin",
sources=[ source_list=[
Source(SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/bands/I%27m_in_a_Coffin/127727") objects.Source(
objects.SourcePages.ENCYCLOPAEDIA_METALLUM,
"https://www.metal-archives.com/bands/I%27m_in_a_Coffin/127727"
)
]
),
objects.Artist(name="some_split_artist")
],
feature_artist_list=[
objects.Artist(
name="Ruffiction",
label_list=[
objects.Label(name="Ruffiction Productions")
] ]
) )
], ],
feature_artist_list=[Artist(name="Rick Astley")],
) )
print(song.option_string)
for album in song.album_collection:
print(album.option_string)
for artist in song.main_artist_collection:
print(artist.option_string)
``` ```

View File

@ -1,25 +1,6 @@
from music_kraken import objects from music_kraken import objects
import pycountry import pycountry
import logging
logging.disable()
def div(msg: str = ""):
print("-" * 50 + msg + "-" * 50)
def print_song(song_: objects.Song):
print(str(song_.metadata))
print("----album--")
print(song_.album)
print("----src----")
print("song:")
print(song_.source_list)
print("album:")
print(song_.album.source_list)
print("\n")
song = objects.Song( song = objects.Song(
@ -41,13 +22,15 @@ song = objects.Song(
], ],
album_list=[ album_list=[
objects.Album( objects.Album(
title="One Final Action", title="One Final Action",
date=objects.ID3Timestamp(year=1986, month=3, day=1), date=objects.ID3Timestamp(year=1986, month=3, day=1),
language=pycountry.languages.get(alpha_2="en"), language=pycountry.languages.get(alpha_2="en"),
label="cum productions", label_list=[
source_list=[ objects.Label(name="an album label")
objects.Source(objects.SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/albums/I%27m_in_a_Coffin/One_Final_Action/207614") ],
] source_list=[
objects.Source(objects.SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/albums/I%27m_in_a_Coffin/One_Final_Action/207614")
]
), ),
], ],
main_artist_list=[ main_artist_list=[
@ -62,25 +45,18 @@ song = objects.Song(
), ),
objects.Artist(name="some_split_artist") objects.Artist(name="some_split_artist")
], ],
feature_artist_list=[objects.Artist(name="Ruffiction")], feature_artist_list=[
objects.Artist(
name="Ruffiction",
label_list=[
objects.Label(name="Ruffiction Productions")
]
)
],
) )
print(song) print(song.option_string)
for album in song.album_collection:
exit() print(album.option_string)
for artist in song.main_artist_collection:
div() print(artist.option_string)
song_ref = song.reference
# getting song by song ref
song_list = cache.pull_songs(song_ref=song_ref)
song_from_db = song_list[0]
print_song(song_from_db)
# try writing metadata
write_metadata(song)
# getting song by album ref
div()

View File

@ -19,7 +19,7 @@ class DatabaseObject:
https://docs.python.org/3/library/uuid.html https://docs.python.org/3/library/uuid.html
""" """
_id = str(uuid.uuid4()) _id = str(uuid.uuid4())
LOGGER.info(f"id for {type(self).__name__} isn't set. Setting to {_id}") LOGGER.debug(f"id for {type(self).__name__} isn't set. Setting to {_id}")
# The id can only be None, if the object is dynamic (self.dynamic = True) # The id can only be None, if the object is dynamic (self.dynamic = True)
self.id: Optional[str] = _id self.id: Optional[str] = _id
@ -74,6 +74,14 @@ class DatabaseObject:
def metadata(self) -> Metadata: def metadata(self) -> Metadata:
return Metadata() return Metadata()
@property
def option_list(self) -> List[Type['DatabaseObject']]:
return [self]
@property
def option_string(self) -> str:
return self.__repr__()
class MainObject(DatabaseObject): class MainObject(DatabaseObject):
""" """
@ -91,12 +99,3 @@ class MainObject(DatabaseObject):
DatabaseObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs) DatabaseObject.__init__(self, _id=_id, dynamic=dynamic, **kwargs)
self.additional_arguments: dict = kwargs self.additional_arguments: dict = kwargs
def get_options(self) -> list:
return []
def get_option_string(self) -> str:
return ""
options = property(fget=get_options)
options_str = property(fget=get_option_string)

View File

@ -11,7 +11,7 @@ from ..utils.shared import (
MUSIC_DIR, MUSIC_DIR,
DATABASE_LOGGER as LOGGER DATABASE_LOGGER as LOGGER
) )
from ..utils.string_processing import unify from ..utils.string_processing import unify
from .parents import ( from .parents import (
DatabaseObject, DatabaseObject,
MainObject MainObject
@ -33,6 +33,7 @@ All Objects dependent
""" """
CountryTyping = type(list(pycountry.countries)[0]) CountryTyping = type(list(pycountry.countries)[0])
OPTION_STRING_DELIMITER = " | "
class Song(MainObject): class Song(MainObject):
@ -41,7 +42,9 @@ class Song(MainObject):
tracksort, genre, source_list, target, lyrics_list, album, main_artist_list, and feature_artist_list. tracksort, genre, source_list, target, lyrics_list, album, main_artist_list, and feature_artist_list.
""" """
COLLECTION_ATTRIBUTES = ("lyrics_collection", "album_collection", "main_artist_collection", "feature_artist_collection", "source_collection") COLLECTION_ATTRIBUTES = (
"lyrics_collection", "album_collection", "main_artist_collection", "feature_artist_collection",
"source_collection")
SIMPLE_ATTRIBUTES = ("title", "unified_title", "isrc", "length", "tracksort", "genre") SIMPLE_ATTRIBUTES = ("title", "unified_title", "isrc", "length", "tracksort", "genre")
def __init__( def __init__(
@ -73,15 +76,10 @@ class Song(MainObject):
self.genre: str = genre self.genre: str = genre
self.source_collection: SourceCollection = SourceCollection(source_list) self.source_collection: SourceCollection = SourceCollection(source_list)
self.target_collection: Collection = Collection(data=target_list, element_type=Target) self.target_collection: Collection = Collection(data=target_list, element_type=Target)
self.lyrics_collection: Collection = Collection(data=lyrics_list, element_type=Lyrics) self.lyrics_collection: Collection = Collection(data=lyrics_list, element_type=Lyrics)
self.album_collection: Collection = Collection(data=album_list, element_type=Album) self.album_collection: Collection = Collection(data=album_list, element_type=Album)
self.main_artist_collection = Collection(data=main_artist_list, element_type=Artist) self.main_artist_collection = Collection(data=main_artist_list, element_type=Artist)
self.feature_artist_collection = Collection(data=feature_artist_list, element_type=Artist) self.feature_artist_collection = Collection(data=feature_artist_list, element_type=Artist)
@property @property
@ -92,7 +90,7 @@ class Song(MainObject):
('isrc', self.isrc.strip()), ('isrc', self.isrc.strip()),
*[('url', source.url) for source in self.source_collection] *[('url', source.url) for source in self.source_collection]
] ]
@property @property
def metadata(self) -> Metadata: def metadata(self) -> Metadata:
metadata = Metadata({ metadata = Metadata({
@ -111,11 +109,6 @@ class Song(MainObject):
return metadata return metadata
def __eq__(self, other):
if type(other) != type(self):
return False
return self.id == other.id
def get_artist_credits(self) -> str: def get_artist_credits(self) -> str:
main_artists = ", ".join([artist.name for artist in self.main_artist_collection]) main_artists = ", ".join([artist.name for artist in self.main_artist_collection])
feature_artists = ", ".join([artist.name for artist in self.feature_artist_collection]) feature_artists = ", ".join([artist.name for artist in self.feature_artist_collection])
@ -135,6 +128,13 @@ class Song(MainObject):
def __repr__(self) -> str: def __repr__(self) -> str:
return f"Song(\"{self.title}\")" return f"Song(\"{self.title}\")"
@property
def option_string(self) -> str:
return f"{self.__repr__()} " \
f"from Album({OPTION_STRING_DELIMITER.join(album.title for album in self.album_collection)}) " \
f"by Artist({OPTION_STRING_DELIMITER.join(artist.name for artist in self.main_artist_collection)}) " \
f"feat. Artist({OPTION_STRING_DELIMITER.join(artist.name for artist in self.feature_artist_collection)})"
@property @property
def tracksort_str(self) -> str: def tracksort_str(self) -> str:
""" """
@ -143,21 +143,19 @@ class Song(MainObject):
""" """
return f"{self.tracksort}/{len(self.album.tracklist) or 1}" return f"{self.tracksort}/{len(self.album.tracklist) or 1}"
def get_options(self) -> list: @property
def option_list(self) -> list:
""" """
Return a list of related objects including the song object, album object, main artist objects, and feature artist objects. Return a list of related objects including the song object, album object, main artist objects, and feature artist objects.
:return: a list of objects that are related to the Song object :return: a list of objects that are related to the Song object
""" """
options = self.main_artist_list.copy() options = self.main_artist_collection.shallow_list
options.extend(self.feature_artist_collection) options.extend(self.feature_artist_collection)
options.extend(self.album_collection) options.extend(self.album_collection)
options.append(self) options.append(self)
return options return options
def get_option_string(self) -> str:
return f"Song({self.title}) of Album({self.album.title}) from Artists({self.get_artist_credits()})"
""" """
All objects dependent on Album All objects dependent on Album
@ -210,14 +208,10 @@ class Album(MainObject):
self.albumsort: Optional[int] = albumsort self.albumsort: Optional[int] = albumsort
self.source_collection: SourceCollection = SourceCollection(source_list) self.source_collection: SourceCollection = SourceCollection(source_list)
self.song_collection: Collection = Collection(data=song_list, element_type=Song) self.song_collection: Collection = Collection(data=song_list, element_type=Song)
self.artist_collection: Collection = Collection(data=artist_list, element_type=Artist) self.artist_collection: Collection = Collection(data=artist_list, element_type=Artist)
self.label_collection: Collection = Collection(data=label_list, element_type=Label) self.label_collection: Collection = Collection(data=label_list, element_type=Label)
@property @property
def indexing_values(self) -> List[Tuple[str, object]]: def indexing_values(self) -> List[Tuple[str, object]]:
return [ return [
@ -226,7 +220,7 @@ class Album(MainObject):
('barcode', self.barcode), ('barcode', self.barcode),
*[('url', source.url) for source in self.source_collection] *[('url', source.url) for source in self.source_collection]
] ]
@property @property
def metadata(self) -> Metadata: def metadata(self) -> Metadata:
return Metadata({ return Metadata({
@ -240,6 +234,12 @@ class Album(MainObject):
def __repr__(self): def __repr__(self):
return f"Album(\"{self.title}\")" return f"Album(\"{self.title}\")"
@property
def option_string(self) -> str:
return f"{self.__repr__()} " \
f"by Artist({OPTION_STRING_DELIMITER.join([artist.name for artist in self.artist_collection])}) " \
f"under Label({OPTION_STRING_DELIMITER.join([label.name for label in self.label_collection])})"
def update_tracksort(self): def update_tracksort(self):
""" """
This updates the tracksort attributes, of the songs in This updates the tracksort attributes, of the songs in
@ -272,8 +272,6 @@ class Album(MainObject):
continue continue
song.tracksort = i + 1 song.tracksort = i + 1
@property @property
def copyright(self) -> str: def copyright(self) -> str:
if self.date is None: if self.date is None:
@ -300,16 +298,16 @@ class Album(MainObject):
""" """
return len(self.artist_collection) > 1 return len(self.artist_collection) > 1
def get_options(self) -> list: @property
options = self.artist_collection.copy() def option_list(self) -> list:
options = self.artist_collection.shallow_list
options.append(self) options.append(self)
options.extend(self.song_collection) options.extend(self.song_collection)
return options return options
def get_option_string(self) -> str:
return f"Album: {self.title}; Artists {', '.join([i.name for i in self.artist_collection])}"
""" """
All objects dependent on Artist All objects dependent on Artist
@ -319,7 +317,7 @@ All objects dependent on Artist
class Artist(MainObject): class Artist(MainObject):
COLLECTION_ATTRIBUTES = ("feature_song_collection", "main_album_collection", "label_collection") COLLECTION_ATTRIBUTES = ("feature_song_collection", "main_album_collection", "label_collection")
SIMPLE_ATTRIBUTES = ("name", "name", "country", "formed_in", "notes", "lyrical_themes", "general_genre") SIMPLE_ATTRIBUTES = ("name", "name", "country", "formed_in", "notes", "lyrical_themes", "general_genre")
def __init__( def __init__(
self, self,
_id: str = None, _id: str = None,
@ -359,13 +357,10 @@ class Artist(MainObject):
""" """
self.lyrical_themes: List[str] = lyrical_themes or [] self.lyrical_themes: List[str] = lyrical_themes or []
self.general_genre = general_genre self.general_genre = general_genre
self.source_collection: SourceCollection = SourceCollection(source_list) self.source_collection: SourceCollection = SourceCollection(source_list)
self.feature_song_collection: Collection = Collection(data=feature_song_list, element_type=Song) self.feature_song_collection: Collection = Collection(data=feature_song_list, element_type=Song)
self.main_album_collection: Collection = Collection(data=main_album_list, element_type=Album) self.main_album_collection: Collection = Collection(data=main_album_list, element_type=Album)
self.label_collection: Collection = Collection(data=label_list, element_type=Label) self.label_collection: Collection = Collection(data=label_list, element_type=Label)
@property @property
@ -375,7 +370,7 @@ class Artist(MainObject):
('name', self.unified_name), ('name', self.unified_name),
*[('url', source.url) for source in self.source_collection] *[('url', source.url) for source in self.source_collection]
] ]
@property @property
def metadata(self) -> Metadata: def metadata(self) -> Metadata:
metadata = Metadata({ metadata = Metadata({
@ -395,6 +390,11 @@ class Artist(MainObject):
def __repr__(self): def __repr__(self):
return f"Artist(\"{self.name}\")" return f"Artist(\"{self.name}\")"
@property
def option_string(self) -> str:
return f"{self.__repr__()} " \
f"under Label({OPTION_STRING_DELIMITER.join([label.name for label in self.label_collection])})"
@property @property
def country_string(self): def country_string(self):
return self.country.alpha_3 return self.country.alpha_3
@ -428,15 +428,13 @@ class Artist(MainObject):
song_list=self.feature_song_collection.copy() song_list=self.feature_song_collection.copy()
) )
def get_options(self) -> list: @property
def option_list(self) -> list:
options = [self] options = [self]
options.extend(self.main_album_collection) options.extend(self.main_album_collection)
options.extend(self.feature_song_collection) options.extend(self.feature_song_collection)
return options return options
def get_option_string(self) -> str:
return f"Artist: {self.name}"
def get_all_songs(self) -> List[Song]: def get_all_songs(self) -> List[Song]:
""" """
returns a list of all Songs. returns a list of all Songs.
@ -464,7 +462,7 @@ Label
class Label(MainObject): class Label(MainObject):
COLLECTION_ATTRIBUTES = ("album_collection", "current_artist_collection") COLLECTION_ATTRIBUTES = ("album_collection", "current_artist_collection")
SIMPLE_ATTRIBUTES = ("name",) SIMPLE_ATTRIBUTES = ("name",)
def __init__( def __init__(
self, self,
_id: str = None, _id: str = None,
@ -480,7 +478,7 @@ class Label(MainObject):
self.name: str = name self.name: str = name
self.unified_name: str = unified_name or unify(self.name) self.unified_name: str = unified_name or unify(self.name)
self.source_collection: SourceCollection = SourceCollection(source_list) self.source_collection: SourceCollection = SourceCollection(source_list)
self.album_collection: Collection = Collection(data=album_list, element_type=Album) self.album_collection: Collection = Collection(data=album_list, element_type=Album)
self.current_artist_collection: Collection = Collection(data=current_artist_list, element_type=Artist) self.current_artist_collection: Collection = Collection(data=current_artist_list, element_type=Artist)