Fx #1178: Display channel and track downloads count

environments/review-docs-devel-1399dq/deployments/6607
Agate 2020-07-31 11:46:25 +02:00
rodzic 75f9537d89
commit e9186ca813
8 zmienionych plików z 30 dodań i 3 usunięć

Wyświetl plik

@ -235,6 +235,7 @@ class ChannelUpdateSerializer(serializers.Serializer):
class ChannelSerializer(serializers.ModelSerializer): class ChannelSerializer(serializers.ModelSerializer):
artist = serializers.SerializerMethodField() artist = serializers.SerializerMethodField()
actor = serializers.SerializerMethodField() actor = serializers.SerializerMethodField()
downloads_count = serializers.SerializerMethodField()
attributed_to = federation_serializers.APIActorSerializer() attributed_to = federation_serializers.APIActorSerializer()
rss_url = serializers.CharField(source="get_rss_url") rss_url = serializers.CharField(source="get_rss_url")
url = serializers.SerializerMethodField() url = serializers.SerializerMethodField()
@ -250,6 +251,7 @@ class ChannelSerializer(serializers.ModelSerializer):
"metadata", "metadata",
"rss_url", "rss_url",
"url", "url",
"downloads_count",
] ]
def get_artist(self, obj): def get_artist(self, obj):
@ -264,6 +266,9 @@ class ChannelSerializer(serializers.ModelSerializer):
def get_subscriptions_count(self, obj): def get_subscriptions_count(self, obj):
return obj.actor.received_follows.exclude(approved=False).count() 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): def get_actor(self, obj):
if obj.attributed_to == actors.get_service_actor(): if obj.attributed_to == actors.get_service_actor():
return None return None

Wyświetl plik

@ -7,7 +7,7 @@ from rest_framework import viewsets
from django import http from django import http
from django.db import transaction 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 django.utils import timezone
from funkwhale_api.common import locales from funkwhale_api.common import locales
@ -93,6 +93,14 @@ class ChannelViewSet(
return serializers.ChannelUpdateSerializer return serializers.ChannelUpdateSerializer
return serializers.ChannelCreateSerializer 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): def perform_create(self, serializer):
return serializer.save(attributed_to=self.request.user.actor) return serializer.save(attributed_to=self.request.user.actor)

Wyświetl plik

@ -294,6 +294,7 @@ class TrackSerializer(OptionalDescriptionMixin, serializers.Serializer):
is_local = serializers.BooleanField() is_local = serializers.BooleanField()
position = serializers.IntegerField() position = serializers.IntegerField()
disc_number = serializers.IntegerField() disc_number = serializers.IntegerField()
downloads_count = serializers.IntegerField()
copyright = serializers.CharField() copyright = serializers.CharField()
license = serializers.SerializerMethodField() license = serializers.SerializerMethodField()
cover = cover_field cover = cover_field

Wyświetl plik

@ -213,7 +213,7 @@ def test_channel_serializer_update_podcast(factories):
def test_channel_serializer_representation(factories, to_api_date): def test_channel_serializer_representation(factories, to_api_date):
content = factories["common.Content"]() content = factories["common.Content"]()
channel = factories["audio.Channel"](artist__description=content) channel = factories["audio.Channel"](artist__description=content)
setattr(channel, "_downloads_count", 12)
expected = { expected = {
"artist": music_serializers.serialize_artist_simple(channel.artist), "artist": music_serializers.serialize_artist_simple(channel.artist),
"uuid": str(channel.uuid), "uuid": str(channel.uuid),
@ -225,6 +225,7 @@ def test_channel_serializer_representation(factories, to_api_date):
"metadata": {}, "metadata": {},
"rss_url": channel.get_rss_url(), "rss_url": channel.get_rss_url(),
"url": channel.actor.url, "url": channel.actor.url,
"downloads_count": 12,
} }
expected["artist"]["description"] = common_serializers.ContentSerializer( expected["artist"]["description"] = common_serializers.ContentSerializer(
content content
@ -248,6 +249,7 @@ def test_channel_serializer_external_representation(factories, to_api_date):
"metadata": {}, "metadata": {},
"rss_url": channel.get_rss_url(), "rss_url": channel.get_rss_url(),
"url": channel.actor.url, "url": channel.actor.url,
"downloads_count": None,
} }
expected["artist"]["description"] = common_serializers.ContentSerializer( expected["artist"]["description"] = common_serializers.ContentSerializer(
content content

Wyświetl plik

@ -234,6 +234,7 @@ def test_track_serializer(factories, to_api_date):
"tags": [], "tags": [],
"attributed_to": federation_serializers.APIActorSerializer(actor).data, "attributed_to": federation_serializers.APIActorSerializer(actor).data,
"cover": common_serializers.AttachmentSerializer(track.attachment_cover).data, "cover": common_serializers.AttachmentSerializer(track.attachment_cover).data,
"downloads_count": track.downloads_count,
} }
serializer = serializers.TrackSerializer(track) serializer = serializers.TrackSerializer(track)
assert serializer.data == expected assert serializer.data == expected

Wyświetl plik

@ -0,0 +1 @@
Display channel and track downloads count (#1178)

Wyświetl plik

@ -48,6 +48,14 @@
<translate v-else translate-context="*/*/*">N/A</translate> <translate v-else translate-context="*/*/*">N/A</translate>
</td> </td>
</tr> </tr>
<tr>
<td>
<translate translate-context="Content/*/*">Downloads</translate>
</td>
<td class="right aligned">
{{ track.downloads_count }}
</td>
</tr>
</tbody> </tbody>
</table> </table>

Wyświetl plik

@ -28,7 +28,8 @@
<translate key="2" v-else translate-context="*/*/*" :translate-params="{count: totalTracks}" :translate-n="totalTracks" translate-plural="%{ count } tracks">%{ count } track</translate> <translate key="2" v-else translate-context="*/*/*" :translate-params="{count: totalTracks}" :translate-n="totalTracks" translate-plural="%{ count } tracks">%{ count } track</translate>
</template> </template>
<template v-if="object.attributed_to.full_username === $store.state.auth.fullUsername || $store.getters['channels/isSubscribed'](object.uuid)"> <template v-if="object.attributed_to.full_username === $store.state.auth.fullUsername || $store.getters['channels/isSubscribed'](object.uuid)">
· <translate translate-context="Content/Channel/Paragraph" translate-plural="%{ count } subscribers" :translate-n="object.subscriptions_count" :translate-params="{count: object.subscriptions_count}">%{ count } subscriber</translate> <br><translate translate-context="Content/Channel/Paragraph" translate-plural="%{ count } subscribers" :translate-n="object.subscriptions_count" :translate-params="{count: object.subscriptions_count}">%{ count } subscriber</translate>
<br><translate translate-context="Content/Channel/Paragraph" translate-plural="%{ count } listenings" :translate-n="object.downloads_count" :translate-params="{count: object.downloads_count}">%{ count } listening</translate>
</template> </template>
<div class="ui hidden small divider"></div> <div class="ui hidden small divider"></div>
<a @click.stop.prevent="showSubscribeModal = true" class="ui icon small basic button"> <a @click.stop.prevent="showSubscribeModal = true" class="ui icon small basic button">