mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 12:33:03 +00:00
rewrite album and artist stores using in-mem hashmap stores
This commit is contained in:
+36
-27
@@ -4,26 +4,24 @@ Contains all the album routes.
|
||||
|
||||
import random
|
||||
|
||||
from pydantic import Field
|
||||
from pydantic import BaseModel, 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.models.album import Album
|
||||
from app.settings import Defaults
|
||||
from app.utils import flatten
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.hashing import create_hash
|
||||
from app.lib.albumslib import sort_by_track_no
|
||||
from app.serializers.album import serialize_for_card_many
|
||||
from app.serializers.track import 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")
|
||||
@@ -39,12 +37,14 @@ def get_album_tracks_and_info(body: AlbumHashSchema):
|
||||
Returns album info and tracks for the given albumhash.
|
||||
"""
|
||||
albumhash = body.albumhash
|
||||
album = AlbumDb.get_album_by_albumhash(albumhash)
|
||||
# album = AlbumDb.get_album_by_albumhash(albumhash)
|
||||
albumentry = AlbumStore.albummap.get(albumhash)
|
||||
|
||||
if album is None:
|
||||
if albumentry is None:
|
||||
return {"error": "Album not found"}, 404
|
||||
|
||||
tracks = TrackDb.get_tracks_by_albumhash(albumhash)
|
||||
album = albumentry.album
|
||||
tracks = TrackStore.get_tracks_by_trackhashes(albumentry.trackhashes)
|
||||
album.trackcount = len(tracks)
|
||||
album.duration = sum(t.duration for t in tracks)
|
||||
album.check_type(
|
||||
@@ -52,6 +52,7 @@ def get_album_tracks_and_info(body: AlbumHashSchema):
|
||||
)
|
||||
|
||||
track_total = sum({int(t.extra.get("track_total", 1) or 1) for t in tracks})
|
||||
avg_bitrate = sum(t.bitrate for t in tracks) // (len(tracks) or 1)
|
||||
|
||||
return {
|
||||
"info": album,
|
||||
@@ -61,7 +62,7 @@ def get_album_tracks_and_info(body: AlbumHashSchema):
|
||||
# 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),
|
||||
"avg_bitrate": avg_bitrate,
|
||||
},
|
||||
"copyright": tracks[0].copyright,
|
||||
"tracks": serialize_tracks(tracks, remove_disc=False),
|
||||
@@ -76,7 +77,7 @@ def get_album_tracks(path: AlbumHashSchema):
|
||||
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 = AlbumStore.get_album_tracks(path.albumhash)
|
||||
tracks = sort_by_track_no(tracks)
|
||||
|
||||
return serialize_tracks(tracks)
|
||||
@@ -105,7 +106,11 @@ def get_more_from_artist(body: GetMoreFromArtistsBody):
|
||||
limit = body.limit
|
||||
base_title = body.base_title
|
||||
|
||||
all_albums = AlbumDb.get_albums_by_artisthashes(albumartists)
|
||||
all_albums: dict[str, list[Album]] = {}
|
||||
|
||||
for artisthash in albumartists:
|
||||
all_albums[artisthash] = AlbumStore.get_albums_by_artisthash(artisthash)
|
||||
|
||||
seen_hashes = set()
|
||||
|
||||
for artisthash, albums in all_albums.items():
|
||||
@@ -128,14 +133,15 @@ def get_more_from_artist(body: GetMoreFromArtistsBody):
|
||||
return all_albums
|
||||
|
||||
|
||||
class GetAlbumVersionsBody(ArtistHashSchema):
|
||||
class GetAlbumVersionsBody(BaseModel):
|
||||
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,
|
||||
|
||||
albumhash: str = Field(
|
||||
description="The album hash of the album to exclude from the results.",
|
||||
example=Defaults.API_ALBUMHASH,
|
||||
)
|
||||
|
||||
|
||||
@@ -146,18 +152,23 @@ def get_album_versions(body: GetAlbumVersionsBody):
|
||||
|
||||
Returns other versions of the given album.
|
||||
"""
|
||||
og_album_title = body.og_album_title
|
||||
base_title = body.base_title
|
||||
artisthash = body.artisthash
|
||||
albumhash = body.albumhash
|
||||
|
||||
albums = AlbumDb.get_albums_by_base_title(base_title)
|
||||
album = AlbumStore.albummap.get(albumhash)
|
||||
if not album:
|
||||
return []
|
||||
artisthash = album.album.artisthashes[0]
|
||||
albums = AlbumStore.get_albums_by_artisthash(artisthash)
|
||||
|
||||
basetitle = album.basetitle
|
||||
albums = [
|
||||
a
|
||||
for a in albums
|
||||
if a.og_title != og_album_title
|
||||
if a.og_title != album.album.og_title
|
||||
if a.base_title == basetitle
|
||||
and artisthash in {a["artisthash"] for a in a.albumartists}
|
||||
]
|
||||
print(albums)
|
||||
|
||||
return serialize_for_card_many(albums)
|
||||
|
||||
|
||||
@@ -181,10 +192,8 @@ def get_similar_albums(query: GetSimilarAlbumsQuery):
|
||||
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])
|
||||
albums = flatten(albums.values())
|
||||
artists = ArtistStore.get_artists_by_hashes(artisthashes)
|
||||
albums = AlbumStore.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])
|
||||
|
||||
+17
-14
@@ -17,14 +17,16 @@ from app.api.apischemas import (
|
||||
)
|
||||
|
||||
from app.config import UserConfig
|
||||
from app.db.libdata import ArtistTable
|
||||
from app.db.libdata import AlbumTable, TrackTable
|
||||
from app.db.userdata import SimilarArtistTable
|
||||
|
||||
from app.serializers.album import serialize_for_card_many
|
||||
from app.serializers.artist import serialize_for_cards
|
||||
from app.serializers.track import serialize_tracks
|
||||
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
|
||||
bp_tag = Tag(name="Artist", description="Single artist")
|
||||
api = APIBlueprint("artist", __name__, url_prefix="/artist", abp_tags=[bp_tag])
|
||||
|
||||
@@ -39,13 +41,15 @@ def get_artist(path: ArtistHashSchema, query: TrackLimitSchema):
|
||||
artisthash = path.artisthash
|
||||
limit = query.limit
|
||||
|
||||
artist = ArtistTable.get_artist_by_hash(artisthash)
|
||||
if artist is None:
|
||||
entry = ArtistStore.artistmap.get(artisthash)
|
||||
|
||||
if entry is None:
|
||||
return {"error": "Artist not found"}, 404
|
||||
|
||||
tracks = TrackTable.get_tracks_by_artisthash(artisthash)
|
||||
tracks = TrackStore.get_tracks_by_trackhashes(entry.trackhashes)
|
||||
tcount = len(tracks)
|
||||
|
||||
artist = entry.artist
|
||||
if artist.albumcount == 0 and tcount < 10:
|
||||
limit = tcount
|
||||
|
||||
@@ -85,19 +89,19 @@ def get_artist_albums(path: ArtistHashSchema, query: GetArtistAlbumsQuery):
|
||||
|
||||
limit = query.limit
|
||||
|
||||
artist = ArtistTable.get_artist_by_hash(artisthash)
|
||||
entry = ArtistStore.artistmap.get(artisthash)
|
||||
|
||||
if artist is None:
|
||||
if entry is None:
|
||||
return {"error": "Artist not found"}, 404
|
||||
|
||||
albums = AlbumTable.get_albums_by_artisthash(artisthash)
|
||||
tracks = TrackTable.get_tracks_by_artisthash(artisthash)
|
||||
albums = AlbumStore.get_albums_by_hashes(entry.albumhashes)
|
||||
tracks = TrackStore.get_tracks_by_trackhashes(entry.trackhashes)
|
||||
|
||||
missing_albumhashes = {
|
||||
t.albumhash for t in tracks if t.albumhash not in {a.albumhash for a in albums}
|
||||
}
|
||||
|
||||
albums.extend(AlbumTable.get_albums_by_albumhashes(missing_albumhashes))
|
||||
albums.extend(AlbumStore.get_albums_by_hashes(missing_albumhashes))
|
||||
albumdict = {a.albumhash: a for a in albums}
|
||||
|
||||
config = UserConfig()
|
||||
@@ -135,7 +139,7 @@ def get_artist_albums(path: ArtistHashSchema, query: GetArtistAlbumsQuery):
|
||||
for key, value in res.items():
|
||||
res[key] = serialize_for_card_many(value[:limit])
|
||||
|
||||
res["artistname"] = artist.name
|
||||
res["artistname"] = entry.artist.name
|
||||
return res
|
||||
|
||||
|
||||
@@ -146,8 +150,7 @@ def get_all_artist_tracks(path: ArtistHashSchema):
|
||||
|
||||
Returns all artists by a given artist.
|
||||
"""
|
||||
# tracks = TrackStore.get_tracks_by_artisthash(path.artisthash)
|
||||
tracks = TrackTable.get_tracks_by_artisthash(path.artisthash)
|
||||
tracks = ArtistStore.get_artist_tracks(path.artisthash)
|
||||
return serialize_tracks(tracks)
|
||||
|
||||
|
||||
@@ -162,7 +165,7 @@ def get_similar_artists(path: ArtistHashSchema, query: ArtistLimitSchema):
|
||||
if result is None:
|
||||
return []
|
||||
|
||||
similar = ArtistTable.get_artists_by_artisthashes(result.get_artist_hash_set())
|
||||
similar = ArtistStore.get_artists_by_hashes(result.get_artist_hash_set())
|
||||
|
||||
if len(similar) > limit:
|
||||
similar = random.sample(similar, min(limit, len(similar)))
|
||||
|
||||
Reference in New Issue
Block a user