polished the song and db oject

This commit is contained in:
Hellow 2022-12-09 18:24:58 +01:00
parent eb42920488
commit 9d43dfd129
5 changed files with 88 additions and 28 deletions

View File

@ -9,6 +9,9 @@ from music_kraken import (
import music_kraken.database.new_database as db
def div():
print("-"*100)
cache = music_kraken.database.new_database.Database("test.db")
cache.reset()
@ -21,6 +24,7 @@ song_input = Song(
title="Vein Deep in the Solution",
album_name=album_input.title,
length=666,
tracksort=2,
target=Target(file="~/Music/genre/artist/album/song.mp3", path="~/Music/genre/artist/album"),
metadata={
"album": "One Final Action"
@ -49,18 +53,28 @@ lyrics = Lyrics(text="these are some Lyrics that don't belong to any Song", lang
cache.push([album_input, song_input, lyrics, additional_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)
# song_output = song_output_list[0]
# print(song_output)
# print("album id", song_output.album_ref)
print(len(song_output_list), song_output_list, song_output_list[0].album, sep=" | ")
print("tracksort", song_output_list[0].tracksort, sep=": ")
# getting song by album ref
div()
song_output_list = cache.pull_songs(album_ref=album_input.reference)
print(len(song_output_list), song_output_list)
for song in song_output_list:
print(song, song.album)
# getting album
div()
album_output_list = cache.pull_albums(album_ref=album_input.reference)
album_output = album_output_list[0]
print(album_output)
print(album_output.tracklist)
for track in album_output.tracklist:
print(track.tracksort, track)
# getting album by song
div()
album_output_list = cache.pull_albums(song_ref=song_ref)
print(album_output_list)
print("len of album ->", len(album_output_list[0]), album_output_list[0], sep=" | ")

View File

@ -22,7 +22,7 @@ logger = logging.getLogger("database")
# use complicated query builder
SONG_QUERY = """
SELECT
Song.id AS song_id, Song.name AS title, Song.isrc AS isrc, Song.length AS length, Song.album_id,
Song.id AS song_id, Song.name AS title, Song.isrc AS isrc, Song.length AS length, Song.album_id, Song.tracksort,
Target.id AS target_id, Target.file AS file, Target.path AS path
FROM Song
LEFT JOIN Target ON Song.id=Target.song_id
@ -38,11 +38,17 @@ SELECT id, text, language, song_id
FROM Lyrics
WHERE {where};
"""
ALBUM_QUERY = """
ALBUM_QUERY_UNJOINED = """
SELECT Album.id AS album_id, title, copyright, album_status, language, year, date, country, barcode
FROM Album
WHERE {where};
"""
ALBUM_QUERY_JOINED = """
SELECT a.id AS album_id, a.title, a.copyright, a.album_status, a.language, a.year, a.date, a.country, a.barcode
FROM Song
INNER JOIN Album a ON Song.album_id=a.id
WHERE {where};
"""
class Database:
@ -147,9 +153,10 @@ class Database:
song.title,
song.isrc,
song.length,
song.get_album_id()
song.get_album_id(),
song.tracksort
)
query = f"INSERT OR REPLACE INTO {table} (id, name, isrc, length, album_id) VALUES (?, ?, ?, ?, ?);"
query = f"INSERT OR REPLACE INTO {table} (id, name, isrc, length, album_id, tracksort) VALUES (?, ?, ?, ?, ?, ?);"
self.cursor.execute(query, values)
self.connection.commit()
@ -268,7 +275,9 @@ class Database:
url=source_row['url']
) for source_row in source_rows]
def get_song_from_row(self, song_result, exclude_relations: set = set()) -> Song:
def get_song_from_row(self, song_result, exclude_relations: set = None) -> Song:
if exclude_relations is None:
exclude_relations = set()
new_exclude_relations: set = set(exclude_relations)
new_exclude_relations.add(Song)
@ -279,6 +288,7 @@ class Database:
title=song_result['title'],
isrc=song_result['isrc'],
length=song_result['length'],
tracksort=song_result['tracksort'],
target=Target(
id_=song_result['target_id'],
file=song_result['file'],
@ -290,21 +300,24 @@ class Database:
)
if Album not in exclude_relations and song_result['album_id'] is not None:
album_obj = self.pull_albums(album_ref=Reference(song_result['album_id']), exclude_relations=new_exclude_relations)
album_obj = self.pull_albums(album_ref=Reference(song_result['album_id']),
exclude_relations=new_exclude_relations)
if len(album_obj) > 0:
song_obj.album = album_obj[0]
return song_obj
def pull_songs(self, song_ref: Reference = None, album_ref: Reference = None, exclude_relations: set = set()) -> List[Song]:
def pull_songs(self, song_ref: Reference = None, album_ref: Reference = None, exclude_relations: set = set()) -> \
List[Song]:
"""
This function is used to get one song (including its children like Sources etc)
from one song id (a reference object)
:param exclude_relations:
By default all relations are pulled by this funktion. If the class object of for
example the Artists is in the set it won't get fetched.
This is done to prevent an infinite recursion.
:param song_ref:
:param album_ref:
:param exclude_independent_relations:
This excludes all relations from being fetched like for example the Album of the Song.
This is necessary when adding the Song as subclass as e.g. an Album (as tracklist or whatever).
:return requested_song:
"""
@ -324,9 +337,10 @@ class Database:
exclude_relations=exclude_relations
) for song_result in song_rows]
def get_album_from_row(self, album_result, exclude_relations: set = set()) -> Album:
def get_album_from_row(self, album_result, exclude_relations=None) -> Album:
if exclude_relations is None:
exclude_relations = set()
new_exclude_relations: set = exclude_relations.copy()
new_exclude_relations.add(Album)
album_id = album_result['album_id']
@ -343,10 +357,7 @@ class Database:
barcode=album_result['barcode']
)
print(exclude_relations)
if Song not in exclude_relations:
print("yay")
# getting the tracklist
tracklist: List[Song] = self.pull_songs(
album_ref=Reference(id_=album_id),
@ -356,18 +367,30 @@ class Database:
return album_obj
def pull_albums(self, album_ref: Reference = None, exclude_relations: set = set()) -> List[Album]:
def pull_albums(self, album_ref: Reference = None, song_ref: Reference = None, exclude_relations: set = None) -> List[Album]:
"""
This function is used to get matching albums/releses
from one song id (a reference object)
:param exclude_relations:
By default all relations are pulled by this funktion. If the class object of for
example the Artists is in the set it won't get fetched.
This is done to prevent an infinite recursion.
:param album_ref:
:return requested_album_list:
"""
if exclude_relations is None:
exclude_relations = set()
query = ALBUM_QUERY_UNJOINED
where = "1=1"
if album_ref is not None:
query = ALBUM_QUERY_UNJOINED
where = f"Album.id=\"{album_ref.id}\""
elif song_ref is not None:
query = ALBUM_QUERY_JOINED
where = f"Song.id=\"{song_ref.id}\""
query = ALBUM_QUERY.format(where=where)
query = query.format(where=where)
self.cursor.execute(query)
album_rows = self.cursor.fetchall()

View File

@ -145,6 +145,7 @@ class Song(DatabaseObject):
artist_names: List[str] = [],
isrc: str = None,
length: int = None,
tracksort: int = None,
sources: List[Source] = None,
target: Target = None,
lyrics: List[Lyrics] = None,
@ -167,6 +168,7 @@ class Song(DatabaseObject):
self.isrc: str | None = isrc
self.length_: int | None = length
self.artist_names = artist_names
self.tracksort: int | None = tracksort
self.metadata = Metadata(data=metadata)
@ -190,7 +192,7 @@ class Song(DatabaseObject):
self.album_ref = album_ref
self.artist_refs = artist_refs
self.album: Album = None
self._album: Album | None = None
def __eq__(self, other):
if type(other) != type(self):
@ -227,11 +229,20 @@ class Song(DatabaseObject):
return None
return self.album_ref.id
length = property(fget=get_length, fset=set_length)
def set_album(self, album):
if self.album_ref.id is not None:
if self.album_ref.id != album.id:
logger.warning(f"song already refers to different album, overriding reference.")
self.album_ref = Reference(album.id)
self._album = album
album = property(fget=lambda self: self._album, fset=set_album)
length: int = property(fget=get_length, fset=set_length)
"""
All objects dependend on Album
All objects dependent on Album
"""
@ -273,11 +284,22 @@ class Album(DatabaseObject):
self.tracklist: List[Song] = []
def __str__(self) -> str:
return f"Album: \"{self.title}\""
def __len__(self) -> int:
return len(self.tracklist)
def set_tracklist(self, tracklist: List[Song]):
self.tracklist = tracklist
for i, track in enumerate(self.tracklist):
track.tracksort = i+1
def add_song(self, song: Song):
for existing_song in self.tracklist:
if existing_song == song:
return
song.tracksort = len(self.tracklist)
self.tracklist.append(song)

View File

@ -4,6 +4,7 @@ CREATE TABLE Song
name TEXT,
isrc TEXT,
length INT, -- length is in milliseconds (could be wrong)
tracksort INT,
album_id BIGINT,
FOREIGN KEY(album_id) REFERENCES Album(id)
);

Binary file not shown.