refactoring

This commit is contained in:
Lars Noack 2022-12-01 13:15:30 +01:00
parent 67e1aa8a3c
commit 13e026d1e5
11 changed files with 159 additions and 107 deletions

View File

@ -1,5 +1,7 @@
import music_kraken import music_kraken
music_kraken.clear_cache()
artist = music_kraken.Artist( artist = music_kraken.Artist(
name="I'm in a Coffin" name="I'm in a Coffin"
) )
@ -11,5 +13,6 @@ song = music_kraken.Song(
) )
print(song) print(song)
print(song.id)
music_kraken.fetch_sources([song]) # music_kraken.fetch_sources([song])

View File

@ -1,17 +1,13 @@
from . import ( from . import (
temp_database, temp_database,
song, song
artist,
metadata,
source,
target,
) )
Song = song.Song Song = song.Song
Artist = song.Artist Artist = song.Artist
Source = source.Source Source = song.Source
Target = target.Target Target = song.Target
Metadata = metadata.Metadata Metadata = song.Metadata
Lyrics = song.Lyrics Lyrics = song.Lyrics
cache = temp_database.TempDatabase() cache = temp_database.TempDatabase()

View File

@ -1,15 +0,0 @@
class Artist:
def __init__(self, artist_data) -> None:
self.artist_data = artist_data
self.id = self.artist_data['id']
self.name = self.artist_data['name']
def __eq__(self, __o: object) -> bool:
if type(__o) != type(self):
return False
return self.id == __o.id
def __str__(self) -> str:
return self.name

View File

@ -3,10 +3,12 @@ import sqlite3
import os import os
import logging import logging
import json import json
import requests
from pkg_resources import resource_string from pkg_resources import resource_string
from . import song from .song import (
Song,
Lyrics
)
from .get_song import get_song_from_response from .get_song import get_song_from_response
from ..utils.shared import ( from ..utils.shared import (
DATABASE_LOGGER DATABASE_LOGGER
@ -153,7 +155,24 @@ SELECT DISTINCT
) )
) )
), ),
'lyrics', json_group_array(
(
SELECT DISTINCT json_object(
'text', lyrics_table.text
'language', lyrics_table.language
)
)
),
'target', json_group_array(
(
SELECT DISTINCT json_object(
'file', target.file
'path', target.path
)
)
),
'id', track.id, 'id', track.id,
'mb_id', track.mb_id,
'tracknumber', track.tracknumber, 'tracknumber', track.tracknumber,
'titlesort', track.tracknumber, 'titlesort', track.tracknumber,
'musicbrainz_releasetrackid', track.id, 'musicbrainz_releasetrackid', track.id,
@ -187,13 +206,15 @@ LEFT JOIN release_group ON release_.id = release_group.id
LEFT JOIN artist_track ON track.id = artist_track.track_id LEFT JOIN artist_track ON track.id = artist_track.track_id
LEFT JOIN artist ON artist_track.artist_id = artist.id LEFT JOIN artist ON artist_track.artist_id = artist.id
LEFT JOIN source src_table ON track.id = src_table.track_id LEFT JOIN source src_table ON track.id = src_table.track_id
LEFT JOIN lyrics lyrics_table ON track.id = lyrics_table.track_id
LEFT JOIN target ON track.id = target.track_id
WHERE WHERE
{where_arg} {where_arg}
GROUP BY track.id; GROUP BY track.id;
""" """
return query return query
def get_custom_track(self, custom_where: list) -> List[song.Song]: def get_custom_track(self, custom_where: list) -> List[Song]:
query = Database.get_custom_track_query(custom_where=custom_where) query = Database.get_custom_track_query(custom_where=custom_where)
return [get_song_from_response(json.loads(i[0])) for i in self.cursor.execute(query)] return [get_song_from_response(json.loads(i[0])) for i in self.cursor.execute(query)]
@ -205,22 +226,22 @@ GROUP BY track.id;
return resulting_tracks[0] return resulting_tracks[0]
def get_tracks_to_download(self) -> List[song.Song]: def get_tracks_to_download(self) -> List[Song]:
return self.get_custom_track(['track.downloaded == 0']) return self.get_custom_track(['track.downloaded == 0'])
def get_tracks_without_src(self) -> List[song.Song]: def get_tracks_without_src(self) -> List[Song]:
return self.get_custom_track(["(track.url IS NULL OR track.src IS NULL)"]) return self.get_custom_track(["(track.url IS NULL OR track.src IS NULL)"])
def get_tracks_without_isrc(self) -> List[song.Song]: def get_tracks_without_isrc(self) -> List[Song]:
return self.get_custom_track(["track.isrc IS NULL"]) return self.get_custom_track(["track.isrc IS NULL"])
def get_tracks_without_filepath(self) -> List[song.Song]: def get_tracks_without_filepath(self) -> List[Song]:
return self.get_custom_track(["(track.file IS NULL OR track.path IS NULL OR track.genre IS NULL)"]) return self.get_custom_track(["(track.file IS NULL OR track.path IS NULL OR track.genre IS NULL)"])
def get_tracks_for_lyrics(self) -> List[song.Song]: def get_tracks_for_lyrics(self) -> List[Song]:
return self.get_custom_track(["track.lyrics IS NULL"]) return self.get_custom_track(["track.lyrics IS NULL"])
def add_lyrics(self, song: song.Song, lyrics: song.Lyrics): def add_lyrics(self, song: Song, lyrics: Lyrics):
query = f""" query = f"""
UPDATE track UPDATE track
SET lyrics = ? SET lyrics = ?
@ -264,6 +285,13 @@ WHERE '{track_id}' == id;
self.cursor.execute(query, (file, path, genre)) self.cursor.execute(query, (file, path, genre))
self.connection.commit() self.connection.commit()
def write_song(self, song: Song):
pass
def write_many_song(self, songs: List[Song]):
for song in songs:
self.write_song(song=song)
if __name__ == "__main__": if __name__ == "__main__":
import tempfile import tempfile

