Merge branch '114-exclude-empty-albums' into 'develop'

Fix #114: can now filter artists and albums with no listenable tracks

Closes #114

See merge request funkwhale/funkwhale!83
merge-requests/154/head
Eliot Berriot 2018-03-07 22:19:21 +00:00
commit c70ab72bc0
6 zmienionych plików z 84 dodań i 4 usunięć

Wyświetl plik

@ -1,12 +1,36 @@
import django_filters
from django.db.models import Count
from django_filters import rest_framework as filters
from . import models
class ArtistFilter(django_filters.FilterSet):
class ListenableMixin(filters.FilterSet):
listenable = filters.BooleanFilter(name='_', method='filter_listenable')
def filter_listenable(self, queryset, name, value):
queryset = queryset.annotate(
files_count=Count('tracks__files')
)
if value:
return queryset.filter(files_count__gt=0)
else:
return queryset.filter(files_count=0)
class ArtistFilter(ListenableMixin):
class Meta:
model = models.Artist
fields = {
'name': ['exact', 'iexact', 'startswith', 'icontains']
'name': ['exact', 'iexact', 'startswith', 'icontains'],
'listenable': 'exact',
}
class AlbumFilter(ListenableMixin):
listenable = filters.BooleanFilter(name='_', method='filter_listenable')
class Meta:
model = models.Album
fields = ['listenable']

Wyświetl plik

@ -54,6 +54,7 @@ class TagViewSetMixin(object):
queryset = queryset.filter(tags__pk=tag)
return queryset
class ArtistViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet):
queryset = (
models.Artist.objects.all()
@ -67,6 +68,7 @@ class ArtistViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet):
filter_class = filters.ArtistFilter
ordering_fields = ('id', 'name', 'creation_date')
class AlbumViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet):
queryset = (
models.Album.objects.all()
@ -78,6 +80,7 @@ class AlbumViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet):
permission_classes = [ConditionalAuthentication]
search_fields = ['title__unaccent']
ordering_fields = ('creation_date',)
filter_class = filters.AlbumFilter
class ImportBatchViewSet(

Wyświetl plik

@ -4,6 +4,7 @@ import pytest
from django.core.cache import cache as django_cache
from dynamic_preferences.registries import global_preferences_registry
from rest_framework.test import APIClient
from rest_framework.test import APIRequestFactory
from funkwhale_api.activity import record
from funkwhale_api.taskapp import celery
@ -84,6 +85,11 @@ def superuser_client(db, factories, client):
delattr(client, 'user')
@pytest.fixture
def api_request():
return APIRequestFactory()
@pytest.fixture
def activity_registry():
r = record.registry

Wyświetl plik

@ -0,0 +1,45 @@
import pytest
from funkwhale_api.music import views
@pytest.mark.parametrize('param,expected', [
('true', 'full'),
('false', 'empty'),
])
def test_artist_view_filter_listenable(
param, expected, factories, api_request):
artists = {
'empty': factories['music.Artist'](),
'full': factories['music.TrackFile']().track.artist,
}
request = api_request.get('/', {'listenable': param})
view = views.ArtistViewSet()
view.action_map = {'get': 'list'}
expected = [artists[expected]]
view.request = view.initialize_request(request)
queryset = view.filter_queryset(view.get_queryset())
assert list(queryset) == expected
@pytest.mark.parametrize('param,expected', [
('true', 'full'),
('false', 'empty'),
])
def test_album_view_filter_listenable(
param, expected, factories, api_request):
artists = {
'empty': factories['music.Album'](),
'full': factories['music.TrackFile']().track.album,
}
request = api_request.get('/', {'listenable': param})
view = views.AlbumViewSet()
view.action_map = {'get': 'list'}
expected = [artists[expected]]
view.request = view.initialize_request(request)
queryset = view.filter_queryset(view.get_queryset())
assert list(queryset) == expected

Wyświetl plik

@ -0,0 +1 @@
Can now filter artists and albums with no listenable tracks (#114)

Wyświetl plik

@ -129,7 +129,8 @@ export default {
page: this.page,
page_size: this.paginateBy,
name__icontains: this.query,
ordering: this.getOrderingAsString()
ordering: this.getOrderingAsString(),
listenable: 'true'
}
logger.default.debug('Fetching artists')
axios.get(url, {params: params}).then((response) => {