See #432: API endpoint to query tags
This commit is contained in:
parent
e11c1dfe29
commit
9f3076f4db
|
@ -10,11 +10,12 @@ from funkwhale_api.common import routers as common_routers
|
|||
from funkwhale_api.music import views
|
||||
from funkwhale_api.playlists import views as playlists_views
|
||||
from funkwhale_api.subsonic.views import SubsonicViewSet
|
||||
from funkwhale_api.tags import views as tags_views
|
||||
|
||||
router = common_routers.OptionalSlashRouter()
|
||||
router.register(r"settings", GlobalPreferencesViewSet, basename="settings")
|
||||
router.register(r"activity", activity_views.ActivityViewSet, "activity")
|
||||
router.register(r"tags", views.TagViewSet, "tags")
|
||||
router.register(r"tags", tags_views.TagViewSet, "tags")
|
||||
router.register(r"tracks", views.TrackViewSet, "tracks")
|
||||
router.register(r"uploads", views.UploadViewSet, "uploads")
|
||||
router.register(r"libraries", views.LibraryViewSet, "libraries")
|
||||
|
|
|
@ -447,14 +447,6 @@ class UploadViewSet(
|
|||
instance.delete()
|
||||
|
||||
|
||||
class TagViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
queryset = Tag.objects.all().order_by("name")
|
||||
serializer_class = serializers.TagSerializer
|
||||
permission_classes = [oauth_permissions.ScopePermission]
|
||||
required_scope = "libraries"
|
||||
anonymous_policy = "setting"
|
||||
|
||||
|
||||
class Search(views.APIView):
|
||||
max_results = 3
|
||||
permission_classes = [oauth_permissions.ScopePermission]
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import django_filters
|
||||
from django_filters import rest_framework as filters
|
||||
|
||||
from funkwhale_api.common import fields
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
class TagFilter(filters.FilterSet):
|
||||
q = fields.SearchFilter(search_fields=["name"])
|
||||
ordering = django_filters.OrderingFilter(
|
||||
fields=(
|
||||
("name", "name"),
|
||||
("creation_date", "creation_date"),
|
||||
("__size", "length"),
|
||||
)
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = models.Tag
|
||||
fields = ["q"]
|
|
@ -0,0 +1,9 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
class TagSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.Tag
|
||||
fields = ["name", "creation_date"]
|
|
@ -0,0 +1,22 @@
|
|||
from django.db.models import functions
|
||||
from rest_framework import viewsets
|
||||
|
||||
from funkwhale_api.users.oauth import permissions as oauth_permissions
|
||||
|
||||
from . import filters
|
||||
from . import models
|
||||
from . import serializers
|
||||
|
||||
|
||||
class TagViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
lookup_field = "name"
|
||||
queryset = (
|
||||
models.Tag.objects.all()
|
||||
.annotate(__size=functions.Length("name"))
|
||||
.order_by("name")
|
||||
)
|
||||
serializer_class = serializers.TagSerializer
|
||||
permission_classes = [oauth_permissions.ScopePermission]
|
||||
required_scope = "libraries"
|
||||
anonymous_policy = "setting"
|
||||
filterset_class = filters.TagFilter
|
|
@ -0,0 +1,16 @@
|
|||
from funkwhale_api.tags import filters
|
||||
from funkwhale_api.tags import models
|
||||
|
||||
|
||||
def test_filter_search_tag(factories, queryset_equal_list):
|
||||
matches = [
|
||||
factories["tags.Tag"](name="Tag1"),
|
||||
factories["tags.Tag"](name="TestTag1"),
|
||||
factories["tags.Tag"](name="TestTag12"),
|
||||
]
|
||||
factories["tags.Tag"](name="TestTag")
|
||||
factories["tags.Tag"](name="TestTag2")
|
||||
qs = models.Tag.objects.all().order_by("name")
|
||||
filterset = filters.TagFilter({"q": "tag1"}, queryset=qs)
|
||||
|
||||
assert filterset.qs == matches
|
|
@ -0,0 +1,14 @@
|
|||
from funkwhale_api.tags import serializers
|
||||
|
||||
|
||||
def test_tag_serializer(factories):
|
||||
tag = factories["tags.Tag"]()
|
||||
|
||||
serializer = serializers.TagSerializer(tag)
|
||||
|
||||
expected = {
|
||||
"name": tag.name,
|
||||
"creation_date": tag.creation_date.isoformat().split("+")[0] + "Z",
|
||||
}
|
||||
|
||||
assert serializer.data == expected
|
|
@ -0,0 +1,50 @@
|
|||
from django.urls import reverse
|
||||
|
||||
from funkwhale_api.tags import serializers
|
||||
|
||||
|
||||
def test_tags_list(factories, logged_in_api_client):
|
||||
url = reverse("api:v1:tags-list")
|
||||
tag = factories["tags.Tag"]()
|
||||
|
||||
expected = {
|
||||
"count": 1,
|
||||
"next": None,
|
||||
"previous": None,
|
||||
"results": [serializers.TagSerializer(tag).data],
|
||||
}
|
||||
|
||||
response = logged_in_api_client.get(url)
|
||||
|
||||
assert response.data == expected
|
||||
|
||||
|
||||
def test_tags_list_ordering_length(factories, logged_in_api_client):
|
||||
url = reverse("api:v1:tags-list")
|
||||
tags = [
|
||||
factories["tags.Tag"](name="iamareallylongtag"),
|
||||
factories["tags.Tag"](name="reallylongtag"),
|
||||
factories["tags.Tag"](name="short"),
|
||||
factories["tags.Tag"](name="bar"),
|
||||
]
|
||||
expected = {
|
||||
"count": 4,
|
||||
"next": None,
|
||||
"previous": None,
|
||||
"results": [serializers.TagSerializer(tag).data for tag in tags],
|
||||
}
|
||||
|
||||
response = logged_in_api_client.get(url, {"ordering": "-length"})
|
||||
|
||||
assert response.data == expected
|
||||
|
||||
|
||||
def test_tags_detail(factories, logged_in_api_client):
|
||||
tag = factories["tags.Tag"]()
|
||||
url = reverse("api:v1:tags-detail", kwargs={"name": tag.name})
|
||||
|
||||
expected = serializers.TagSerializer(tag).data
|
||||
|
||||
response = logged_in_api_client.get(url)
|
||||
|
||||
assert response.data == expected
|
|
@ -35,6 +35,7 @@ from funkwhale_api.users.oauth import scopes
|
|||
"get",
|
||||
),
|
||||
("api:v1:federation:library-follows-list", {}, "read:follows", "get"),
|
||||
("api:v1:tags-list", {}, "read:libraries", "get"),
|
||||
# admin / privileged stuff
|
||||
("api:v1:instance:admin-settings-list", {}, "read:instance:settings", "get"),
|
||||
(
|
||||
|
|
Loading…
Reference in New Issue