From e82a53da3570128d493d85c13762dd8493f7a975 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 10 Apr 2018 23:17:51 +0200 Subject: [PATCH] Added API endpoints to list library followees and followers --- api/funkwhale_api/federation/filters.py | 19 +++++++++++ api/funkwhale_api/federation/serializers.py | 19 +++++++++++ api/funkwhale_api/federation/views.py | 35 +++++++++++++++++++++ api/tests/federation/test_views.py | 28 +++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 api/funkwhale_api/federation/filters.py diff --git a/api/funkwhale_api/federation/filters.py b/api/funkwhale_api/federation/filters.py new file mode 100644 index 00000000..a43c2dc0 --- /dev/null +++ b/api/funkwhale_api/federation/filters.py @@ -0,0 +1,19 @@ +import django_filters + +from . import models + + +class FollowFilter(django_filters.FilterSet): + ordering = django_filters.OrderingFilter( + # tuple-mapping retains order + fields=( + ('creation_date', 'creation_date'), + ('modification_date', 'modification_date'), + ), + ) + + class Meta: + model = models.Follow + fields = { + 'approved': ['exact'], + } diff --git a/api/funkwhale_api/federation/serializers.py b/api/funkwhale_api/federation/serializers.py index 68eef135..0fe52e1f 100644 --- a/api/funkwhale_api/federation/serializers.py +++ b/api/funkwhale_api/federation/serializers.py @@ -96,6 +96,22 @@ class ActorSerializer(serializers.ModelSerializer): return value[:500] +class APIActorSerializer(serializers.ModelSerializer): + class Meta: + model = models.Actor + fields = [ + 'id', + 'url', + 'creation_date', + 'summary', + 'preferred_username', + 'name', + 'last_fetch_date', + 'domain', + 'type', + 'manually_approves_followers', + + ] class LibraryActorSerializer(ActorSerializer): url = serializers.ListField( child=serializers.JSONField()) @@ -224,6 +240,9 @@ class FollowSerializer(serializers.Serializer): class APIFollowSerializer(serializers.ModelSerializer): + actor = APIActorSerializer() + target = APIActorSerializer() + class Meta: model = models.Follow fields = [ diff --git a/api/funkwhale_api/federation/views.py b/api/funkwhale_api/federation/views.py index 623fd574..5b11942f 100644 --- a/api/funkwhale_api/federation/views.py +++ b/api/funkwhale_api/federation/views.py @@ -18,6 +18,7 @@ from funkwhale_api.music.models import TrackFile from . import activity from . import actors from . import authentication +from . import filters from . import library from . import models from . import permissions @@ -177,6 +178,40 @@ class LibraryViewSet(viewsets.GenericViewSet): data = library.scan_from_account_name(account) return response.Response(data) + @list_route(methods=['get']) + def following(self, request, *args, **kwargs): + library_actor = actors.SYSTEM_ACTORS['library'].get_actor_instance() + queryset = models.Follow.objects.filter( + actor=library_actor + ).select_related( + 'target', + 'target', + ).order_by('-creation_date') + filterset = filters.FollowFilter(request.GET, queryset=queryset) + serializer = serializers.APIFollowSerializer(filterset.qs, many=True) + data = { + 'results': serializer.data, + 'count': len(filterset.qs), + } + return response.Response(data) + + @list_route(methods=['get']) + def followers(self, request, *args, **kwargs): + library_actor = actors.SYSTEM_ACTORS['library'].get_actor_instance() + queryset = models.Follow.objects.filter( + target=library_actor + ).select_related( + 'target', + 'target', + ).order_by('-creation_date') + filterset = filters.FollowFilter(request.GET, queryset=queryset) + serializer = serializers.APIFollowSerializer(filterset.qs, many=True) + data = { + 'results': serializer.data, + 'count': len(filterset.qs), + } + return response.Response(data) + @transaction.atomic def create(self, request, *args, **kwargs): serializer = serializers.APILibraryCreateSerializer(data=request.data) diff --git a/api/tests/federation/test_views.py b/api/tests/federation/test_views.py index 99d42566..3bc9fa88 100644 --- a/api/tests/federation/test_views.py +++ b/api/tests/federation/test_views.py @@ -233,3 +233,31 @@ def test_follow_library(superuser_api_client, mocker, factories, r_mock): on_behalf_of=library_actor, to=[actor.url] ) + + +def test_can_list_system_actor_following(factories, superuser_api_client): + library_actor = actors.SYSTEM_ACTORS['library'].get_actor_instance() + follow1 = factories['federation.Follow'](actor=library_actor) + follow2 = factories['federation.Follow']() + + url = reverse('api:v1:federation:libraries-following') + response = superuser_api_client.get(url) + + assert response.status_code == 200 + assert response.data['results'] == [ + serializers.APIFollowSerializer(follow1).data + ] + + +def test_can_list_system_actor_followers(factories, superuser_api_client): + library_actor = actors.SYSTEM_ACTORS['library'].get_actor_instance() + follow1 = factories['federation.Follow'](actor=library_actor) + follow2 = factories['federation.Follow'](target=library_actor) + + url = reverse('api:v1:federation:libraries-followers') + response = superuser_api_client.get(url) + + assert response.status_code == 200 + assert response.data['results'] == [ + serializers.APIFollowSerializer(follow2).data + ] -- GitLab