Skip to content
Snippets Groups Projects
views.py 4.37 KiB
Newer Older
  • Learn to ignore specific revisions
  • from django.db.models import Q
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    from rest_framework import mixins, permissions, status, viewsets
    
    from rest_framework.decorators import detail_route, list_route
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    from rest_framework.response import Response
    
    from funkwhale_api.common import permissions as common_permissions
    
    from funkwhale_api.music.serializers import TrackSerializer
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    from . import filters, filtersets, models, serializers
    
    
    class RadioViewSet(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        mixins.CreateModelMixin,
        mixins.RetrieveModelMixin,
        mixins.UpdateModelMixin,
        mixins.ListModelMixin,
        mixins.DestroyModelMixin,
        viewsets.GenericViewSet,
    ):
    
    
        serializer_class = serializers.RadioSerializer
    
        permission_classes = [
            permissions.IsAuthenticated,
            common_permissions.OwnerPermission,
        ]
    
        filter_class = filtersets.RadioFilter
    
        owner_field = "user"
        owner_checks = ["write"]
    
    
        def get_queryset(self):
    
            queryset = models.Radio.objects.all()
    
            query = Q(is_public=True)
            if self.request.user.is_authenticated:
                query |= Q(user=self.request.user)
    
    
        def perform_create(self, serializer):
            return serializer.save(user=self.request.user)
    
        def perform_update(self, serializer):
            return serializer.save(user=self.request.user)
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        @detail_route(methods=["get"])
    
    Bat's avatar
    Bat committed
        def tracks(self, request, *args, **kwargs):
            radio = self.get_object()
            tracks = radio.get_candidates().for_nested_serialization()
    
    
            page = self.paginate_queryset(tracks)
            if page is not None:
    
                serializer = TrackSerializer(page, many=True)
    
                return self.get_paginated_response(serializer.data)
    
    Bat's avatar
    Bat committed
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        @list_route(methods=["get"])
    
        def filters(self, request, *args, **kwargs):
            serializer = serializers.FilterSerializer(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                filters.registry.exposed_filters, many=True
            )
    
            return Response(serializer.data)
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        @list_route(methods=["post"])
    
        def validate(self, request, *args, **kwargs):
            try:
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                f_list = request.data["filters"]
    
            except KeyError:
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                return Response({"error": "You must provide a filters list"}, status=400)
            data = {"filters": []}
    
            for f in f_list:
                results = filters.test(f)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                if results["candidates"]["sample"]:
                    qs = results["candidates"]["sample"].for_nested_serialization()
                    results["candidates"]["sample"] = TrackSerializer(qs, many=True).data
                data["filters"].append(results)
    
    
            return Response(data)
    
    
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    class RadioSessionViewSet(
        mixins.CreateModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet
    ):
    
    
        serializer_class = serializers.RadioSessionSerializer
        queryset = models.RadioSession.objects.all()
    
        permission_classes = [permissions.IsAuthenticated]
    
    
        def get_queryset(self):
            queryset = super().get_queryset()
    
            return queryset.filter(user=self.request.user)
    
    
        def get_serializer_context(self):
            context = super().get_serializer_context()
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            context["user"] = self.request.user
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    class RadioSessionTrackViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
    
        serializer_class = serializers.RadioSessionTrackSerializer
        queryset = models.RadioSessionTrack.objects.all()
    
        permission_classes = [permissions.IsAuthenticated]
    
    
        def create(self, request, *args, **kwargs):
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            session = serializer.validated_data["session"]
    
            except AssertionError:
                return Response(status=status.HTTP_403_FORBIDDEN)
    
            session.radio.pick()
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            session_track = session.session_tracks.all().latest("id")
    
            # self.perform_create(serializer)
            # dirty override here, since we use a different serializer for creation and detail
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            serializer = self.serializer_class(
                instance=session_track, context=self.get_serializer_context()
            )
    
            headers = self.get_success_headers(serializer.data)
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            return Response(
                serializer.data, status=status.HTTP_201_CREATED, headers=headers
            )
    
    
        def get_serializer_class(self, *args, **kwargs):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            if self.action == "create":
    
                return serializers.RadioSessionTrackSerializerCreate
            return super().get_serializer_class(*args, **kwargs)