from django.contrib.auth import get_user_model from django.utils import timezone from dynamic_preferences.registries import global_preferences_registry from rest_framework import status from rest_framework.authentication import (SessionAuthentication, TokenAuthentication) from rest_framework.generics import RetrieveAPIView from rest_framework.permissions import IsAuthenticated from rest_framework.renderers import BrowsableAPIRenderer, JSONRenderer from rest_framework.response import Response from rest_framework.views import APIView from profiles.exceptions import MakeRequestError from profiles.models import RadioProfile, SongRequest from radio.models import Song from ..permissions import IsDJ from ..renderers import build_annotate_string, LiquidsoapAnnotateRenderer from ..serializers.controls import (JustPlayedSerializer, MakeRequestSerializer, GetRequestSerializer) User = get_user_model() radio_settings = global_preferences_registry.manager() class JustPlayed(APIView): authentication_classes = [TokenAuthentication] permission_classes = [IsDJ] def post(self, request, format=None): serializer = JustPlayedSerializer(data=request.data) if serializer.is_valid(): request_pk = serializer.data['song_request'] try: song_request = SongRequest.objects.get(pk=request_pk) except SongRequest.DoesNotExist: return Response({'detail': 'Song request does not exist.'}, status=status.HTTP_400_BAD_REQUEST) if song_request.played_at: return Response({'detail': 'Song request was already played.'}, status=status.HTTP_400_BAD_REQUEST) song_request.played_at = timezone.now() song_request.save(update_fields=['played_at']) return Response(status=status.HTTP_204_NO_CONTENT) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class NextRequest(RetrieveAPIView): authentication_classes = [TokenAuthentication] permission_classes = [IsDJ] queryset = SongRequest.objects.all() renderer_classes = [ JSONRenderer, BrowsableAPIRenderer, LiquidsoapAnnotateRenderer ] serializer = GetRequestSerializer def retrieve(self, request): dj_profile = RadioProfile.objects.get(user__is_dj=True) limit = radio_settings['general__songs_per_jingle'] queued_songs = SongRequest.music.get_queued_requests(limit) if [j for j in queued_songs if j.song.is_jingle]: if not SongRequest.music.new_requests().exists(): random_song = Song.music.get_random_requestable_song() next_request = SongRequest.objects.create(profile=dj_profile, song=random_song) else: next_request = SongRequest.music.next_request() else: random_jingle = Song.music.get_random_jingle() next_request = SongRequest.objects.create(profile=dj_profile, song=random_jingle) next_request.queued_at = timezone.now() next_request.save(update_fields=['queued_at']) serializer = GetRequestSerializer(next_request, many=False) media_type = request.accepted_renderer.media_type if media_type == 'application/vnd.liquidsoap.annotate': return Response(build_annotate_string(serializer.data)) return Response(serializer.data) class MakeRequest(APIView): authentication_classes = [SessionAuthentication, TokenAuthentication] permission_classes = [IsAuthenticated] def post(self, request, format=None): serializer = MakeRequestSerializer(data=request.data) if serializer.is_valid(): profile = RadioProfile.objects.get(user=request.user) try: profile.make_request(serializer.data['song']) except MakeRequestError as e: return Response({'detail': str(e)}, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)