View File

@ -0,0 +1,23 @@
import uuid
from ..utils.shared import (
SONG_LOGGER as logger
)
class DatabaseObject:
def __init__(self, id_: str = None) -> None:
self.id_: str | None = id_
def get_id(self):
"""
returns the id if it is set, else
it returns a randomly generated UUID
https://docs.python.org/3/library/uuid.html
"""
if self.id_ is None:
self.id_ = str(uuid.uuid4())
logger.info(f"id for {self.__str__()} isn't set. Setting to {self.id_}")
return self.id_
id = property(fget=get_id)

View File

@ -1,17 +0,0 @@
from mutagen.easyid3 import EasyID3
class Metadata:
def __init__(self) -> None:
self.data = {}
def get_all_metadata(self):
return list(self.data.items())
def __setitem__(self, item, value):
if item in EasyID3.valid_keys.keys():
self.data[item] = value
def __getitem__(self, item):
if item not in self.data:
return None
return self.data[item]

View File

@ -1,9 +1,77 @@
from typing import List from typing import List
import uuid
import os
from mutagen.easyid3 import EasyID3
from .artist import Artist from ..utils.shared import (
from .metadata import Metadata MUSIC_DIR,
from .source import Source SONG_LOGGER as logger
from .target import Target )
from .database_object import DatabaseObject
class Metadata:
def __init__(self) -> None:
self.data = {}
def get_all_metadata(self):
return list(self.data.items())
def __setitem__(self, item, value):
if item in EasyID3.valid_keys.keys():
self.data[item] = value
def __getitem__(self, item):
if item not in self.data:
return None
return self.data[item]
class Source:
def __init__(self, src_data) -> None:
self.src_data = src_data
self.src = self.src_data['src']
self.url = self.src_data['url']
class Target:
def __init__(self) -> None:
self._file = None
self._path = None
def set_file(self, _file: str):
self._file = _file
def get_file(self) -> str | None:
if self._file is None:
return None
return os.path.join(MUSIC_DIR, self._file)
def set_path(self, _path: str):
self._path = _path
def get_path(self) -> str | None:
if self._path is None:
return None
return os.path.join(MUSIC_DIR, self._path)
def get_exists_on_disc(self) -> bool:
"""
returns True when file can be found on disc
returns False when file can't be found on disc or no filepath is set
"""
if not self.is_set():
return False
return os.path.exists(self.file)
def is_set(self) -> bool:
return not (self._file is None or self._path is None)
file = property(fget=get_file, fset=set_file)
path = property(fget=get_path, fset=set_path)
exists_on_disc = property(fget=get_exists_on_disc)
class Artist: class Artist:
@ -50,7 +118,7 @@ class LyricsContainer:
is_empty = property(fget=lambda self: len(self.lyrics_list) <= 0) is_empty = property(fget=lambda self: len(self.lyrics_list) <= 0)
class Song: class Song(DatabaseObject):
def __init__( def __init__(
self, self,
id_: str = None, id_: str = None,
@ -71,8 +139,9 @@ class Song:
target: Each Song can have exactly one target which can be either full or empty target: Each Song can have exactly one target which can be either full or empty
lyrics: There can be multiple lyrics. Each Lyrics object can me added to multiple lyrics lyrics: There can be multiple lyrics. Each Lyrics object can me added to multiple lyrics
""" """
super().__init__(id_=id_)
# attributes # attributes
self.id: str | None = id_ # self.id_: str | None = id_
self.mb_id: str | None = mb_id self.mb_id: str | None = mb_id
self.title: str | None = title self.title: str | None = title
self.release: str | None = release self.release: str | None = release

View File

@ -1,6 +0,0 @@
class Source:
def __init__(self, src_data) -> None:
self.src_data = src_data
self.src = self.src_data['src']
self.url = self.src_data['url']

View File

@ -1,45 +0,0 @@
import os
from ..utils.shared import (
MUSIC_DIR
)
class Target:
def __init__(self) -> None:
self._file = None
self._path = None
def set_file(self, _file: str):
self._file = _file
def get_file(self) -> str | None:
if self._file is None:
return None
return os.path.join(MUSIC_DIR, self._file)
def set_path(self, _path: str):
self._path = _path
def get_path(self) -> str | None:
if self._path is None:
return None
return os.path.join(MUSIC_DIR, self._path)
def get_exists_on_disc(self) -> bool:
"""
returns True when file can be found on disc
returns False when file can't be found on disc or no filepath is set
"""
if not self.is_set():
return False
return os.path.exists(self.file)
def is_set(self) -> bool:
return not (self._file is None or self._path is None)
file = property(fget=get_file, fset=set_file)
path = property(fget=get_path, fset=set_path)
exists_on_disc = property(fget=get_exists_on_disc)

View File

@ -45,6 +45,7 @@ CREATE TABLE track (
id TEXT PRIMARY KEY NOT NULL, id TEXT PRIMARY KEY NOT NULL,
downloaded BOOLEAN NOT NULL DEFAULT 0, downloaded BOOLEAN NOT NULL DEFAULT 0,
release_id TEXT NOT NULL, release_id TEXT NOT NULL,
mb_id TEXT,
track TEXT, track TEXT,
length INT, length INT,
tracknumber TEXT, tracknumber TEXT,
@ -57,6 +58,20 @@ CREATE TABLE track (
src TEXT src TEXT
); );
DROP TABLE IF EXISTS lyrics;
CREATE TABLE lyrics (
track_id TEXT NOT NULL,
text TEXT,
language TEXT
);
DROP TABLE IF EXISTS target;
CREATE TABLE target (
track_id TEXT NOT NULL,
file TEXT,
path TEXT
);
DROP TABLE IF EXISTS source; DROP TABLE IF EXISTS source;
CREATE TABLE source ( CREATE TABLE source (
track_id TEXT NOT NULL, track_id TEXT NOT NULL,

View File

@ -27,6 +27,7 @@ logging.basicConfig(
] ]
) )
SONG_LOGGER = logging.getLogger("song-obj")
SEARCH_LOGGER = logging.getLogger("mb-cli") SEARCH_LOGGER = logging.getLogger("mb-cli")
INIT_PATH_LOGGER = logging.getLogger("init_path") INIT_PATH_LOGGER = logging.getLogger("init_path")
DATABASE_LOGGER = logging.getLogger("database") DATABASE_LOGGER = logging.getLogger("database")