doesn't throw exceptions
This commit is contained in:
parent
809ba07acc
commit
53f1254231
80
README.md
80
README.md
@ -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")
|
||||||
],
|
],
|
||||||
album=Album(
|
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",
|
title="One Final Action",
|
||||||
date=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=[
|
||||||
sources=[
|
objects.Label(name="an album label")
|
||||||
Source(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=[
|
||||||
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)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -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(
|
||||||
@ -44,7 +25,9 @@ song = objects.Song(
|
|||||||
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=[
|
||||||
|
objects.Label(name="an album label")
|
||||||
|
],
|
||||||
source_list=[
|
source_list=[
|
||||||
objects.Source(objects.SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/albums/I%27m_in_a_Coffin/One_Final_Action/207614")
|
objects.Source(objects.SourcePages.ENCYCLOPAEDIA_METALLUM, "https://www.metal-archives.com/albums/I%27m_in_a_Coffin/One_Final_Action/207614")
|
||||||
]
|
]
|
||||||
@ -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()
|
|
||||||
|
@ -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)
|
|
||||||
|
@ -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
|
||||||
@ -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 [
|
||||||
@ -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,15 +298,15 @@ 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])}"
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -361,11 +359,8 @@ class Artist(MainObject):
|
|||||||
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
|
||||||
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user