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 @@