mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
fix: duplication of artist albums on album/from-artist
+ remove more fields from artist, album and artist models on serializers
This commit is contained in:
+22
-20
@@ -2,10 +2,8 @@
|
|||||||
Contains all the album routes.
|
Contains all the album routes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from itertools import groupby
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from flask_jwt_extended import current_user
|
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
from flask_openapi3 import Tag
|
from flask_openapi3 import Tag
|
||||||
from flask_openapi3 import APIBlueprint
|
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.libdata import AlbumTable as AlbumDb, TrackTable as TrackDb
|
||||||
from app.db.userdata import SimilarArtistTable
|
from app.db.userdata import SimilarArtistTable
|
||||||
from app.settings import Defaults
|
from app.settings import Defaults
|
||||||
|
from app.utils import flatten
|
||||||
from app.utils.hashing import create_hash
|
from app.utils.hashing import create_hash
|
||||||
from app.lib.albumslib import sort_by_track_no
|
from app.lib.albumslib import sort_by_track_no
|
||||||
from app.serializers.album import serialize_for_card, serialize_for_card_many
|
from app.serializers.album import serialize_for_card_many
|
||||||
from app.serializers.track import serialize_track, serialize_tracks
|
from app.serializers.track import serialize_tracks
|
||||||
from app.db.sqlite.albumcolors import SQLiteAlbumMethods as adb
|
from app.db.sqlite.albumcolors import SQLiteAlbumMethods as adb
|
||||||
from app.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
|
from app.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
|
||||||
from app.db.sqlite.lastfm.similar_artists import SQLiteLastFMSimilarArtists as lastfmdb
|
from app.db.sqlite.lastfm.similar_artists import SQLiteLastFMSimilarArtists as lastfmdb
|
||||||
@@ -86,7 +85,6 @@ def get_album_tracks(path: AlbumHashSchema):
|
|||||||
class GetMoreFromArtistsBody(AlbumLimitSchema):
|
class GetMoreFromArtistsBody(AlbumLimitSchema):
|
||||||
albumartists: list = Field(
|
albumartists: list = Field(
|
||||||
description="The artist hashes to get more albums from",
|
description="The artist hashes to get more albums from",
|
||||||
example='[{"name": "Khalid", "artisthash": "94ca2dba1c"}]',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
base_title: str = Field(
|
base_title: str = Field(
|
||||||
@@ -108,23 +106,26 @@ def get_more_from_artist(body: GetMoreFromArtistsBody):
|
|||||||
base_title = body.base_title
|
base_title = body.base_title
|
||||||
|
|
||||||
all_albums = AlbumDb.get_albums_by_artisthashes(albumartists)
|
all_albums = AlbumDb.get_albums_by_artisthashes(albumartists)
|
||||||
|
seen_hashes = set()
|
||||||
|
|
||||||
# filter out albums with the same base title
|
for artisthash, albums in all_albums.items():
|
||||||
all_albums = filter(
|
albums = [
|
||||||
lambda a: create_hash(a.base_title) != create_hash(base_title), all_albums
|
a
|
||||||
)
|
for a in albums
|
||||||
all_albums = list(all_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 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):
|
class GetAlbumVersionsBody(ArtistHashSchema):
|
||||||
@@ -183,6 +184,7 @@ def get_similar_albums(query: GetSimilarAlbumsQuery):
|
|||||||
artists = ArtistTable.get_artists_by_artisthashes(artisthashes)
|
artists = ArtistTable.get_artists_by_artisthashes(artisthashes)
|
||||||
|
|
||||||
albums = AlbumDb.get_albums_by_artisthashes([a.artisthash for a in artists])
|
albums = AlbumDb.get_albums_by_artisthashes([a.artisthash for a in artists])
|
||||||
|
albums = flatten(albums.values())
|
||||||
sample = random.sample(albums, min(len(albums), limit))
|
sample = random.sample(albums, min(len(albums), limit))
|
||||||
|
|
||||||
return serialize_for_card_many(sample[:limit])
|
return serialize_for_card_many(sample[:limit])
|
||||||
|
|||||||
+2
-1
@@ -22,6 +22,7 @@ from app.db.libdata import AlbumTable, TrackTable
|
|||||||
from app.db.userdata import SimilarArtistTable
|
from app.db.userdata import SimilarArtistTable
|
||||||
|
|
||||||
from app.serializers.album import serialize_for_card_many
|
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.serializers.track import serialize_tracks
|
||||||
|
|
||||||
bp_tag = Tag(name="Artist", description="Single artist")
|
bp_tag = Tag(name="Artist", description="Single artist")
|
||||||
@@ -166,4 +167,4 @@ def get_similar_artists(path: ArtistHashSchema, query: ArtistLimitSchema):
|
|||||||
if len(similar) > limit:
|
if len(similar) > limit:
|
||||||
similar = random.sample(similar, min(limit, len(similar)))
|
similar = random.sample(similar, min(limit, len(similar)))
|
||||||
|
|
||||||
return similar[:limit]
|
return serialize_for_cards(similar[:limit])
|
||||||
|
|||||||
+3
-3
@@ -311,14 +311,14 @@ class AlbumTable(Base):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_albums_by_artisthashes(cls, artisthashes: list[str]):
|
def get_albums_by_artisthashes(cls, artisthashes: list[str]):
|
||||||
with DbManager() as conn:
|
with DbManager() as conn:
|
||||||
albums: list[AlbumModel] = []
|
albums: dict[str, list[AlbumModel]] = {}
|
||||||
|
|
||||||
for artist in artisthashes:
|
for artist in artisthashes:
|
||||||
result = conn.execute(
|
result = conn.execute(
|
||||||
# NOTE: The artist dict keys need to in the same order they appear in the db for this to work!
|
# 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
|
return albums
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,20 @@ def serialize_for_card(album: Album):
|
|||||||
props_to_remove = {
|
props_to_remove = {
|
||||||
"duration",
|
"duration",
|
||||||
"count",
|
"count",
|
||||||
|
"artisthashes",
|
||||||
"albumartists_hashes",
|
"albumartists_hashes",
|
||||||
|
"created_date",
|
||||||
"og_title",
|
"og_title",
|
||||||
"base_title",
|
"base_title",
|
||||||
"genres",
|
"genres",
|
||||||
"playcount"
|
"playcount",
|
||||||
|
"trackcount",
|
||||||
|
"type",
|
||||||
|
"playduration",
|
||||||
|
"genrehashes",
|
||||||
|
"extra",
|
||||||
|
"id",
|
||||||
|
"lastplayed",
|
||||||
}
|
}
|
||||||
|
|
||||||
return album_serializer(album, props_to_remove)
|
return album_serializer(album, props_to_remove)
|
||||||
|
|||||||
@@ -15,6 +15,15 @@ def serialize_for_card(artist: Artist):
|
|||||||
"duration",
|
"duration",
|
||||||
"albumcount",
|
"albumcount",
|
||||||
"playcount",
|
"playcount",
|
||||||
|
"playduration",
|
||||||
|
"playcount",
|
||||||
|
"lastplayed",
|
||||||
|
"id",
|
||||||
|
"genres",
|
||||||
|
"genrehashes",
|
||||||
|
"extra",
|
||||||
|
"created_date",
|
||||||
|
"date",
|
||||||
}
|
}
|
||||||
|
|
||||||
for key in props_to_remove:
|
for key in props_to_remove:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from dataclasses import asdict
|
|||||||
from app.models.track import Track
|
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)
|
album_dict = asdict(track)
|
||||||
# is_favorite @property is not included in asdict
|
# is_favorite @property is not included in asdict
|
||||||
album_dict["is_favorite"] = track.is_favorite
|
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",
|
"created_date",
|
||||||
"fav_userids",
|
"fav_userids",
|
||||||
"playcount",
|
"playcount",
|
||||||
|
"genrehashes",
|
||||||
|
"id",
|
||||||
|
"lastplayed",
|
||||||
|
"playduration",
|
||||||
|
"genres",
|
||||||
}.union(to_remove)
|
}.union(to_remove)
|
||||||
|
|
||||||
if not remove_disc:
|
if not remove_disc:
|
||||||
@@ -42,6 +47,6 @@ def serialize_track(track: Track, to_remove: set = {}, remove_disc=True) -> dict
|
|||||||
|
|
||||||
|
|
||||||
def serialize_tracks(
|
def serialize_tracks(
|
||||||
tracks: list[Track], _remove: set = {}, remove_disc=True
|
tracks: list[Track], _remove: set = set(), remove_disc=True
|
||||||
) -> list[dict]:
|
) -> list[dict]:
|
||||||
return [serialize_track(t, _remove, remove_disc) for t in tracks]
|
return [serialize_track(t, _remove, remove_disc) for t in tracks]
|
||||||
|
|||||||
Reference in New Issue
Block a user