From 44ac313617bb04273b6337bcc909c6e45a594775 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 18 Oct 2021 10:23:03 +0200 Subject: [PATCH] Adds support for artist's cover art in subsonic API (#1528) --- api/funkwhale_api/subsonic/serializers.py | 3 ++ api/funkwhale_api/subsonic/views.py | 15 +++++++++- api/tests/subsonic/test_serializers.py | 36 ++++++++++++++++++----- changes/changelog.d/1528.enhancement | 1 + 4 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 changes/changelog.d/1528.enhancement diff --git a/api/funkwhale_api/subsonic/serializers.py b/api/funkwhale_api/subsonic/serializers.py index 5d3990baf..237eb0cff 100644 --- a/api/funkwhale_api/subsonic/serializers.py +++ b/api/funkwhale_api/subsonic/serializers.py @@ -49,6 +49,7 @@ def get_artist_data(artist_values): "id": artist_values["id"], "name": artist_values["name"], "albumCount": artist_values["_albums_count"], + "coverArt": "ar-{}".format(artist_values["id"]), } @@ -82,6 +83,8 @@ class GetArtistSerializer(serializers.Serializer): "albumCount": len(albums), "album": [], } + if artist.attachment_cover_id: + payload["coverArt"] = "ar-{}".format(artist.id) for album in albums: album_data = { "id": album.id, diff --git a/api/funkwhale_api/subsonic/views.py b/api/funkwhale_api/subsonic/views.py index 3fe647140..f03fe2654 100644 --- a/api/funkwhale_api/subsonic/views.py +++ b/api/funkwhale_api/subsonic/views.py @@ -773,6 +773,19 @@ class SubsonicViewSet(viewsets.GenericViewSet): {"error": {"code": 70, "message": "cover art not found."}} ) attachment = album.attachment_cover + elif id.startswith("ar-"): + try: + artist_id = int(id.replace("ar-", "")) + artist = ( + music_models.Artist.objects.exclude(attachment_cover=None) + .select_related("attachment_cover") + .get(pk=artist_id) + ) + except (TypeError, ValueError, music_models.Album.DoesNotExist): + return response.Response( + {"error": {"code": 70, "message": "cover art not found."}} + ) + attachment = artist.attachment_cover elif id.startswith("at-"): try: attachment_id = id.replace("at-", "") @@ -932,7 +945,7 @@ class SubsonicViewSet(viewsets.GenericViewSet): ) uploads_qs = ( music_models.Upload.objects.playable_by(request.user.actor) - .select_related("track__attachment_cover", "track__description",) + .select_related("track__attachment_cover", "track__description") .order_by("-track__creation_date") ) diff --git a/api/tests/subsonic/test_serializers.py b/api/tests/subsonic/test_serializers.py index a57631724..c993942dc 100644 --- a/api/tests/subsonic/test_serializers.py +++ b/api/tests/subsonic/test_serializers.py @@ -67,10 +67,12 @@ def test_get_track_path(factory_kwargs, suffix, expected, factories): def test_get_artists_serializer(factories): - artist1 = factories["music.Artist"](name="eliot") - artist2 = factories["music.Artist"](name="Ellena") - artist3 = factories["music.Artist"](name="Rilay") - artist4 = factories["music.Artist"](name="") # Shouldn't be serialised + artist1 = factories["music.Artist"](name="eliot", with_cover=True) + artist2 = factories["music.Artist"](name="Ellena", with_cover=True) + artist3 = factories["music.Artist"](name="Rilay", with_cover=True) + artist4 = factories["music.Artist"]( + name="", with_cover=False + ) # Shouldn't be serialised factories["music.Album"].create_batch(size=3, artist=artist1) factories["music.Album"].create_batch(size=2, artist=artist2) @@ -81,13 +83,30 @@ def test_get_artists_serializer(factories): { "name": "E", "artist": [ - {"id": artist1.pk, "name": artist1.name, "albumCount": 3}, - {"id": artist2.pk, "name": artist2.name, "albumCount": 2}, + { + "id": artist1.pk, + "name": artist1.name, + "albumCount": 3, + "coverArt": "ar-{}".format(artist1.id), + }, + { + "id": artist2.pk, + "name": artist2.name, + "albumCount": 2, + "coverArt": "ar-{}".format(artist2.id), + }, ], }, { "name": "R", - "artist": [{"id": artist3.pk, "name": artist3.name, "albumCount": 0}], + "artist": [ + { + "id": artist3.pk, + "name": artist3.name, + "albumCount": 0, + "coverArt": "ar-{}".format(artist3.id), + } + ], }, ], } @@ -100,7 +119,7 @@ def test_get_artists_serializer(factories): def test_get_artist_serializer(factories): - artist = factories["music.Artist"]() + artist = factories["music.Artist"](with_cover=True) album = factories["music.Album"](artist=artist, with_cover=True) tracks = factories["music.Track"].create_batch(size=3, album=album) @@ -108,6 +127,7 @@ def test_get_artist_serializer(factories): "id": artist.pk, "name": artist.name, "albumCount": 1, + "coverArt": "ar-{}".format(artist.id), "album": [ { "id": album.pk, diff --git a/changes/changelog.d/1528.enhancement b/changes/changelog.d/1528.enhancement new file mode 100644 index 000000000..58fa56805 --- /dev/null +++ b/changes/changelog.d/1528.enhancement @@ -0,0 +1 @@ +Adds artist cover art in subsonic API response (#1528)