refactored Song object. I hooooope it works
This commit is contained in:
parent
ddf19c4716
commit
12c453e005
@ -1,6 +1,7 @@
|
||||
import music_kraken as mk
|
||||
print(mk.__file__)
|
||||
|
||||
"""
|
||||
mk.clear_cache()
|
||||
song_list = mk.cache.get_custom_track([])
|
||||
print(mk.cache, len(song_list))
|
||||
@ -14,4 +15,5 @@ print(song.length)
|
||||
mk.set_targets(genre="test")
|
||||
|
||||
song = mk.cache.get_track_metadata(musicbrainz_releasetrackid=id_)
|
||||
mk.fetch_sources([song])
|
||||
"""
|
||||
mk.fetch_audios(mk.cache.get_tracks_to_download())
|
||||
|
@ -16,7 +16,7 @@ calling of the functions do search for a song and to download it.
|
||||
class AudioSource:
|
||||
@classmethod
|
||||
def fetch_source(cls, row: dict):
|
||||
logger.info(f"try getting source {row['title']} from {cls.__name__}")
|
||||
logger.info(f"try getting source {row.title} from {cls.__name__}")
|
||||
|
||||
@classmethod
|
||||
def fetch_audio(cls, song: song_objects.Song, src: song_objects.Source):
|
||||
|
@ -7,6 +7,7 @@ import requests
|
||||
from pkg_resources import resource_string
|
||||
|
||||
from . import song
|
||||
from .get_song import get_song_from_response
|
||||
from ..utils.shared import (
|
||||
DATABASE_LOGGER
|
||||
)
|
||||
@ -194,7 +195,7 @@ GROUP BY track.id;
|
||||
|
||||
def get_custom_track(self, custom_where: list) -> List[song.Song]:
|
||||
query = Database.get_custom_track_query(custom_where=custom_where)
|
||||
return [song.Song(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)]
|
||||
|
||||
def get_track_metadata(self, musicbrainz_releasetrackid: str):
|
||||
# this would be vulnerable if musicbrainz_releasetrackid would be user input
|
||||
|
@ -5,109 +5,6 @@ from .metadata import Metadata
|
||||
from .source import Source
|
||||
from .target import Target
|
||||
|
||||
# I don't import cache from the db module because it would lead to circular imports
|
||||
# from .temp_database import temp_database as cache
|
||||
# from . import cache
|
||||
|
||||
|
||||
|
||||
class Song:
|
||||
def __init__(
|
||||
self,
|
||||
json_response: dict,
|
||||
) -> None:
|
||||
"""
|
||||
id: is not NECESARRILY the musicbrainz id, but is DISTINCT for every song
|
||||
mb_id: is the musicbrainz_id
|
||||
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
|
||||
"""
|
||||
# attributes
|
||||
self.id: str | None = None
|
||||
self.mb_id: str | None = None
|
||||
self.title: str | None = None
|
||||
self.isrc: str | None = None
|
||||
self.length: int | None = None
|
||||
|
||||
self.metadata: Metadata = Metadata()
|
||||
# joins
|
||||
self.artists: List[Artist] = []
|
||||
self.lyrics: LyricsContainer = LyricsContainer(parent=self)
|
||||
|
||||
self.sources: List[Source] = []
|
||||
self.target: Target = Target()
|
||||
|
||||
self.json_data = json_response
|
||||
|
||||
# initialize the data
|
||||
self.id = self.json_data['id']
|
||||
self.title = self.json_data['title']
|
||||
self.artists = []
|
||||
for a in self.json_data['artists']:
|
||||
new_artist = Artist(a)
|
||||
exists = False
|
||||
for existing_artist in self.artists:
|
||||
if new_artist == existing_artist:
|
||||
exists = True
|
||||
break
|
||||
if not exists:
|
||||
self.artists.append(new_artist)
|
||||
self.isrc = self.json_data['isrc']
|
||||
|
||||
# initialize the sources
|
||||
self.sources: List[Source] = []
|
||||
for src in self.json_data['source']:
|
||||
if src['src'] is None:
|
||||
continue
|
||||
self.sources.append(Source(src))
|
||||
|
||||
# initialize the target
|
||||
self.target = Target()
|
||||
self.target.file = self.json_data['file']
|
||||
self.target.path = self.json_data['path']
|
||||
|
||||
# initialize id3 metadata
|
||||
self.metadata = Metadata()
|
||||
for key, value in self.json_data.items():
|
||||
self.metadata[key] = value
|
||||
self.metadata['artist'] = self.get_artist_names()
|
||||
|
||||
self.length = self.json_data['length']
|
||||
# EasyID3.valid_keys.keys()
|
||||
|
||||
# the lyrics are not in the metadata class because the field isn't supported
|
||||
# by easyid3
|
||||
self.lyrics: LyricsContainer = LyricsContainer(parent=self)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"\"{self.title}\" by {', '.join([str(a) for a in self.artists])}"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return self.__str__()
|
||||
|
||||
def get_metadata(self):
|
||||
return self.metadata.get_all_metadata()
|
||||
|
||||
def has_isrc(self) -> bool:
|
||||
return self.isrc is not None
|
||||
|
||||
def get_artist_names(self) -> List[str]:
|
||||
return [a.name for a in self.artists]
|
||||
|
||||
def __getitem__(self, item):
|
||||
if item not in self.json_data:
|
||||
return None
|
||||
return self.json_data[item]
|
||||
|
||||
def __setitem__(self, item, value):
|
||||
if item == "file":
|
||||
self.target.file = value
|
||||
return
|
||||
if item == "path":
|
||||
self.target.path = value
|
||||
return
|
||||
|
||||
self.json_data[item] = value
|
||||
|
||||
|
||||
class Lyrics:
|
||||
@ -117,11 +14,9 @@ class Lyrics:
|
||||
|
||||
|
||||
class LyricsContainer:
|
||||
def __init__(self, parent: Song):
|
||||
def __init__(self):
|
||||
self.lyrics_list: List[Lyrics] = []
|
||||
|
||||
self.parent = parent
|
||||
|
||||
def append(self, lyrics: Lyrics):
|
||||
# due to my db not supporting multiple Lyrics yet, I just use for doing stuff with the lyrics
|
||||
# the first element. I know this implementation is junk, but take it or leave it, it is going
|
||||
@ -141,3 +36,69 @@ class LyricsContainer:
|
||||
|
||||
is_empty = property(fget=lambda self: len(self.lyrics_list) <= 0)
|
||||
|
||||
|
||||
class Song:
|
||||
def __init__(
|
||||
self,
|
||||
id_: str = None,
|
||||
mb_id: str = None,
|
||||
title: str = None,
|
||||
release: str = None,
|
||||
isrc: str = None,
|
||||
length: int = None,
|
||||
artists: List[Artist] = None,
|
||||
metadata: Metadata = None,
|
||||
sources: List[Source] = None,
|
||||
target: Target = None,
|
||||
lyrics: LyricsContainer = None
|
||||
) -> None:
|
||||
"""
|
||||
id: is not NECESARRILY the musicbrainz id, but is DISTINCT for every song
|
||||
mb_id: is the musicbrainz_id
|
||||
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
|
||||
"""
|
||||
# attributes
|
||||
self.id: str | None = id_
|
||||
self.mb_id: str | None = mb_id
|
||||
self.title: str | None = title
|
||||
self.release: str | None = release
|
||||
self.isrc: str | None = isrc
|
||||
self.length: int | None = length
|
||||
|
||||
if metadata is None:
|
||||
metadata = Metadata()
|
||||
self.metadata: Metadata = metadata
|
||||
|
||||
# joins
|
||||
if artists is None:
|
||||
artists = []
|
||||
self.artists: List[Artist] = artists
|
||||
|
||||
if sources is None:
|
||||
sources = []
|
||||
self.sources: List[Source] = sources
|
||||
|
||||
if target is None:
|
||||
target = Target()
|
||||
self.target: Target = target
|
||||
|
||||
if lyrics is None:
|
||||
lyrics = LyricsContainer()
|
||||
self.lyrics: LyricsContainer = lyrics
|
||||
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"\"{self.title}\" by {', '.join([str(a) for a in self.artists])}"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return self.__str__()
|
||||
|
||||
def get_metadata(self):
|
||||
return self.metadata.get_all_metadata()
|
||||
|
||||
def has_isrc(self) -> bool:
|
||||
return self.isrc is not None
|
||||
|
||||
def get_artist_names(self) -> List[str]:
|
||||
return [a.name for a in self.artists]
|
||||
|
@ -22,22 +22,22 @@ class UrlPath:
|
||||
|
||||
self.genre = genre
|
||||
|
||||
for row in temp_database.get_tracks_without_filepath():
|
||||
# print(row)
|
||||
file, path = self.get_path_from_row(row)
|
||||
for song in temp_database.get_tracks_without_filepath():
|
||||
# print(song)
|
||||
file, path = self.get_path_from_song(song)
|
||||
logger.info(f"setting target to {file}")
|
||||
temp_database.set_filepath(row['id'], file, path, genre)
|
||||
temp_database.set_filepath(song.id, file, path, genre)
|
||||
|
||||
def get_path_from_row(self, row):
|
||||
def get_path_from_song(self, song):
|
||||
"""
|
||||
genre/artist/song.mp3
|
||||
|
||||
:param row:
|
||||
:param song:
|
||||
:return: path:
|
||||
"""
|
||||
return os.path.join(self.get_genre(), self.get_artist(row), self.get_album(row),
|
||||
f"{self.get_song(row)}.mp3"), os.path.join(self.get_genre(), self.get_artist(row),
|
||||
self.get_album(row))
|
||||
return os.path.join(self.get_genre(), self.get_artist(song), self.get_album(song),
|
||||
f"{self.get_song(song)}.mp3"), os.path.join(self.get_genre(), self.get_artist(song),
|
||||
self.get_album(song))
|
||||
|
||||
@staticmethod
|
||||
def escape_part(part: str):
|
||||
@ -46,15 +46,15 @@ class UrlPath:
|
||||
def get_genre(self):
|
||||
return self.escape_part(self.genre)
|
||||
|
||||
def get_album(self, row):
|
||||
return self.escape_part(row['album'])
|
||||
def get_album(self, song):
|
||||
return self.escape_part(song.release)
|
||||
|
||||
def get_artist(self, row):
|
||||
artists = [artist['name'] for artist in row['artists']]
|
||||
def get_artist(self, song):
|
||||
artists = song.get_artist_names()
|
||||
return self.escape_part(artists[0])
|
||||
|
||||
def get_song(self, row):
|
||||
return self.escape_part(row['title'])
|
||||
def get_song(self, song):
|
||||
return self.escape_part(song.title)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
Reference in New Issue
Block a user