mirror of
https://gitlab.science.ru.nl/technicie/MarietjeDjango.git
synced 2025-12-09 18:52:23 +01:00
99 lines
4.0 KiB
Python
99 lines
4.0 KiB
Python
from django_filters.rest_framework import DjangoFilterBackend
|
|
from rest_framework.generics import ListAPIView, RetrieveAPIView, CreateAPIView
|
|
from rest_framework import filters
|
|
from rest_framework.views import APIView
|
|
from rest_framework.response import Response
|
|
|
|
from marietje.api.permissions import IsAuthenticatedOrTokenHasScopeForMethod
|
|
from songs.api.v1.serializers import SongSerializer, ReportNoteSerializer
|
|
from songs.counters import upload_counter
|
|
from songs.models import Song
|
|
|
|
from songs.services import check_upload_stats, get_reputation, upload_file, UploadException
|
|
|
|
|
|
class SongsListAPIView(ListAPIView):
|
|
serializer_class = SongSerializer
|
|
queryset = Song.objects.all()
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {"GET": ["read"]}
|
|
filter_backends = (filters.SearchFilter, filters.OrderingFilter, DjangoFilterBackend)
|
|
filterset_fields = ["user__username", "artist"]
|
|
search_fields = ["artist", "title", "user__name", "user__username"]
|
|
ordering_fields = [
|
|
"artist",
|
|
"title",
|
|
"duration",
|
|
]
|
|
|
|
|
|
class SongRetrieveAPIView(RetrieveAPIView):
|
|
serializer_class = SongSerializer
|
|
queryset = Song.objects.all()
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {"GET": ["read"]}
|
|
|
|
|
|
class ReportNoteCreateAPIView(CreateAPIView):
|
|
serializer_class = ReportNoteSerializer
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {"POST": ["write"]}
|
|
|
|
def perform_create(self, serializer):
|
|
serializer.save(user=self.request.user)
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
if self.request.user is None:
|
|
return Response(
|
|
status=403, data={"success": False, "errorMessage": "A user is necessary for creating a report note."}
|
|
)
|
|
else:
|
|
return super(ReportNoteCreateAPIView, self).create(request, *args, **kwargs)
|
|
|
|
|
|
class SongUploadAPIView(APIView):
|
|
serializer_class = SongSerializer
|
|
permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
|
|
required_scopes_for_method = {
|
|
"POST": ["write"],
|
|
}
|
|
|
|
def post(self, request, **kwargs):
|
|
if request.user is None:
|
|
return Response(
|
|
status=403, data={"success": False, "errorMessage": "A user is necessary for uploading a song."}
|
|
)
|
|
|
|
file = request.data.get("file", None)
|
|
artist = request.data.get("artist", None)
|
|
title = request.data.get("title", None)
|
|
if file is None:
|
|
return Response(status=400, data={"success": False, "errorMessage": "Please select a file to upload."})
|
|
if artist is None or artist == "":
|
|
return Response(status=400, data={"success": False, "errorMessage": "Please set an artist for this file."})
|
|
if title is None or title == "":
|
|
return Response(status=400, data={"success": False, "errorMessage": "Please set a title for this file."})
|
|
|
|
if not check_upload_stats(request.user):
|
|
reputation = get_reputation(request.user)
|
|
msg = (
|
|
"Queue-to-upload ratio too low. Please queue more during regular opening hours to improve the "
|
|
"ratio. (Ratio: {} ≱ 1.00)"
|
|
)
|
|
return Response(status=403, data={"success": False, "errorMessage": msg.format(reputation)})
|
|
|
|
try:
|
|
song = upload_file(file, artist, title, request.user)
|
|
upload_counter.inc()
|
|
return Response(status=200, data=self.serializer_class(song).data)
|
|
except (UploadException, ConnectionRefusedError):
|
|
return Response(
|
|
status=500,
|
|
data={
|
|
"success": False,
|
|
"errorMessage": "File could not be uploaded due to an exception that "
|
|
"occurred while contacting the file server, please try "
|
|
"again.",
|
|
},
|
|
)
|