kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
Fx #1178: Display channel and track downloads count
rodzic
75f9537d89
commit
e9186ca813
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Display channel and track downloads count (#1178)
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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">
|
||||||
|
|
Ładowanie…
Reference in New Issue