diff --git a/api/funkwhale_api/audio/serializers.py b/api/funkwhale_api/audio/serializers.py index c31cdb69d..d6d75a58f 100644 --- a/api/funkwhale_api/audio/serializers.py +++ b/api/funkwhale_api/audio/serializers.py @@ -235,6 +235,7 @@ class ChannelUpdateSerializer(serializers.Serializer): class ChannelSerializer(serializers.ModelSerializer): artist = serializers.SerializerMethodField() actor = serializers.SerializerMethodField() + downloads_count = serializers.SerializerMethodField() attributed_to = federation_serializers.APIActorSerializer() rss_url = serializers.CharField(source="get_rss_url") url = serializers.SerializerMethodField() @@ -250,6 +251,7 @@ class ChannelSerializer(serializers.ModelSerializer): "metadata", "rss_url", "url", + "downloads_count", ] def get_artist(self, obj): @@ -264,6 +266,9 @@ class ChannelSerializer(serializers.ModelSerializer): def get_subscriptions_count(self, obj): return obj.actor.received_follows.exclude(approved=False).count() + def get_downloads_count(self, obj): + return getattr(obj, "_downloads_count", None) + def get_actor(self, obj): if obj.attributed_to == actors.get_service_actor(): return None diff --git a/api/funkwhale_api/audio/views.py b/api/funkwhale_api/audio/views.py index 4f32ad63c..40ae12735 100644 --- a/api/funkwhale_api/audio/views.py +++ b/api/funkwhale_api/audio/views.py @@ -7,7 +7,7 @@ from rest_framework import viewsets from django import http from django.db import transaction -from django.db.models import Count, Prefetch, Q +from django.db.models import Count, Prefetch, Q, Sum from django.utils import timezone from funkwhale_api.common import locales @@ -93,6 +93,14 @@ class ChannelViewSet( return serializers.ChannelUpdateSerializer return serializers.ChannelCreateSerializer + def get_queryset(self): + queryset = super().get_queryset() + if self.action == "retrieve": + queryset = queryset.annotate( + _downloads_count=Sum("artist__tracks__downloads_count") + ) + return queryset + def perform_create(self, serializer): return serializer.save(attributed_to=self.request.user.actor) diff --git a/api/funkwhale_api/music/serializers.py b/api/funkwhale_api/music/serializers.py index c546dc316..124c57f62 100644 --- a/api/funkwhale_api/music/serializers.py +++ b/api/funkwhale_api/music/serializers.py @@ -294,6 +294,7 @@ class TrackSerializer(OptionalDescriptionMixin, serializers.Serializer): is_local = serializers.BooleanField() position = serializers.IntegerField() disc_number = serializers.IntegerField() + downloads_count = serializers.IntegerField() copyright = serializers.CharField() license = serializers.SerializerMethodField() cover = cover_field diff --git a/api/tests/audio/test_serializers.py b/api/tests/audio/test_serializers.py index 0eecba8d9..0d1c91cc5 100644 --- a/api/tests/audio/test_serializers.py +++ b/api/tests/audio/test_serializers.py @@ -213,7 +213,7 @@ def test_channel_serializer_update_podcast(factories): def test_channel_serializer_representation(factories, to_api_date): content = factories["common.Content"]() channel = factories["audio.Channel"](artist__description=content) - + setattr(channel, "_downloads_count", 12) expected = { "artist": music_serializers.serialize_artist_simple(channel.artist), "uuid": str(channel.uuid), @@ -225,6 +225,7 @@ def test_channel_serializer_representation(factories, to_api_date): "metadata": {}, "rss_url": channel.get_rss_url(), "url": channel.actor.url, + "downloads_count": 12, } expected["artist"]["description"] = common_serializers.ContentSerializer( content @@ -248,6 +249,7 @@ def test_channel_serializer_external_representation(factories, to_api_date): "metadata": {}, "rss_url": channel.get_rss_url(), "url": channel.actor.url, + "downloads_count": None, } expected["artist"]["description"] = common_serializers.ContentSerializer( content diff --git a/api/tests/music/test_serializers.py b/api/tests/music/test_serializers.py index 9500a2c6a..1fb5ac120 100644 --- a/api/tests/music/test_serializers.py +++ b/api/tests/music/test_serializers.py @@ -234,6 +234,7 @@ def test_track_serializer(factories, to_api_date): "tags": [], "attributed_to": federation_serializers.APIActorSerializer(actor).data, "cover": common_serializers.AttachmentSerializer(track.attachment_cover).data, + "downloads_count": track.downloads_count, } serializer = serializers.TrackSerializer(track) assert serializer.data == expected diff --git a/changes/changelog.d/1178.enhancement b/changes/changelog.d/1178.enhancement new file mode 100644 index 000000000..b247fd098 --- /dev/null +++ b/changes/changelog.d/1178.enhancement @@ -0,0 +1 @@ +Display channel and track downloads count (#1178) \ No newline at end of file diff --git a/front/src/components/library/TrackDetail.vue b/front/src/components/library/TrackDetail.vue index 5802a734e..1d9461ae5 100644 --- a/front/src/components/library/TrackDetail.vue +++ b/front/src/components/library/TrackDetail.vue @@ -48,6 +48,14 @@ N/A + + + Downloads + + + {{ track.downloads_count }} + + diff --git a/front/src/views/channels/DetailBase.vue b/front/src/views/channels/DetailBase.vue index 627c5010b..c6e00b73f 100644 --- a/front/src/views/channels/DetailBase.vue +++ b/front/src/views/channels/DetailBase.vue @@ -28,7 +28,8 @@ %{ count } track