mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
add method and route to search across tracks, albums and artists.
+ break models into separate files + same for the utils and setup
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
from .album import Album
|
||||
from .track import Track
|
||||
from .artist import Artist, ArtistMinimal
|
||||
from .enums import FavType
|
||||
from .playlist import Playlist
|
||||
from .folder import Folder
|
||||
|
||||
__all__ = [
|
||||
"Album",
|
||||
"Track",
|
||||
"Artist",
|
||||
"ArtistMinimal",
|
||||
"Playlist",
|
||||
"Folder",
|
||||
"FavType",
|
||||
]
|
||||
@@ -0,0 +1,123 @@
|
||||
import dataclasses
|
||||
from dataclasses import dataclass
|
||||
|
||||
from .track import Track
|
||||
from .artist import Artist
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class Album:
|
||||
"""
|
||||
Creates an album object
|
||||
"""
|
||||
|
||||
albumhash: str
|
||||
title: str
|
||||
albumartists: list[Artist]
|
||||
|
||||
albumartisthash: str = ""
|
||||
image: str = ""
|
||||
count: int = 0
|
||||
duration: int = 0
|
||||
colors: list[str] = dataclasses.field(default_factory=list)
|
||||
date: str = ""
|
||||
|
||||
is_soundtrack: bool = False
|
||||
is_compilation: bool = False
|
||||
is_single: bool = False
|
||||
is_EP: bool = False
|
||||
is_favorite: bool = False
|
||||
is_live: bool = False
|
||||
genres: list[str] = dataclasses.field(default_factory=list)
|
||||
|
||||
def __post_init__(self):
|
||||
self.image = self.albumhash + ".webp"
|
||||
self.albumartisthash = "-".join(a.artisthash for a in self.albumartists)
|
||||
|
||||
def set_colors(self, colors: list[str]):
|
||||
self.colors = colors
|
||||
|
||||
def check_type(self):
|
||||
"""
|
||||
Runs all the checks to determine the type of album.
|
||||
"""
|
||||
self.is_soundtrack = self.check_is_soundtrack()
|
||||
if self.is_soundtrack:
|
||||
return
|
||||
|
||||
self.is_live = self.check_is_live_album()
|
||||
if self.is_live:
|
||||
return
|
||||
|
||||
self.is_compilation = self.check_is_compilation()
|
||||
if self.is_compilation:
|
||||
return
|
||||
|
||||
self.is_EP = self.check_is_ep()
|
||||
|
||||
def check_is_soundtrack(self) -> bool:
|
||||
"""
|
||||
Checks if the album is a soundtrack.
|
||||
"""
|
||||
keywords = ["motion picture", "soundtrack"]
|
||||
for keyword in keywords:
|
||||
if keyword in self.title.lower():
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def check_is_compilation(self) -> bool:
|
||||
"""
|
||||
Checks if the album is a compilation.
|
||||
"""
|
||||
artists = [a.name for a in self.albumartists] # type: ignore
|
||||
artists = "".join(artists).lower()
|
||||
|
||||
if "various artists" in artists:
|
||||
return True
|
||||
|
||||
substrings = ["the essential", "best of", "greatest hits", "#1 hits", "number ones", "super hits",
|
||||
"ultimate collection"]
|
||||
|
||||
for substring in substrings:
|
||||
if substring in self.title.lower():
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def check_is_live_album(self):
|
||||
"""
|
||||
Checks if the album is a live album.
|
||||
"""
|
||||
keywords = ["live from", "live at", "live in"]
|
||||
for keyword in keywords:
|
||||
if keyword in self.title.lower():
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def check_is_ep(self) -> bool:
|
||||
"""
|
||||
Checks if the album is an EP.
|
||||
"""
|
||||
return self.title.strip().endswith(" EP")
|
||||
|
||||
def check_is_single(self, tracks: list[Track]):
|
||||
"""
|
||||
Checks if the album is a single.
|
||||
"""
|
||||
if (
|
||||
len(tracks) == 1
|
||||
and tracks[0].title == self.title
|
||||
|
||||
# and tracks[0].track == 1
|
||||
# and tracks[0].disc == 1
|
||||
# Todo: Are the above commented checks necessary?
|
||||
):
|
||||
self.is_single = True
|
||||
|
||||
def get_date_from_tracks(self, tracks: list[Track]):
|
||||
for track in tracks:
|
||||
if track.date != "Unknown":
|
||||
self.date = track.date
|
||||
break
|
||||
@@ -0,0 +1,41 @@
|
||||
import dataclasses
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
|
||||
from app.utils.hashing import create_hash
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class Artist:
|
||||
"""
|
||||
Artist class
|
||||
"""
|
||||
|
||||
name: str
|
||||
artisthash: str = ""
|
||||
image: str = ""
|
||||
trackcount: int = 0
|
||||
albumcount: int = 0
|
||||
duration: int = 0
|
||||
colors: list[str] = dataclasses.field(default_factory=list)
|
||||
is_favorite: bool = False
|
||||
|
||||
def __post_init__(self):
|
||||
self.artisthash = create_hash(self.name, decode=True)
|
||||
self.image = self.artisthash + ".webp"
|
||||
self.colors = json.loads(str(self.colors))
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class ArtistMinimal:
|
||||
"""
|
||||
ArtistMinimal class
|
||||
"""
|
||||
|
||||
name: str
|
||||
artisthash: str = ""
|
||||
image: str = ""
|
||||
|
||||
def __post_init__(self):
|
||||
self.artisthash = create_hash(self.name, decode=True)
|
||||
self.image = self.artisthash + ".webp"
|
||||
@@ -0,0 +1,6 @@
|
||||
class FavType:
|
||||
"""Favorite types enum"""
|
||||
|
||||
track = "track"
|
||||
album = "album"
|
||||
artist = "artist"
|
||||
@@ -0,0 +1,10 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class Folder:
|
||||
name: str
|
||||
path: str
|
||||
has_tracks: bool
|
||||
is_sym: bool = False
|
||||
path_hash: str = ""
|
||||
@@ -0,0 +1,33 @@
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class Playlist:
|
||||
"""Creates playlist objects"""
|
||||
|
||||
id: int
|
||||
artisthashes: str | list[str]
|
||||
banner_pos: int
|
||||
has_gif: str | bool
|
||||
image: str
|
||||
last_updated: str
|
||||
name: str
|
||||
trackhashes: str | list[str]
|
||||
|
||||
thumb: str = ""
|
||||
count: int = 0
|
||||
duration: int = 0
|
||||
|
||||
def __post_init__(self):
|
||||
self.trackhashes = json.loads(str(self.trackhashes))
|
||||
self.artisthashes = json.loads(str(self.artisthashes))
|
||||
|
||||
self.count = len(self.trackhashes)
|
||||
self.has_gif = bool(int(self.has_gif))
|
||||
|
||||
if self.image is not None:
|
||||
self.thumb = "thumb_" + self.image
|
||||
else:
|
||||
self.image = "None"
|
||||
self.thumb = "None"
|
||||
@@ -0,0 +1,70 @@
|
||||
import dataclasses
|
||||
from dataclasses import dataclass
|
||||
|
||||
from app import settings
|
||||
from .artist import ArtistMinimal
|
||||
from app.utils.hashing import create_hash
|
||||
from app.utils.parsers import split_artists, remove_prod, parse_feat_from_title
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class Track:
|
||||
"""
|
||||
Track class
|
||||
"""
|
||||
|
||||
album: str
|
||||
albumartist: str | list[ArtistMinimal]
|
||||
albumhash: str
|
||||
artist: str | list[ArtistMinimal]
|
||||
bitrate: int
|
||||
copyright: str
|
||||
date: str
|
||||
disc: int
|
||||
duration: int
|
||||
filepath: str
|
||||
folder: str
|
||||
genre: str | list[str]
|
||||
title: str
|
||||
track: int
|
||||
trackhash: str
|
||||
|
||||
filetype: str = ""
|
||||
image: str = ""
|
||||
artist_hashes: list[str] = dataclasses.field(default_factory=list)
|
||||
is_favorite: bool = False
|
||||
og_title: str = ""
|
||||
|
||||
def __post_init__(self):
|
||||
self.og_title = self.title
|
||||
if self.artist is not None:
|
||||
artists = split_artists(self.artist)
|
||||
new_title = self.title
|
||||
|
||||
if settings.EXTRACT_FEAT:
|
||||
featured, new_title = parse_feat_from_title(self.title)
|
||||
original_lower = "-".join([a.lower() for a in artists])
|
||||
artists.extend([a for a in featured if a.lower() not in original_lower])
|
||||
|
||||
if settings.REMOVE_PROD:
|
||||
new_title = remove_prod(new_title)
|
||||
|
||||
# if track is a single
|
||||
if self.og_title == self.album:
|
||||
self.album = new_title
|
||||
|
||||
self.title = new_title
|
||||
|
||||
self.artist_hashes = [create_hash(a, decode=True) for a in artists]
|
||||
self.artist = [ArtistMinimal(a) for a in artists]
|
||||
|
||||
albumartists = split_artists(self.albumartist)
|
||||
self.albumartist = [ArtistMinimal(a) for a in albumartists]
|
||||
|
||||
self.filetype = self.filepath.rsplit(".", maxsplit=1)[-1]
|
||||
self.image = self.albumhash + ".webp"
|
||||
|
||||
if self.genre is not None:
|
||||
self.genre = str(self.genre).replace("/", ",").replace(";", ",")
|
||||
self.genre = str(self.genre).lower().split(",")
|
||||
self.genre = [g.strip() for g in self.genre]
|
||||
Reference in New Issue
Block a user