From a8baf8fa67ba28c50f4c0542bc3612a6256d1a4b Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Tue, 22 May 2018 22:22:53 +0200 Subject: [PATCH] See #224: updated front-end with new music API --- api/funkwhale_api/music/filters.py | 34 ++++++++++++++++++- api/funkwhale_api/music/models.py | 7 ++-- api/funkwhale_api/music/serializers.py | 5 ++- api/funkwhale_api/music/views.py | 33 ++++++------------ api/funkwhale_api/radios/filters.py | 4 +-- api/funkwhale_api/requests/views.py | 4 --- front/src/components/audio/PlayButton.vue | 28 +++++++++++---- front/src/components/audio/artist/Card.vue | 15 ++------ front/src/components/library/Artist.vue | 28 ++++++++------- front/src/components/library/Artists.vue | 8 ----- front/src/components/library/Home.vue | 8 ----- .../src/components/library/radios/Builder.vue | 2 +- .../src/components/library/radios/Filter.vue | 2 +- 13 files changed, 94 insertions(+), 84 deletions(-) diff --git a/api/funkwhale_api/music/filters.py b/api/funkwhale_api/music/filters.py index 6da9cca63..dc7aafc21 100644 --- a/api/funkwhale_api/music/filters.py +++ b/api/funkwhale_api/music/filters.py @@ -32,6 +32,33 @@ class ArtistFilter(ListenableMixin): } +class TrackFilter(filters.FilterSet): + q = fields.SearchFilter(search_fields=[ + 'title', + 'album__title', + 'artist__name', + ]) + listenable = filters.BooleanFilter(name='_', method='filter_listenable') + + class Meta: + model = models.Track + fields = { + 'title': ['exact', 'iexact', 'startswith', 'icontains'], + 'listenable': ['exact'], + 'artist': ['exact'], + 'album': ['exact'], + } + + def filter_listenable(self, queryset, name, value): + queryset = queryset.annotate( + files_count=Count('files') + ) + if value: + return queryset.filter(files_count__gt=0) + else: + return queryset.filter(files_count=0) + + class ImportBatchFilter(filters.FilterSet): q = fields.SearchFilter(search_fields=[ 'submitted_by__username', @@ -67,7 +94,12 @@ class ImportJobFilter(filters.FilterSet): class AlbumFilter(ListenableMixin): listenable = filters.BooleanFilter(name='_', method='filter_listenable') + q = fields.SearchFilter(search_fields=[ + 'title', + 'artist__name' + 'source', + ]) class Meta: model = models.Album - fields = ['listenable'] + fields = ['listenable', 'q', 'artist'] diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py index 51ccec905..51ece7d7b 100644 --- a/api/funkwhale_api/music/models.py +++ b/api/funkwhale_api/music/models.py @@ -319,11 +319,8 @@ class Lyrics(models.Model): class TrackQuerySet(models.QuerySet): def for_nested_serialization(self): return (self.select_related() - .select_related('album__artist') - .prefetch_related( - 'tags', - 'files', - 'artist__albums__tracks__tags')) + .select_related('album__artist', 'artist') + .prefetch_related('files')) class Track(APIModelMixin): diff --git a/api/funkwhale_api/music/serializers.py b/api/funkwhale_api/music/serializers.py index 042646927..c77983a40 100644 --- a/api/funkwhale_api/music/serializers.py +++ b/api/funkwhale_api/music/serializers.py @@ -122,7 +122,10 @@ class AlbumSerializer(serializers.ModelSerializer): ) def get_tracks(self, o): - ordered_tracks = sorted(o.tracks.all(), key=lambda v: v.position) + ordered_tracks = sorted( + o.tracks.all(), + key=lambda v: (v.position, v.title) if v.position else (99999, v.title) + ) return AlbumTrackSerializer(ordered_tracks, many=True).data diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py index 3a03a9227..24a9cbbcd 100644 --- a/api/funkwhale_api/music/views.py +++ b/api/funkwhale_api/music/views.py @@ -46,17 +46,6 @@ from . import utils logger = logging.getLogger(__name__) -class SearchMixin(object): - search_fields = [] - - @list_route(methods=['get']) - def search(self, request, *args, **kwargs): - query = utils.get_query(request.GET['query'], self.search_fields) - queryset = self.get_queryset().filter(query) - serializer = self.serializer_class(queryset, many=True) - return Response(serializer.data) - - class TagViewSetMixin(object): def get_queryset(self): @@ -67,26 +56,25 @@ class TagViewSetMixin(object): return queryset -class ArtistViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet): +class ArtistViewSet(viewsets.ReadOnlyModelViewSet): queryset = models.Artist.objects.with_albums() serializer_class = serializers.ArtistWithAlbumsSerializer permission_classes = [ConditionalAuthentication] - search_fields = ['name__unaccent'] filter_class = filters.ArtistFilter ordering_fields = ('id', 'name', 'creation_date') -class AlbumViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet): +class AlbumViewSet(viewsets.ReadOnlyModelViewSet): queryset = ( models.Album.objects.all() - .order_by('-creation_date') + .order_by('artist', 'release_date') .select_related() - .prefetch_related('tracks__tags', - 'tracks__files')) + .prefetch_related( + 'tracks__artist', + 'tracks__files')) serializer_class = serializers.AlbumSerializer permission_classes = [ConditionalAuthentication] - search_fields = ['title__unaccent'] - ordering_fields = ('creation_date',) + ordering_fields = ('creation_date', 'release_date', 'title') filter_class = filters.AlbumFilter @@ -155,19 +143,20 @@ class ImportJobViewSet( ) -class TrackViewSet( - TagViewSetMixin, SearchMixin, viewsets.ReadOnlyModelViewSet): +class TrackViewSet(TagViewSetMixin, viewsets.ReadOnlyModelViewSet): """ A simple ViewSet for viewing and editing accounts. """ queryset = (models.Track.objects.all().for_nested_serialization()) serializer_class = serializers.TrackSerializer permission_classes = [ConditionalAuthentication] - search_fields = ['title', 'artist__name'] + filter_class = filters.TrackFilter ordering_fields = ( 'creation_date', 'title__unaccent', 'album__title__unaccent', + 'album__release_date', + 'position', 'artist__name__unaccent', ) diff --git a/api/funkwhale_api/radios/filters.py b/api/funkwhale_api/radios/filters.py index 344a4dabf..d0d338d66 100644 --- a/api/funkwhale_api/radios/filters.py +++ b/api/funkwhale_api/radios/filters.py @@ -144,8 +144,8 @@ class ArtistFilter(RadioFilter): 'name': 'ids', 'type': 'list', 'subtype': 'number', - 'autocomplete': reverse_lazy('api:v1:artists-search'), - 'autocomplete_qs': 'query={query}', + 'autocomplete': reverse_lazy('api:v1:artists-list'), + 'autocomplete_qs': 'q={query}', 'autocomplete_fields': {'name': 'name', 'value': 'id'}, 'label': 'Artist', 'placeholder': 'Select artists' diff --git a/api/funkwhale_api/requests/views.py b/api/funkwhale_api/requests/views.py index 395fac66c..6553f3316 100644 --- a/api/funkwhale_api/requests/views.py +++ b/api/funkwhale_api/requests/views.py @@ -3,15 +3,12 @@ from rest_framework import status from rest_framework.response import Response from rest_framework.decorators import detail_route -from funkwhale_api.music.views import SearchMixin - from . import filters from . import models from . import serializers class ImportRequestViewSet( - SearchMixin, mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, @@ -22,7 +19,6 @@ class ImportRequestViewSet( models.ImportRequest.objects.all() .select_related() .order_by('-creation_date')) - search_fields = ['artist_name', 'album_name', 'comment'] filter_class = filters.ImportRequestFilter ordering_fields = ('id', 'artist_name', 'creation_date', 'status') diff --git a/front/src/components/audio/PlayButton.vue b/front/src/components/audio/PlayButton.vue index efa59a29d..6fc769969 100644 --- a/front/src/components/audio/PlayButton.vue +++ b/front/src/components/audio/PlayButton.vue @@ -21,7 +21,6 @@