From a76e91cf5a11ef82bfdb7a479446257905de5eef Mon Sep 17 00:00:00 2001 From: cwilvx Date: Fri, 5 Jul 2024 04:43:39 +0300 Subject: [PATCH] fix: duplication of artist albums on album/from-artist + remove more fields from artist, album and artist models on serializers --- app/api/album.py | 42 ++++++++++++++++++++------------------- app/api/artist.py | 3 ++- app/db/libdata.py | 6 +++--- app/serializers/album.py | 11 +++++++++- app/serializers/artist.py | 9 +++++++++ app/serializers/track.py | 9 +++++++-- 6 files changed, 53 insertions(+), 27 deletions(-) diff --git a/app/api/album.py b/app/api/album.py index d03b3025..6c8ab65f 100644 --- a/app/api/album.py +++ b/app/api/album.py @@ -2,10 +2,8 @@ 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 @@ -16,10 +14,11 @@ 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 import flatten 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.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 @@ -86,7 +85,6 @@ def get_album_tracks(path: AlbumHashSchema): class GetMoreFromArtistsBody(AlbumLimitSchema): albumartists: list = Field( description="The artist hashes to get more albums from", - example='[{"name": "Khalid", "artisthash": "94ca2dba1c"}]', ) base_title: str = Field( @@ -108,23 +106,26 @@ def get_more_from_artist(body: GetMoreFromArtistsBody): base_title = body.base_title all_albums = AlbumDb.get_albums_by_artisthashes(albumartists) + seen_hashes = set() - # 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) + for artisthash, albums in all_albums.items(): + albums = [ + a + for a in albums + # INFO: filter out albums added to other artists + if a.albumhash not in seen_hashes + # INFO: filter out albums with the same base title + and create_hash(a.base_title) != create_hash(base_title) + ] + all_albums[artisthash] = serialize_for_card_many( + [a for a in albums if create_hash(a.base_title) != create_hash(base_title)][ + :limit + ] + ) + # INFO: record albums added to other artists + seen_hashes.update([a.albumhash for a in albums][:limit]) - 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 - ] + return all_albums class GetAlbumVersionsBody(ArtistHashSchema): @@ -183,6 +184,7 @@ def get_similar_albums(query: GetSimilarAlbumsQuery): artists = ArtistTable.get_artists_by_artisthashes(artisthashes) albums = AlbumDb.get_albums_by_artisthashes([a.artisthash for a in artists]) + albums = flatten(albums.values()) sample = random.sample(albums, min(len(albums), limit)) return serialize_for_card_many(sample[:limit]) diff --git a/app/api/artist.py b/app/api/artist.py index 65bc6798..d2b7e2af 100644 --- a/app/api/artist.py +++ b/app/api/artist.py @@ -22,6 +22,7 @@ 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 bp_tag = Tag(name="Artist", description="Single artist") @@ -166,4 +167,4 @@ def get_similar_artists(path: ArtistHashSchema, query: ArtistLimitSchema): if len(similar) > limit: similar = random.sample(similar, min(limit, len(similar))) - return similar[:limit] + return serialize_for_cards(similar[:limit]) diff --git a/app/db/libdata.py b/app/db/libdata.py index ecb0f5de..c769eb2e 100644 --- a/app/db/libdata.py +++ b/app/db/libdata.py @@ -311,14 +311,14 @@ class AlbumTable(Base): @classmethod def get_albums_by_artisthashes(cls, artisthashes: list[str]): with DbManager() as conn: - albums: list[AlbumModel] = [] + albums: dict[str, list[AlbumModel]] = {} for artist in artisthashes: result = conn.execute( # NOTE: The artist dict keys need to in the same order they appear in the db for this to work! - select(AlbumTable).where(AlbumTable.albumartists.contains(artist)) + select(AlbumTable).where(AlbumTable.artisthashes.contains(artist)) ) - albums.extend(albums_to_dataclasses(result.fetchall())) + albums[artist] = (albums_to_dataclasses(result.fetchall())) return albums diff --git a/app/serializers/album.py b/app/serializers/album.py index 2a559866..4bec0b4e 100644 --- a/app/serializers/album.py +++ b/app/serializers/album.py @@ -23,11 +23,20 @@ def serialize_for_card(album: Album): props_to_remove = { "duration", "count", + "artisthashes", "albumartists_hashes", + "created_date", "og_title", "base_title", "genres", - "playcount" + "playcount", + "trackcount", + "type", + "playduration", + "genrehashes", + "extra", + "id", + "lastplayed", } return album_serializer(album, props_to_remove) diff --git a/app/serializers/artist.py b/app/serializers/artist.py index 633b0789..dc39e72e 100644 --- a/app/serializers/artist.py +++ b/app/serializers/artist.py @@ -15,6 +15,15 @@ def serialize_for_card(artist: Artist): "duration", "albumcount", "playcount", + "playduration", + "playcount", + "lastplayed", + "id", + "genres", + "genrehashes", + "extra", + "created_date", + "date", } for key in props_to_remove: diff --git a/app/serializers/track.py b/app/serializers/track.py index 10426fbb..49618050 100644 --- a/app/serializers/track.py +++ b/app/serializers/track.py @@ -3,7 +3,7 @@ from dataclasses import asdict from app.models.track import Track -def serialize_track(track: Track, to_remove: set = {}, remove_disc=True) -> dict: +def serialize_track(track: Track, to_remove: set = set(), remove_disc=True) -> dict: album_dict = asdict(track) # is_favorite @property is not included in asdict album_dict["is_favorite"] = track.is_favorite @@ -21,6 +21,11 @@ def serialize_track(track: Track, to_remove: set = {}, remove_disc=True) -> dict "created_date", "fav_userids", "playcount", + "genrehashes", + "id", + "lastplayed", + "playduration", + "genres", }.union(to_remove) if not remove_disc: @@ -42,6 +47,6 @@ def serialize_track(track: Track, to_remove: set = {}, remove_disc=True) -> dict def serialize_tracks( - tracks: list[Track], _remove: set = {}, remove_disc=True + tracks: list[Track], _remove: set = set(), remove_disc=True ) -> list[dict]: return [serialize_track(t, _remove, remove_disc) for t in tracks]