Newer
Older
from django.db.models import Q
from django.http import Http404
Eliot Berriot
committed
from rest_framework import generics, mixins, viewsets
from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import detail_route, list_route
Eliot Berriot
committed
from funkwhale_api.music.serializers import TrackSerializerNested
from funkwhale_api.common.permissions import ConditionalAuthentication
from . import models
from . import filters
from . import filtersets
Eliot Berriot
committed
from . import serializers
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class RadioViewSet(
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
serializer_class = serializers.RadioSerializer
permission_classes = [ConditionalAuthentication]
filter_class = filtersets.RadioFilter
def get_queryset(self):
query = Q(is_public=True)
if self.request.user.is_authenticated:
query |= Q(user=self.request.user)
return models.Radio.objects.filter(query)
def perform_create(self, serializer):
return serializer.save(user=self.request.user)
def perform_update(self, serializer):
if serializer.instance.user != self.request.user:
raise Http404
return serializer.save(user=self.request.user)
@list_route(methods=['get'])
def filters(self, request, *args, **kwargs):
serializer = serializers.FilterSerializer(
filters.registry.exposed_filters, many=True)
return Response(serializer.data)
@list_route(methods=['post'])
def validate(self, request, *args, **kwargs):
try:
f_list = request.data['filters']
except KeyError:
return Response(
{'error': 'You must provide a filters list'}, status=400)
data = {
'filters': []
}
for f in f_list:
results = filters.test(f)
if results['candidates']['sample']:
qs = results['candidates']['sample'].for_nested_serialization()
results['candidates']['sample'] = TrackSerializerNested(
qs, many=True).data
data['filters'].append(results)
return Response(data)
Eliot Berriot
committed
class RadioSessionViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
serializer_class = serializers.RadioSessionSerializer
queryset = models.RadioSession.objects.all()
permission_classes = [ConditionalAuthentication]
def get_queryset(self):
queryset = super().get_queryset()
if self.request.user.is_authenticated:
Eliot Berriot
committed
return queryset.filter(user=self.request.user)
else:
return queryset.filter(session_key=self.request.session.session_key)
def get_serializer_context(self):
context = super().get_serializer_context()
if self.request.user.is_authenticated:
Eliot Berriot
committed
context['user'] = self.request.user
else:
context['session_key'] = self.request.session.session_key
return context
class RadioSessionTrackViewSet(mixins.CreateModelMixin,
viewsets.GenericViewSet):
serializer_class = serializers.RadioSessionTrackSerializer
queryset = models.RadioSessionTrack.objects.all()
permission_classes = [ConditionalAuthentication]
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
session = serializer.validated_data['session']
try:
if request.user.is_authenticated:
Eliot Berriot
committed
assert request.user == session.user
else:
assert request.session.session_key == session.session_key
except AssertionError:
return Response(status=status.HTTP_403_FORBIDDEN)
track = session.radio.pick()
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
serializer = self.serializer_class(instance=session_track, context=self.get_serializer_context())
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def get_serializer_class(self, *args, **kwargs):
if self.action == 'create':
return serializers.RadioSessionTrackSerializerCreate
return super().get_serializer_class(*args, **kwargs)