mirror of
https://gitlab.science.ru.nl/technicie/MarietjeDjango.git
synced 2025-12-09 19:22:22 +01:00
301 lines
11 KiB
Python
301 lines
11 KiB
Python
from django.db.models import Q
|
|
from rest_framework.generics import ListAPIView, RetrieveAPIView, get_object_or_404, CreateAPIView, DestroyAPIView
|
|
from rest_framework.views import APIView
|
|
from rest_framework.response import Response
|
|
|
|
from marietje.api.openapi import CustomAutoSchema
|
|
from marietje.api.permissions import IsAuthenticatedOrTokenHasScopeForMethod
|
|
from django.http import Http404
|
|
|
|
from queues.api.v1.serializers import PlaylistSerializer, QueueSerializer, PlaylistSongSerializer
|
|
from queues.exceptions import RequestException
|
|
from queues.models import Playlist, PlaylistSong, QueueCommand, Queue
|
|
from queues.services import get_user_or_default_queue
|
|
from songs.counters import request_counter
|
|
from songs.models import Song
|
|
|
|
|
|
class PlaylistListAPIView(ListAPIView):
|
|
serializer_class = PlaylistSerializer
|
|
queryset = Playlist.objects.all()
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {"GET": ["read"]}
|
|
|
|
|
|
class PlaylistRetrieveAPIView(RetrieveAPIView):
|
|
serializer_class = PlaylistSerializer
|
|
queryset = Playlist.objects.all()
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {"GET": ["read"]}
|
|
|
|
|
|
class QueueAPIView(APIView):
|
|
serializer_class = QueueSerializer
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {"GET": ["read"]}
|
|
schema = CustomAutoSchema(
|
|
response_schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {"type": "int", "example": 1},
|
|
"name": {"type": "string", "example": "string"},
|
|
"playlist": {"type": "int", "example": 1},
|
|
"random_playlist": {"type": "int", "example": 1},
|
|
"current_song": {"$ref": "#/components/schemas/PlaylistSong"},
|
|
"queue": {"type": "array", "items": {"$ref": "#/components/schemas/PlaylistSong"}},
|
|
"started_at": {"type": "string", "format": "date-time", "nullable": True},
|
|
},
|
|
}
|
|
)
|
|
|
|
def get(self, request, **kwargs):
|
|
queue = get_user_or_default_queue(request)
|
|
if queue is None:
|
|
raise Http404()
|
|
return Response(status=200, data=self.serializer_class(queue).data)
|
|
|
|
|
|
class QueueSkipAPIView(APIView):
|
|
serializer_class = QueueSerializer
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {
|
|
"POST": ["write"],
|
|
}
|
|
schema = CustomAutoSchema(
|
|
response_schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {"type": "int", "example": 1},
|
|
"name": {"type": "string", "example": "string"},
|
|
"playlist": {"type": "int", "example": 1},
|
|
"random_playlist": {"type": "int", "example": 1},
|
|
"current_song": {"$ref": "#/components/schemas/PlaylistSong"},
|
|
"queue": {"type": "array", "items": {"$ref": "#/components/schemas/PlaylistSong"}},
|
|
"started_at": {"type": "string", "format": "date-time", "nullable": True},
|
|
},
|
|
}
|
|
)
|
|
|
|
def post(self, request, **kwargs):
|
|
queue = get_user_or_default_queue(request)
|
|
if queue is None:
|
|
return Response(status=404)
|
|
|
|
playlist_song = queue.current_song()
|
|
if (
|
|
request.user is not None
|
|
and playlist_song.user != request.user
|
|
and not request.user.has_perm("queues.can_skip")
|
|
):
|
|
return Response(status=403)
|
|
|
|
playlist_song.state = 2
|
|
playlist_song.save()
|
|
queue.log_action(request.user, "next", "Skipped to next song.")
|
|
|
|
return Response(status=200, data=QueueSerializer(queue).data)
|
|
|
|
|
|
class PlaylistSongMoveDownAPIView(APIView):
|
|
serializer_class = PlaylistSongSerializer
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {
|
|
"PATCH": ["write"],
|
|
}
|
|
schema = CustomAutoSchema(response_schema={"$ref": "#/components/schemas/PlaylistSong"})
|
|
|
|
def patch(self, request, **kwargs):
|
|
playlist_song_id = kwargs.get("id")
|
|
playlist_song = get_object_or_404(PlaylistSong, id=playlist_song_id)
|
|
if (
|
|
request.user is not None
|
|
and playlist_song.user != request.user
|
|
and not request.user.has_perm("queues.can_move")
|
|
):
|
|
return Response(status=403)
|
|
|
|
playlist_song.move_down()
|
|
|
|
for queue in Queue.objects.filter(
|
|
Q(playlist=playlist_song.playlist) | Q(random_playlist=playlist_song.playlist)
|
|
):
|
|
queue.log_action(
|
|
request.user,
|
|
"down",
|
|
'Moved song "{}" of playlist "{}" down.'.format(playlist_song.song, playlist_song.playlist),
|
|
)
|
|
|
|
return Response(status=200, data=self.serializer_class(playlist_song).data)
|
|
|
|
|
|
class PlaylistSongCancelAPIView(DestroyAPIView):
|
|
serializer_class = PlaylistSongSerializer
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {
|
|
"DELETE": ["write"],
|
|
}
|
|
|
|
def delete(self, request, **kwargs):
|
|
playlist_song_id = kwargs.get("id")
|
|
playlist_song = get_object_or_404(PlaylistSong, id=playlist_song_id)
|
|
if (
|
|
request.user is not None
|
|
and playlist_song.user != request.user
|
|
and not request.user.has_perm("queues.can_cancel")
|
|
):
|
|
return Response(status=403)
|
|
|
|
playlist_song.delete()
|
|
|
|
for queue in Queue.objects.filter(
|
|
Q(playlist=playlist_song.playlist) | Q(random_playlist=playlist_song.playlist)
|
|
):
|
|
queue.log_action(
|
|
request.user,
|
|
"cancel",
|
|
'Cancelled song "{}" of playlist "{}".'.format(playlist_song.song, playlist_song.playlist),
|
|
)
|
|
|
|
return Response(status=200, data=self.serializer_class(playlist_song).data)
|
|
|
|
|
|
class QueueRequestAPIView(CreateAPIView):
|
|
serializer_class = PlaylistSongSerializer
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {
|
|
"POST": ["write"],
|
|
}
|
|
schema = CustomAutoSchema(
|
|
request_schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"song": {"type": "int", "example": 1},
|
|
},
|
|
}
|
|
)
|
|
|
|
def post(self, request, **kwargs):
|
|
queue = get_user_or_default_queue(request)
|
|
if queue is None:
|
|
return Response(status=404)
|
|
song_id = request.data.get("song", None)
|
|
if song_id is None:
|
|
return Response(status=400, data={"success": False, "errorMessage": "Song ID not set."})
|
|
|
|
song = get_object_or_404(Song, id=song_id, deleted=False)
|
|
|
|
try:
|
|
playlist_song = queue.request(song, request.user)
|
|
except RequestException as e:
|
|
return Response(data={"success": False, "errorMessage": str(e)})
|
|
|
|
queue.log_action(request.user, "request_song", "Requested song {}.".format(song))
|
|
|
|
request_counter.labels(queue=queue.name).inc()
|
|
return Response(status=200, data=self.serializer_class(playlist_song).data)
|
|
|
|
|
|
class QueueVolumeDownAPIView(APIView):
|
|
serializer_class = QueueSerializer
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {
|
|
"POST": ["write"],
|
|
}
|
|
schema = CustomAutoSchema(
|
|
response_schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {"type": "int", "example": 1},
|
|
"name": {"type": "string", "example": "string"},
|
|
"playlist": {"type": "int", "example": 1},
|
|
"random_playlist": {"type": "int", "example": 1},
|
|
"current_song": {"$ref": "#/components/schemas/PlaylistSong"},
|
|
"queue": {"type": "array", "items": {"$ref": "#/components/schemas/PlaylistSong"}},
|
|
"started_at": {"type": "string", "format": "date-time", "nullable": True},
|
|
},
|
|
}
|
|
)
|
|
|
|
def post(self, request, **kwargs):
|
|
queue = get_user_or_default_queue(request)
|
|
if queue is None:
|
|
return Response(status=404)
|
|
if request.user is not None and not request.user.has_perm("queues.can_control_volume"):
|
|
return Response(status=403)
|
|
|
|
QueueCommand.objects.create(queue=queue, command="volume_down")
|
|
|
|
queue.log_action(request.user, "volume_down", "Reduced the volume of {}.".format(queue))
|
|
|
|
return Response(status=200, data=self.serializer_class(queue).data)
|
|
|
|
|
|
class QueueVolumeUpAPIView(APIView):
|
|
serializer_class = QueueSerializer
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {
|
|
"POST": ["write"],
|
|
}
|
|
schema = CustomAutoSchema(
|
|
response_schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {"type": "int", "example": 1},
|
|
"name": {"type": "string", "example": "string"},
|
|
"playlist": {"type": "int", "example": 1},
|
|
"random_playlist": {"type": "int", "example": 1},
|
|
"current_song": {"$ref": "#/components/schemas/PlaylistSong"},
|
|
"queue": {"type": "array", "items": {"$ref": "#/components/schemas/PlaylistSong"}},
|
|
"started_at": {"type": "string", "format": "date-time", "nullable": True},
|
|
},
|
|
}
|
|
)
|
|
|
|
def post(self, request, **kwargs):
|
|
queue = get_user_or_default_queue(request)
|
|
if queue is None:
|
|
return Response(status=404)
|
|
if request.user is not None and not request.user.has_perm("queues.can_control_volume"):
|
|
return Response(status=403)
|
|
|
|
QueueCommand.objects.create(queue=queue, command="volume_up")
|
|
|
|
queue.log_action(request.user, "volume_up", "Increased the volume of {}.".format(queue))
|
|
|
|
return Response(status=200, data=self.serializer_class(queue).data)
|
|
|
|
|
|
class QueueMuteAPIView(APIView):
|
|
serializer_class = QueueSerializer
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {
|
|
"POST": ["write"],
|
|
}
|
|
schema = CustomAutoSchema(
|
|
response_schema={
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {"type": "int", "example": 1},
|
|
"name": {"type": "string", "example": "string"},
|
|
"playlist": {"type": "int", "example": 1},
|
|
"random_playlist": {"type": "int", "example": 1},
|
|
"current_song": {"$ref": "#/components/schemas/PlaylistSong"},
|
|
"queue": {"type": "array", "items": {"$ref": "#/components/schemas/PlaylistSong"}},
|
|
"started_at": {"type": "string", "format": "date-time", "nullable": True},
|
|
},
|
|
}
|
|
)
|
|
|
|
def post(self, request, **kwargs):
|
|
queue = get_user_or_default_queue(request)
|
|
if queue is None:
|
|
return Response(status=404)
|
|
if request.user is not None and not request.user.has_perm("queues.can_control_volume"):
|
|
return Response(status=403)
|
|
|
|
QueueCommand.objects.create(queue=queue, command="mute")
|
|
|
|
queue.log_action(request.user, "mute", "Muted the volume of {}.".format(queue))
|
|
|
|
return Response(status=200, data=self.serializer_class(queue).data)
|