diff --git a/api/funkwhale_api/federation/serializers.py b/api/funkwhale_api/federation/serializers.py index bca35902d..c717e679b 100644 --- a/api/funkwhale_api/federation/serializers.py +++ b/api/funkwhale_api/federation/serializers.py @@ -112,6 +112,8 @@ class APIActorSerializer(serializers.ModelSerializer): 'manually_approves_followers', ] + + class LibraryActorSerializer(ActorSerializer): url = serializers.ListField( child=serializers.JSONField()) @@ -137,33 +139,52 @@ class LibraryActorSerializer(ActorSerializer): return validated_data +class APIFollowSerializer(serializers.ModelSerializer): + class Meta: + model = models.Follow + fields = [ + 'uuid', + 'actor', + 'target', + 'approved', + 'creation_date', + 'modification_date', + ] + + class APILibrarySerializer(serializers.ModelSerializer): - actor = APIActorSerializer + actor = APIActorSerializer() + follow = APIFollowSerializer() class Meta: model = models.Library - fields = [ + + read_only_fields = [ 'actor', - 'autoimport', - 'federation_enabled', - 'download_files', - 'tracks_count', - 'url', 'uuid', - 'creation_date', + 'url', + 'tracks_count', 'follow', 'fetched_date', 'modification_date', + 'creation_date', ] + fields = [ + 'autoimport', + 'federation_enabled', + 'download_files', + ] + read_only_fields class APILibraryCreateSerializer(serializers.ModelSerializer): actor = serializers.URLField() federation_enabled = serializers.BooleanField() + uuid = serializers.UUIDField(read_only=True) class Meta: model = models.Library fields = [ + 'uuid', 'actor', 'autoimport', 'federation_enabled', diff --git a/api/funkwhale_api/federation/views.py b/api/funkwhale_api/federation/views.py index bceac4243..cac6c4163 100644 --- a/api/funkwhale_api/federation/views.py +++ b/api/funkwhale_api/federation/views.py @@ -166,6 +166,8 @@ class MusicFilesViewSet(FederationMixin, viewsets.GenericViewSet): class LibraryViewSet( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet): permission_classes = [rest_permissions.DjangoModelPermissions] @@ -173,6 +175,7 @@ class LibraryViewSet( 'actor', 'follow', ) + lookup_field = 'uuid' filter_class = filters.LibraryFilter serializer_class = serializers.APILibrarySerializer ordering_fields = ( diff --git a/api/tests/federation/test_views.py b/api/tests/federation/test_views.py index a2786be09..72feaabfd 100644 --- a/api/tests/federation/test_views.py +++ b/api/tests/federation/test_views.py @@ -275,3 +275,34 @@ def test_can_list_libraries(factories, superuser_api_client): serializers.APILibrarySerializer(library1).data, serializers.APILibrarySerializer(library2).data, ] + + +def test_can_detail_library(factories, superuser_api_client): + library = factories['federation.Library']() + + url = reverse( + 'api:v1:federation:libraries-detail', + kwargs={'uuid': str(library.uuid)}) + response = superuser_api_client.get(url) + + assert response.status_code == 200 + assert response.data == serializers.APILibrarySerializer(library).data + + +def test_can_patch_library(factories, superuser_api_client): + library = factories['federation.Library']() + data = { + 'federation_enabled': not library.federation_enabled, + 'download_files': not library.download_files, + 'autoimport': not library.autoimport, + } + url = reverse( + 'api:v1:federation:libraries-detail', + kwargs={'uuid': str(library.uuid)}) + response = superuser_api_client.patch(url, data) + + assert response.status_code == 200 + library.refresh_from_db() + + for k, v in data.items(): + assert getattr(library, k) == v diff --git a/front/src/router/index.js b/front/src/router/index.js index 0981c37f9..394a12849 100644 --- a/front/src/router/index.js +++ b/front/src/router/index.js @@ -25,7 +25,9 @@ import RequestsList from '@/components/requests/RequestsList' import PlaylistDetail from '@/views/playlists/Detail' import PlaylistList from '@/views/playlists/List' import Favorites from '@/components/favorites/List' -import Federation from '@/views/federation/Home' +import FederationBase from '@/views/federation/Base' +import FederationHome from '@/views/federation/Home' +import FederationLibraryDetail from '@/views/federation/LibraryDetail' Vue.use(Router) @@ -86,7 +88,11 @@ export default new Router({ }, { path: '/manage/federation', - component: Federation + component: FederationBase, + children: [ + { path: '', component: FederationHome }, + { path: 'library/:id', name: 'federation.libraries.detail', component: FederationLibraryDetail, props: true } + ] }, { path: '/library', diff --git a/front/src/views/federation/Base.vue b/front/src/views/federation/Base.vue new file mode 100644 index 000000000..6add8e5e4 --- /dev/null +++ b/front/src/views/federation/Base.vue @@ -0,0 +1,7 @@ + diff --git a/front/src/views/federation/Home.vue b/front/src/views/federation/Home.vue index c9e3693d6..89048aac5 100644 --- a/front/src/views/federation/Home.vue +++ b/front/src/views/federation/Home.vue @@ -1,5 +1,5 @@