Skip to content
Snippets Groups Projects
Verified Commit 57bf43bb authored by Eliot Berriot's avatar Eliot Berriot
Browse files

API Endpoint to list lirary tracks

parent bdf93479
No related branches found
No related tags found
No related merge requests found
......@@ -7,5 +7,9 @@ router.register(
r'libraries',
views.LibraryViewSet,
'libraries')
router.register(
r'library-tracks',
views.LibraryTrackViewSet,
'library-tracks')
urlpatterns = router.urls
......@@ -17,6 +17,20 @@ class LibraryFilter(django_filters.FilterSet):
}
class LibraryTrackFilter(django_filters.FilterSet):
library = django_filters.CharFilter('library__uuid')
class Meta:
model = models.LibraryTrack
fields = {
'library': ['exact'],
'artist_name': ['exact', 'icontains'],
'title': ['exact', 'icontains'],
'album_title': ['exact', 'icontains'],
'audio_mimetype': ['exact', 'icontains'],
}
class FollowFilter(django_filters.FilterSet):
ordering = django_filters.OrderingFilter(
# tuple-mapping retains order
......
......@@ -253,6 +253,29 @@ class APILibraryCreateSerializer(serializers.ModelSerializer):
return library
class APILibraryTrackSerializer(serializers.ModelSerializer):
library = APILibrarySerializer()
class Meta:
model = models.LibraryTrack
fields = [
'id',
'url',
'audio_url',
'audio_mimetype',
'creation_date',
'modification_date',
'fetched_date',
'published_date',
'metadata',
'artist_name',
'album_title',
'title',
'library',
'local_track_file',
]
class FollowSerializer(serializers.Serializer):
id = serializers.URLField()
object = serializers.URLField()
......
......@@ -2,6 +2,7 @@ import json
import logging
from django.conf import settings
from django.utils import timezone
from requests.exceptions import RequestException
......@@ -58,6 +59,9 @@ def scan_library(library, until=None):
data = lb.get_library_data(library.url)
scan_library_page.delay(
library_id=library.id, page_url=data['first'], until=until)
library.fetched_date = timezone.now()
library.tracks_count = data['totalItems']
library.save(update_fields=['fetched_date', 'tracks_count'])
@celery.app.task(
......
......@@ -14,6 +14,7 @@ from rest_framework.decorators import list_route, detail_route
from rest_framework.serializers import ValidationError
from funkwhale_api.common import utils as funkwhale_utils
from funkwhale_api.common.permissions import HasModelPermission
from funkwhale_api.music.models import TrackFile
from . import activity
......@@ -166,12 +167,16 @@ class MusicFilesViewSet(FederationMixin, viewsets.GenericViewSet):
return response.Response(data)
class LibraryPermission(HasModelPermission):
model = models.Library
class LibraryViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
permission_classes = [rest_permissions.DjangoModelPermissions]
permission_classes = [LibraryPermission]
queryset = models.Library.objects.all().select_related(
'actor',
'follow',
......@@ -184,6 +189,7 @@ class LibraryViewSet(
'creation_date',
'fetched_date',
'actor__domain',
'tracks_count',
)
@list_route(methods=['get'])
......@@ -203,11 +209,11 @@ class LibraryViewSet(
data=request.data
)
serializer.is_valid(raise_exception=True)
id = tasks.scan_library.delay(
result = tasks.scan_library.delay(
library_id=library.pk,
until=serializer.validated_data['until']
until=serializer.validated_data.get('until')
)
return response.Response({'task': id})
return response.Response({'task': result.id})
@list_route(methods=['get'])
def following(self, request, *args, **kwargs):
......@@ -249,3 +255,26 @@ class LibraryViewSet(
serializer.is_valid(raise_exception=True)
library = serializer.save()
return response.Response(serializer.data, status=201)
class LibraryTrackViewSet(
mixins.ListModelMixin,
viewsets.GenericViewSet):
permission_classes = [LibraryPermission]
queryset = models.LibraryTrack.objects.all().select_related(
'library__actor',
'library__follow',
'local_track_file',
)
filter_class = filters.LibraryTrackFilter
serializer_class = serializers.APILibraryTrackSerializer
ordering_fields = (
'id',
'artist_name',
'title',
'album_title',
'creation_date',
'modification_date',
'fetched_date',
'published_date',
)
from django.core.paginator import Paginator
from django.utils import timezone
from funkwhale_api.federation import serializers
from funkwhale_api.federation import tasks
......@@ -21,6 +22,7 @@ def test_scan_library_page_does_nothing_if_federation_disabled(
def test_scan_library_fetches_page_and_calls_scan_page(
mocker, factories, r_mock):
now = timezone.now()
library = factories['federation.Library'](federation_enabled=True)
collection_conf = {
'actor': library.actor,
......@@ -39,6 +41,8 @@ def test_scan_library_fetches_page_and_calls_scan_page(
page_url=collection.data['first'],
until=None,
)
library.refresh_from_db()
assert library.fetched_date > now
def test_scan_page_fetches_page_and_creates_tracks(
......
......@@ -312,7 +312,7 @@ def test_can_patch_library(factories, superuser_api_client):
def test_scan_library(factories, mocker, superuser_api_client):
scan = mocker.patch(
'funkwhale_api.federation.tasks.scan_library.delay',
return_value='id')
return_value=mocker.Mock(id='id'))
library = factories['federation.Library']()
now = timezone.now()
data = {
......@@ -329,3 +329,20 @@ def test_scan_library(factories, mocker, superuser_api_client):
library_id=library.pk,
until=now
)
def test_list_library_tracks(factories, superuser_api_client):
library = factories['federation.Library']()
lts = list(reversed(factories['federation.LibraryTrack'].create_batch(
size=5, library=library)))
factories['federation.LibraryTrack'].create_batch(size=5)
url = reverse('api:v1:federation:library-tracks-list')
response = superuser_api_client.get(url, {'library': library.uuid})
assert response.status_code == 200
assert response.data == {
'results': serializers.APILibraryTrackSerializer(lts, many=True).data,
'count': 5,
'previous': None,
'next': None,
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment