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.
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
@ -222,60 +222,68 @@ Every Service models Data a bit different, and projecting a one to many relation
```python
# importing the libraries I build on
from music_kraken import objects
import pycountry
# importing the custom dataclasses
from music_kraken import (
Song,
Lyrics,
Target,
Source,
Album,
Artist,
# the custom date class
ID3Timestamp,
# the enums (I will elaborate on later)
SourcePages,
SourceTypes
)
song_object = Song(
song = objects.Song(
genre="HS Core",
title="Vein Deep in the Solution",
length=666,
isrc="US-S1Z-99-00001",
tracksort=2,
target=Target(file="song.mp3", path="~/Music"),
lyrics=[
Lyrics(text="these are some depressive lyrics", language="en"),
Lyrics(text="test", language="en")
target=[
objects.Target(file="song.mp3", path="example")
],
sources=[
Source(SourcePages.YOUTUBE, "https://youtu.be/dfnsdajlhkjhsd"),
Source(SourcePages.MUSIFY, "https://ln.topdf.de/Music-Kraken/")
lyrics_list=[
objects.Lyrics(text="these are some depressive lyrics", language="en"),
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=[
Artist(
objects.Artist(
name="I'm in a coffin",
sources=[
Source(SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/bands/I%27m_in_a_Coffin/127727")
source_list=[
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
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(
@ -41,13 +22,15 @@ song = objects.Song(
],
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="cum productions",
source_list=[
objects.Source(objects.SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/albums/I%27m_in_a_Coffin/One_Final_Action/207614")
]
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")
]
),
],
main_artist_list=[
@ -62,25 +45,18 @@ song = objects.Song(
),
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)
exit()
div()
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()
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

@ -19,7 +19,7 @@ class DatabaseObject:
https://docs.python.org/3/library/uuid.html
"""
_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)
self.id: Optional[str] = _id
@ -74,6 +74,14 @@ class DatabaseObject:
def metadata(self) -> 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):
"""
@ -91,12 +99,3 @@ class MainObject(DatabaseObject):
DatabaseObject.__init__(self, _id=_id, dynamic=dynamic, **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,
DATABASE_LOGGER as LOGGER
)
from ..utils.string_processing import unify
from ..utils.string_processing import unify
from .parents import (
DatabaseObject,
MainObject
@ -33,6 +33,7 @@ All Objects dependent
"""
CountryTyping = type(list(pycountry.countries)[0])
OPTION_STRING_DELIMITER = " | "
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.
"""
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")
def __init__(
@ -73,15 +76,10 @@ class Song(MainObject):
self.genre: str = genre
self.source_collection: SourceCollection = SourceCollection(source_list)
self.target_collection: Collection = Collection(data=target_list, element_type=Target)
self.lyrics_collection: Collection = Collection(data=lyrics_list, element_type=Lyrics)
self.album_collection: Collection = Collection(data=album_list, element_type=Album)
self.main_artist_collection = Collection(data=main_artist_list, element_type=Artist)
self.feature_artist_collection = Collection(data=feature_artist_list, element_type=Artist)
@property
@ -92,7 +90,7 @@ class Song(MainObject):
('isrc', self.isrc.strip()),
*[('url', source.url) for source in self.source_collection]
]
@property
def metadata(self) -> Metadata:
metadata = Metadata({
@ -111,11 +109,6 @@ class Song(MainObject):
return metadata
def __eq__(self, other):
if type(other) != type(self):
return False
return self.id == other.id
def get_artist_credits(self) -> str:
main_artists = ", ".join([artist.name for artist in self.main_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:
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
def tracksort_str(self) -> str:
"""
@ -143,21 +143,19 @@ class Song(MainObject):
"""
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 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.album_collection)
options.append(self)
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
@ -210,14 +208,10 @@ class Album(MainObject):
self.albumsort: Optional[int] = albumsort
self.source_collection: SourceCollection = SourceCollection(source_list)
self.song_collection: Collection = Collection(data=song_list, element_type=Song)
self.artist_collection: Collection = Collection(data=artist_list, element_type=Artist)
self.label_collection: Collection = Collection(data=label_list, element_type=Label)
@property
def indexing_values(self) -> List[Tuple[str, object]]:
return [
@ -226,7 +220,7 @@ class Album(MainObject):
('barcode', self.barcode),
*[('url', source.url) for source in self.source_collection]
]
@property
def metadata(self) -> Metadata:
return Metadata({
@ -240,6 +234,12 @@ class Album(MainObject):
def __repr__(self):
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):
"""
This updates the tracksort attributes, of the songs in
@ -272,8 +272,6 @@ class Album(MainObject):
continue
song.tracksort = i + 1
@property
def copyright(self) -> str:
if self.date is None:
@ -300,16 +298,16 @@ class Album(MainObject):
"""
return len(self.artist_collection) > 1
def get_options(self) -> list:
options = self.artist_collection.copy()
@property
def option_list(self) -> list:
options = self.artist_collection.shallow_list
options.append(self)
options.extend(self.song_collection)
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
@ -319,7 +317,7 @@ All objects dependent on Artist
class Artist(MainObject):
COLLECTION_ATTRIBUTES = ("feature_song_collection", "main_album_collection", "label_collection")
SIMPLE_ATTRIBUTES = ("name", "name", "country", "formed_in", "notes", "lyrical_themes", "general_genre")
def __init__(
self,
_id: str = None,
@ -359,13 +357,10 @@ class Artist(MainObject):
"""
self.lyrical_themes: List[str] = lyrical_themes or []
self.general_genre = general_genre
self.source_collection: SourceCollection = SourceCollection(source_list)
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.label_collection: Collection = Collection(data=label_list, element_type=Label)
@property
@ -375,7 +370,7 @@ class Artist(MainObject):
('name', self.unified_name),
*[('url', source.url) for source in self.source_collection]
]
@property
def metadata(self) -> Metadata:
metadata = Metadata({
@ -395,6 +390,11 @@ class Artist(MainObject):
def __repr__(self):
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
def country_string(self):
return self.country.alpha_3
@ -428,15 +428,13 @@ class Artist(MainObject):
song_list=self.feature_song_collection.copy()
)
def get_options(self) -> list:
@property
def option_list(self) -> list:
options = [self]
options.extend(self.main_album_collection)
options.extend(self.feature_song_collection)
return options
def get_option_string(self) -> str:
return f"Artist: {self.name}"
def get_all_songs(self) -> List[Song]:
"""
returns a list of all Songs.
@ -464,7 +462,7 @@ Label
class Label(MainObject):
COLLECTION_ATTRIBUTES = ("album_collection", "current_artist_collection")
SIMPLE_ATTRIBUTES = ("name",)
def __init__(
self,
_id: str = None,
@ -480,7 +478,7 @@ class Label(MainObject):
self.name: str = name
self.unified_name: str = unified_name or unify(self.name)
self.source_collection: SourceCollection = SourceCollection(source_list)
self.album_collection: Collection = Collection(data=album_list, element_type=Album)
self.current_artist_collection: Collection = Collection(data=current_artist_list, element_type=Artist)