funkwhale/api/funkwhale_api/playlists/views.py

133 wiersze
4.6 KiB
Python
Czysty Zwykły widok Historia

from django.db import transaction
2018-06-10 08:55:16 +00:00
from django.db.models import Count
from rest_framework import exceptions, mixins, viewsets
2019-01-11 12:33:35 +00:00
from rest_framework.decorators import action
2018-06-10 08:55:16 +00:00
from rest_framework.response import Response
2018-06-10 08:55:16 +00:00
from funkwhale_api.common import fields, permissions
2018-09-28 14:45:28 +00:00
from funkwhale_api.music import utils as music_utils
from funkwhale_api.users.oauth import permissions as oauth_permissions
2018-06-10 08:55:16 +00:00
from . import filters, models, serializers
2018-06-09 13:36:16 +00:00
class PlaylistViewSet(
2018-06-09 13:36:16 +00:00
mixins.RetrieveModelMixin,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet,
):
serializer_class = serializers.PlaylistSerializer
queryset = (
2018-06-09 13:36:16 +00:00
models.Playlist.objects.all()
2020-01-23 15:38:04 +00:00
.select_related("user__actor__attachment_icon")
.annotate(tracks_count=Count("playlist_tracks", distinct=True))
2018-07-17 11:09:13 +00:00
.with_covers()
.with_duration()
)
permission_classes = [
oauth_permissions.ScopePermission,
permissions.OwnerPermission,
]
required_scope = "playlists"
anonymous_policy = "setting"
2018-06-09 13:36:16 +00:00
owner_checks = ["write"]
filterset_class = filters.PlaylistFilter
2018-06-09 13:36:16 +00:00
ordering_fields = ("id", "name", "creation_date", "modification_date")
2019-01-11 12:33:35 +00:00
@action(methods=["get"], detail=True)
def tracks(self, request, *args, **kwargs):
playlist = self.get_object()
plts = playlist.playlist_tracks.all().for_nested_serialization(
music_utils.get_actor_from_request(request)
)
serializer = serializers.PlaylistTrackSerializer(plts, many=True)
2018-06-09 13:36:16 +00:00
data = {"count": len(plts), "results": serializer.data}
return Response(data, status=200)
2019-01-11 12:33:35 +00:00
@action(methods=["post"], detail=True)
@transaction.atomic
def add(self, request, *args, **kwargs):
playlist = self.get_object()
serializer = serializers.PlaylistAddManySerializer(data=request.data)
serializer.is_valid(raise_exception=True)
try:
plts = playlist.insert_many(
serializer.validated_data["tracks"],
serializer.validated_data["allow_duplicates"],
)
except exceptions.ValidationError as e:
2018-06-09 13:36:16 +00:00
payload = {"playlist": e.detail}
return Response(payload, status=400)
ids = [p.id for p in plts]
2018-06-09 13:36:16 +00:00
plts = (
models.PlaylistTrack.objects.filter(pk__in=ids)
.order_by("index")
.for_nested_serialization(music_utils.get_actor_from_request(request))
2018-06-09 13:36:16 +00:00
)
serializer = serializers.PlaylistTrackSerializer(plts, many=True)
2018-06-09 13:36:16 +00:00
data = {"count": len(plts), "results": serializer.data}
return Response(data, status=201)
2019-01-11 12:33:35 +00:00
@action(methods=["delete"], detail=True)
2018-03-21 11:19:07 +00:00
@transaction.atomic
def clear(self, request, *args, **kwargs):
playlist = self.get_object()
playlist.playlist_tracks.all().delete()
2018-06-09 13:36:16 +00:00
playlist.save(update_fields=["modification_date"])
2018-03-21 11:19:07 +00:00
return Response(status=204)
def get_queryset(self):
2018-09-28 14:45:28 +00:00
return self.queryset.filter(
fields.privacy_level_query(self.request.user)
).with_playable_plts(music_utils.get_actor_from_request(self.request))
def perform_create(self, serializer):
return serializer.save(
user=self.request.user,
privacy_level=serializer.validated_data.get(
2018-06-09 13:36:16 +00:00
"privacy_level", self.request.user.privacy_level
),
)
class PlaylistTrackViewSet(
2018-06-09 13:36:16 +00:00
mixins.RetrieveModelMixin,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet,
):
serializer_class = serializers.PlaylistTrackSerializer
queryset = models.PlaylistTrack.objects.all()
permission_classes = [
oauth_permissions.ScopePermission,
permissions.OwnerPermission,
]
required_scope = "playlists"
anonymous_policy = "setting"
2018-06-09 13:36:16 +00:00
owner_field = "playlist.user"
owner_checks = ["write"]
def get_serializer_class(self):
2018-06-09 13:36:16 +00:00
if self.request.method in ["PUT", "PATCH", "DELETE", "POST"]:
return serializers.PlaylistTrackWriteSerializer
return self.serializer_class
def get_queryset(self):
return self.queryset.filter(
fields.privacy_level_query(
self.request.user,
lookup_field="playlist__privacy_level",
user_field="playlist__user",
2018-06-09 13:36:16 +00:00
)
).for_nested_serialization(music_utils.get_actor_from_request(self.request))
def perform_destroy(self, instance):
instance.delete(update_indexes=True)