mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
4a9f804e70
+ port populate to new db interface
+ add genrehashes and hash info to tracks
+ properly structure new db table files
+ move helpers to dedicated utils file
+ move settings from db to config file
+ move artists, albums, auth and favorites endpoint to new db interface
+ use folder store to index filepaths
+ paginate favorite pages
+ 56 moretiny changes 😅
189 lines
5.6 KiB
Python
189 lines
5.6 KiB
Python
"""
|
|
Contains all the album routes.
|
|
"""
|
|
|
|
from itertools import groupby
|
|
import random
|
|
|
|
from flask_jwt_extended import current_user
|
|
from pydantic import Field
|
|
from flask_openapi3 import Tag
|
|
from flask_openapi3 import APIBlueprint
|
|
from app.api.apischemas import AlbumHashSchema, AlbumLimitSchema, ArtistHashSchema
|
|
|
|
from app.config import UserConfig
|
|
from app.db.libdata import ArtistTable
|
|
from app.db.libdata import AlbumTable as AlbumDb, TrackTable as TrackDb
|
|
from app.db.userdata import SimilarArtistTable
|
|
from app.settings import Defaults
|
|
from app.utils.hashing import create_hash
|
|
from app.lib.albumslib import sort_by_track_no
|
|
from app.serializers.album import serialize_for_card, serialize_for_card_many
|
|
from app.serializers.track import serialize_track, serialize_tracks
|
|
from app.db.sqlite.albumcolors import SQLiteAlbumMethods as adb
|
|
from app.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
|
|
from app.db.sqlite.lastfm.similar_artists import SQLiteLastFMSimilarArtists as lastfmdb
|
|
|
|
get_albums_by_albumartist = adb.get_albums_by_albumartist
|
|
check_is_fav = favdb.check_is_favorite
|
|
|
|
bp_tag = Tag(name="Album", description="Single album")
|
|
api = APIBlueprint("album", __name__, url_prefix="/album", abp_tags=[bp_tag])
|
|
|
|
|
|
# NOTE: Don't use "/" as it will cause redirects (failure)
|
|
@api.post("")
|
|
def get_album_tracks_and_info(body: AlbumHashSchema):
|
|
"""
|
|
Get album and tracks
|
|
|
|
Returns album info and tracks for the given albumhash.
|
|
"""
|
|
albumhash = body.albumhash
|
|
album = AlbumDb.get_album_by_albumhash(albumhash)
|
|
|
|
if album is None:
|
|
return {"error": "Album not found"}, 404
|
|
|
|
tracks = TrackDb.get_tracks_by_albumhash(albumhash)
|
|
album.trackcount = len(tracks)
|
|
album.duration = sum(t.duration for t in tracks)
|
|
album.type = album.check_type(
|
|
tracks=tracks, singleTrackAsSingle=UserConfig().showAlbumsAsSingles
|
|
)
|
|
|
|
track_total = sum({int(t.extra.get("track_total", 1) or 1) for t in tracks})
|
|
|
|
return {
|
|
"info": album,
|
|
"extra": {
|
|
# INFO: track_total is the sum of a set of track_total values from each track
|
|
# ASSUMPTIONS
|
|
# 1. All the tracks have the correct track totals
|
|
# 2. Tracks with the same track total are from the same disc
|
|
"track_total": track_total,
|
|
"avg_bitrate": sum(t.bitrate for t in tracks) // len(tracks),
|
|
},
|
|
"copyright": tracks[0].copyright,
|
|
"tracks": serialize_tracks(tracks, remove_disc=False),
|
|
}
|
|
|
|
|
|
@api.get("/<albumhash>/tracks")
|
|
def get_album_tracks(path: AlbumHashSchema):
|
|
"""
|
|
Get album tracks
|
|
|
|
Returns all the tracks in the given album, sorted by disc and track number.
|
|
NOTE: No album info is returned.
|
|
"""
|
|
tracks = TrackDb.get_tracks_by_albumhash(path.albumhash)
|
|
tracks = sort_by_track_no(tracks)
|
|
|
|
return serialize_tracks(tracks)
|
|
|
|
|
|
class GetMoreFromArtistsBody(AlbumLimitSchema):
|
|
albumartists: list = Field(
|
|
description="The artist hashes to get more albums from",
|
|
example='[{"name": "Khalid", "artisthash": "94ca2dba1c"}]',
|
|
)
|
|
|
|
base_title: str = Field(
|
|
description="The base title of the album to exclude from the results.",
|
|
example=Defaults.API_ALBUMNAME,
|
|
default=None,
|
|
)
|
|
|
|
|
|
@api.post("/from-artist")
|
|
def get_more_from_artist(body: GetMoreFromArtistsBody):
|
|
"""
|
|
Get more from artist
|
|
|
|
Returns more albums from the given artist hashes.
|
|
"""
|
|
albumartists = body.albumartists
|
|
limit = body.limit
|
|
base_title = body.base_title
|
|
|
|
all_albums = AlbumDb.get_albums_by_artisthashes(albumartists)
|
|
|
|
# filter out albums with the same base title
|
|
all_albums = filter(
|
|
lambda a: create_hash(a.base_title) != create_hash(base_title), all_albums
|
|
)
|
|
all_albums = list(all_albums)
|
|
|
|
if not len(all_albums):
|
|
return []
|
|
|
|
# group by first albumartist's artisthash
|
|
groups = groupby(all_albums, lambda a: a.albumartists[0]["artisthash"])
|
|
|
|
return [
|
|
{"artisthash": g[0], "albums": serialize_for_card_many(list(g[1])[:limit])}
|
|
for g in groups
|
|
]
|
|
|
|
|
|
class GetAlbumVersionsBody(ArtistHashSchema):
|
|
og_album_title: str = Field(
|
|
description="The original album title (album.og_title)",
|
|
example=Defaults.API_ALBUMNAME,
|
|
)
|
|
base_title: str = Field(
|
|
description="The base title of the album to exclude from the results.",
|
|
example=Defaults.API_ALBUMNAME,
|
|
)
|
|
|
|
|
|
@api.post("/other-versions")
|
|
def get_album_versions(body: GetAlbumVersionsBody):
|
|
"""
|
|
Get other versions
|
|
|
|
Returns other versions of the given album.
|
|
"""
|
|
og_album_title = body.og_album_title
|
|
base_title = body.base_title
|
|
artisthash = body.artisthash
|
|
|
|
albums = AlbumDb.get_albums_by_base_title(base_title)
|
|
albums = [
|
|
a
|
|
for a in albums
|
|
if a.og_title != og_album_title
|
|
and artisthash in {a["artisthash"] for a in a.albumartists}
|
|
]
|
|
print(albums)
|
|
return serialize_for_card_many(albums)
|
|
|
|
|
|
class GetSimilarAlbumsQuery(ArtistHashSchema, AlbumLimitSchema):
|
|
pass
|
|
|
|
|
|
@api.get("/similar")
|
|
def get_similar_albums(query: GetSimilarAlbumsQuery):
|
|
"""
|
|
Get similar albums
|
|
|
|
Returns similar albums to the given album.
|
|
"""
|
|
artisthash = query.artisthash
|
|
limit = query.limit
|
|
|
|
similar_artists = SimilarArtistTable.get_by_hash(artisthash)
|
|
|
|
if similar_artists is None:
|
|
return []
|
|
|
|
artisthashes = similar_artists.get_artist_hash_set()
|
|
artists = ArtistTable.get_artists_by_artisthashes(artisthashes)
|
|
|
|
albums = AlbumDb.get_albums_by_artisthashes([a.artisthash for a in artists])
|
|
sample = random.sample(albums, min(len(albums), limit))
|
|
|
|
return serialize_for_card_many(sample[:limit])
|