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 import music_kraken.database.new_database as db
def div():
print("-"*100)
cache = music_kraken.database.new_database.Database("test.db") cache = music_kraken.database.new_database.Database("test.db")
cache.reset() cache.reset()
@ -21,6 +24,7 @@ song_input = Song(
title="Vein Deep in the Solution", title="Vein Deep in the Solution",
album_name=album_input.title, album_name=album_input.title,
length=666, length=666,
tracksort=2,
target=Target(file="~/Music/genre/artist/album/song.mp3", path="~/Music/genre/artist/album"), target=Target(file="~/Music/genre/artist/album/song.mp3", path="~/Music/genre/artist/album"),
metadata={ metadata={
"album": "One Final Action" "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]) cache.push([album_input, song_input, lyrics, additional_song])
# getting song by song ref # getting song by song ref
div()
song_output_list = cache.pull_songs(song_ref=song_ref) song_output_list = cache.pull_songs(song_ref=song_ref)
print(len(song_output_list), song_output_list, song_output_list[0].album) print(len(song_output_list), song_output_list, song_output_list[0].album, sep=" | ")
# song_output = song_output_list[0] print("tracksort", song_output_list[0].tracksort, sep=": ")
# print(song_output)
# print("album id", song_output.album_ref)
# getting song by album ref # getting song by album ref
div()
song_output_list = cache.pull_songs(album_ref=album_input.reference) song_output_list = cache.pull_songs(album_ref=album_input.reference)
print(len(song_output_list), song_output_list) print(len(song_output_list), song_output_list)
for song in song_output_list:
print(song, song.album)
# getting album # getting album
div()
album_output_list = cache.pull_albums(album_ref=album_input.reference) album_output_list = cache.pull_albums(album_ref=album_input.reference)
album_output = album_output_list[0] album_output = album_output_list[0]
print(album_output) 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 # use complicated query builder
SONG_QUERY = """ SONG_QUERY = """
SELECT 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 Target.id AS target_id, Target.file AS file, Target.path AS path
FROM Song FROM Song
LEFT JOIN Target ON Song.id=Target.song_id LEFT JOIN Target ON Song.id=Target.song_id
@ -38,11 +38,17 @@ SELECT id, text, language, song_id
FROM Lyrics FROM Lyrics
WHERE {where}; WHERE {where};
""" """
ALBUM_QUERY = """ ALBUM_QUERY_UNJOINED = """
SELECT Album.id AS album_id, title, copyright, album_status, language, year, date, country, barcode SELECT Album.id AS album_id, title, copyright, album_status, language, year, date, country, barcode
FROM Album FROM Album
WHERE {where}; 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: class Database:
@ -147,9 +153,10 @@ class Database:
song.title, song.title,
song.isrc, song.isrc,
song.length, 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.cursor.execute(query, values)
self.connection.commit() self.connection.commit()
@ -268,17 +275,20 @@ class Database:
url=source_row['url'] url=source_row['url']
) for source_row in source_rows] ) 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: set = set(exclude_relations)
new_exclude_relations.add(Song) new_exclude_relations.add(Song)
song_id = song_result['song_id'] song_id = song_result['song_id']
song_obj = Song( song_obj = Song(
id_=song_id, id_=song_id,
title=song_result['title'], title=song_result['title'],
isrc=song_result['isrc'], isrc=song_result['isrc'],
length=song_result['length'], length=song_result['length'],
tracksort=song_result['tracksort'],
target=Target( target=Target(
id_=song_result['target_id'], id_=song_result['target_id'],
file=song_result['file'], file=song_result['file'],
@ -290,21 +300,24 @@ class Database:
) )
if Album not in exclude_relations and song_result['album_id'] is not None: 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: if len(album_obj) > 0:
song_obj.album = album_obj[0] song_obj.album = album_obj[0]
return song_obj 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) This function is used to get one song (including its children like Sources etc)
from one song id (a reference object) 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 song_ref:
:param album_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: :return requested_song:
""" """
@ -313,7 +326,7 @@ class Database:
where = f"Song.id=\"{song_ref.id}\"" where = f"Song.id=\"{song_ref.id}\""
elif album_ref is not None: elif album_ref is not None:
where = f"Song.album_id=\"{album_ref.id}\"" where = f"Song.album_id=\"{album_ref.id}\""
query = SONG_QUERY.format(where=where) query = SONG_QUERY.format(where=where)
self.cursor.execute(query) self.cursor.execute(query)
@ -324,11 +337,12 @@ class Database:
exclude_relations=exclude_relations exclude_relations=exclude_relations
) for song_result in song_rows] ) 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: set = exclude_relations.copy()
new_exclude_relations.add(Album) new_exclude_relations.add(Album)
album_id = album_result['album_id'] album_id = album_result['album_id']
album_obj = Album( album_obj = Album(
@ -343,10 +357,7 @@ class Database:
barcode=album_result['barcode'] barcode=album_result['barcode']
) )
print(exclude_relations)
if Song not in exclude_relations: if Song not in exclude_relations:
print("yay")
# getting the tracklist # getting the tracklist
tracklist: List[Song] = self.pull_songs( tracklist: List[Song] = self.pull_songs(
album_ref=Reference(id_=album_id), album_ref=Reference(id_=album_id),
@ -356,18 +367,30 @@ class Database:
return album_obj 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 This function is used to get matching albums/releses
from one song id (a reference object) 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: :param album_ref:
:return requested_album_list: :return requested_album_list:
""" """
if exclude_relations is None:
exclude_relations = set()
query = ALBUM_QUERY_UNJOINED
where = "1=1" where = "1=1"
if album_ref is not None: if album_ref is not None:
query = ALBUM_QUERY_UNJOINED
where = f"Album.id=\"{album_ref.id}\"" 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) self.cursor.execute(query)
album_rows = self.cursor.fetchall() album_rows = self.cursor.fetchall()

View File

@ -145,6 +145,7 @@ class Song(DatabaseObject):
artist_names: List[str] = [], artist_names: List[str] = [],
isrc: str = None, isrc: str = None,
length: int = None, length: int = None,
tracksort: int = None,
sources: List[Source] = None, sources: List[Source] = None,
target: Target = None, target: Target = None,
lyrics: List[Lyrics] = None, lyrics: List[Lyrics] = None,
@ -167,6 +168,7 @@ class Song(DatabaseObject):
self.isrc: str | None = isrc self.isrc: str | None = isrc
self.length_: int | None = length self.length_: int | None = length
self.artist_names = artist_names self.artist_names = artist_names
self.tracksort: int | None = tracksort
self.metadata = Metadata(data=metadata) self.metadata = Metadata(data=metadata)
@ -190,7 +192,7 @@ class Song(DatabaseObject):
self.album_ref = album_ref self.album_ref = album_ref
self.artist_refs = artist_refs self.artist_refs = artist_refs
self.album: Album = None self._album: Album | None = None
def __eq__(self, other): def __eq__(self, other):
if type(other) != type(self): if type(other) != type(self):
@ -227,11 +229,20 @@ class Song(DatabaseObject):
return None return None
return self.album_ref.id 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] = [] 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]): def set_tracklist(self, tracklist: List[Song]):
self.tracklist = tracklist self.tracklist = tracklist
for i, track in enumerate(self.tracklist):
track.tracksort = i+1
def add_song(self, song: Song): def add_song(self, song: Song):
for existing_song in self.tracklist: for existing_song in self.tracklist:
if existing_song == song: if existing_song == song:
return return
song.tracksort = len(self.tracklist)
self.tracklist.append(song) self.tracklist.append(song)

View File

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

Binary file not shown.