API refinements for activity stream

merge-requests/154/head
Eliot Berriot 2018-03-01 23:41:51 +01:00
rodzic d509c090d3
commit a6da10be41
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: DD6965E2476E5C27
12 zmienionych plików z 188 dodań i 12 usunięć

Wyświetl plik

@ -3,6 +3,7 @@ from rest_framework import serializers
class ModelSerializer(serializers.ModelSerializer):
id = serializers.CharField(source='get_activity_url')
local_id = serializers.IntegerField(source='id')
# url = serializers.SerializerMethodField()
def get_url(self, obj):

Wyświetl plik

@ -4,17 +4,15 @@ from rest_framework import serializers
from funkwhale_api.activity import serializers as activity_serializers
from funkwhale_api.music.serializers import TrackSerializerNested
from funkwhale_api.music.serializers import TrackActivitySerializer
from funkwhale_api.users.serializers import UserActivitySerializer
from . import models
class TrackFavoriteActivitySerializer(activity_serializers.ModelSerializer):
type = serializers.SerializerMethodField()
object = serializers.CharField(source='track.get_activity_url')
object = TrackActivitySerializer(source='track')
actor = UserActivitySerializer(source='user')
published = serializers.DateTimeField(source='creation_date')
@ -22,6 +20,7 @@ class TrackFavoriteActivitySerializer(activity_serializers.ModelSerializer):
model = models.TrackFavorite
fields = [
'id',
'local_id',
'object',
'type',
'actor',
@ -34,9 +33,6 @@ class TrackFavoriteActivitySerializer(activity_serializers.ModelSerializer):
def get_type(self, obj):
return 'Like'
def get_object(self, obj):
return obj.track.get_activity_url()
class UserTrackFavoriteSerializer(serializers.ModelSerializer):
# track = TrackSerializerNested(read_only=True)

Wyświetl plik

@ -0,0 +1,19 @@
from funkwhale_api.common import channels
from funkwhale_api.activity import record
from . import serializers
record.registry.register_serializer(
serializers.ListeningActivitySerializer)
@record.registry.register_consumer('history.Listening')
def broadcast_listening_to_instance_activity(data, obj):
if obj.user.privacy_level not in ['instance', 'everyone']:
return
channels.group_send('instance_activity', {
'type': 'event.send',
'text': '',
'data': data
})

Wyświetl plik

@ -25,3 +25,8 @@ class Listening(models.Model):
raise ValidationError('Cannot have both session_key and user empty for listening')
super().save(**kwargs)
def get_activity_url(self):
return '{}/listenings/tracks/{}'.format(
self.user.get_activity_url(), self.pk)

Wyświetl plik

@ -1,9 +1,37 @@
from rest_framework import serializers
from funkwhale_api.activity import serializers as activity_serializers
from funkwhale_api.music.serializers import TrackSerializerNested
from funkwhale_api.music.serializers import TrackActivitySerializer
from funkwhale_api.users.serializers import UserActivitySerializer
from . import models
class ListeningActivitySerializer(activity_serializers.ModelSerializer):
type = serializers.SerializerMethodField()
object = TrackActivitySerializer(source='track')
actor = UserActivitySerializer(source='user')
published = serializers.DateTimeField(source='end_date')
class Meta:
model = models.Listening
fields = [
'id',
'local_id',
'object',
'type',
'actor',
'published'
]
def get_actor(self, obj):
return UserActivitySerializer(obj.user).data
def get_type(self, obj):
return 'Listen'
class ListeningSerializer(serializers.ModelSerializer):
class Meta:

Wyświetl plik

@ -3,8 +3,9 @@ from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import detail_route
from funkwhale_api.music.serializers import TrackSerializerNested
from funkwhale_api.activity import record
from funkwhale_api.common.permissions import ConditionalAuthentication
from funkwhale_api.music.serializers import TrackSerializerNested
from . import models
from . import serializers
@ -17,6 +18,12 @@ class ListeningViewSet(mixins.CreateModelMixin,
queryset = models.Listening.objects.all()
permission_classes = [ConditionalAuthentication]
def perform_create(self, serializer):
r = super().perform_create(serializer)
if self.request.user.is_authenticated:
record.send(serializer.instance)
return r
def get_queryset(self):
queryset = super().get_queryset()
if self.request.user.is_authenticated:

Wyświetl plik

@ -1,6 +1,8 @@
from rest_framework import serializers
from taggit.models import Tag
from funkwhale_api.activity import serializers as activity_serializers
from . import models
@ -127,3 +129,24 @@ class ImportBatchSerializer(serializers.ModelSerializer):
model = models.ImportBatch
fields = ('id', 'jobs', 'status', 'creation_date', 'import_request')
read_only_fields = ('creation_date',)
class TrackActivitySerializer(activity_serializers.ModelSerializer):
type = serializers.SerializerMethodField()
name = serializers.CharField(source='title')
artist = serializers.CharField(source='artist.name')
album = serializers.CharField(source='album.title')
class Meta:
model = models.Track
fields = [
'id',
'local_id',
'name',
'type',
'artist',
'album',
]
def get_type(self, obj):
return 'Audio'

Wyświetl plik

@ -8,11 +8,13 @@ from . import models
class UserActivitySerializer(activity_serializers.ModelSerializer):
type = serializers.SerializerMethodField()
name = serializers.CharField(source='username')
local_id = serializers.CharField(source='username')
class Meta:
model = models.User
fields = [
'id',
'local_id',
'name',
'type'
]

Wyświetl plik

@ -1,4 +1,5 @@
from funkwhale_api.users.serializers import UserActivitySerializer
from funkwhale_api.music.serializers import TrackActivitySerializer
from funkwhale_api.favorites import serializers
from funkwhale_api.favorites import activities
@ -18,9 +19,10 @@ def test_activity_favorite_serializer(factories):
field = serializers.serializers.DateTimeField()
expected = {
"type": "Like",
"local_id": favorite.pk,
"id": favorite.get_activity_url(),
"actor": actor,
"object": favorite.track.get_activity_url(),
"object": TrackActivitySerializer(favorite.track).data,
"published": field.to_representation(favorite.creation_date),
}
@ -48,7 +50,8 @@ def test_broadcast_track_favorite_to_instance_activity(
data = serializers.TrackFavoriteActivitySerializer(favorite).data
consumer = activities.broadcast_track_favorite_to_instance_activity
message = {
"type": 'event',
"type": 'event.send',
"text": '',
"data": data
}
consumer(data=data, obj=favorite)
@ -64,7 +67,8 @@ def test_broadcast_track_favorite_to_instance_activity_private(
data = serializers.TrackFavoriteActivitySerializer(favorite).data
consumer = activities.broadcast_track_favorite_to_instance_activity
message = {
"type": 'event',
"type": 'event.send',
"text": '',
"data": data
}
consumer(data=data, obj=favorite)

Wyświetl plik

@ -0,0 +1,75 @@
from funkwhale_api.users.serializers import UserActivitySerializer
from funkwhale_api.music.serializers import TrackActivitySerializer
from funkwhale_api.history import serializers
from funkwhale_api.history import activities
def test_get_listening_activity_url(settings, factories):
listening = factories['history.Listening']()
user_url = listening.user.get_activity_url()
expected = '{}/listenings/tracks/{}'.format(
user_url, listening.pk)
assert listening.get_activity_url() == expected
def test_activity_listening_serializer(factories):
listening = factories['history.Listening']()
actor = UserActivitySerializer(listening.user).data
field = serializers.serializers.DateTimeField()
expected = {
"type": "Listen",
"local_id": listening.pk,
"id": listening.get_activity_url(),
"actor": actor,
"object": TrackActivitySerializer(listening.track).data,
"published": field.to_representation(listening.end_date),
}
data = serializers.ListeningActivitySerializer(listening).data
assert data == expected
def test_track_listening_serializer_is_connected(activity_registry):
conf = activity_registry['history.Listening']
assert conf['serializer'] == serializers.ListeningActivitySerializer
def test_track_listening_serializer_instance_activity_consumer(
activity_registry):
conf = activity_registry['history.Listening']
consumer = activities.broadcast_listening_to_instance_activity
assert consumer in conf['consumers']
def test_broadcast_listening_to_instance_activity(
factories, mocker):
p = mocker.patch('funkwhale_api.common.channels.group_send')
listening = factories['history.Listening']()
data = serializers.ListeningActivitySerializer(listening).data
consumer = activities.broadcast_listening_to_instance_activity
message = {
"type": 'event.send',
"text": '',
"data": data
}
consumer(data=data, obj=listening)
p.assert_called_once_with('instance_activity', message)
def test_broadcast_listening_to_instance_activity_private(
factories, mocker):
p = mocker.patch('funkwhale_api.common.channels.group_send')
listening = factories['history.Listening'](
user__privacy_level='me'
)
data = serializers.ListeningActivitySerializer(listening).data
consumer = activities.broadcast_listening_to_instance_activity
message = {
"type": 'event.send',
"text": '',
"data": data
}
consumer(data=data, obj=listening)
p.assert_not_called()

Wyświetl plik

@ -28,7 +28,8 @@ def test_anonymous_user_can_create_listening_via_api(client, factories, settings
assert listening.session_key == client.session.session_key
def test_logged_in_user_can_create_listening_via_api(logged_in_client, factories):
def test_logged_in_user_can_create_listening_via_api(
logged_in_client, factories, activity_muted):
track = factories['music.Track']()
url = reverse('api:v1:history:listenings-list')
@ -40,3 +41,17 @@ def test_logged_in_user_can_create_listening_via_api(logged_in_client, factories
assert listening.track == track
assert listening.user == logged_in_client.user
def test_adding_listening_calls_activity_record(
factories, logged_in_client, activity_muted):
track = factories['music.Track']()
url = reverse('api:v1:history:listenings-list')
response = logged_in_client.post(url, {
'track': track.pk,
})
listening = models.Listening.objects.latest('id')
activity_muted.assert_called_once_with(listening)

Wyświetl plik

@ -13,6 +13,7 @@ def test_activity_user_serializer(factories):
expected = {
"type": "Person",
"id": user.get_activity_url(),
"local_id": user.username,
"name": user.username,
}