mirror of
https://gitlab.science.ru.nl/technicie/MarietjeDjango.git
synced 2025-12-10 11:32:22 +01:00
Marietje 4.1: Addition of Django REST framework, Swagger, Dark mode and updates to Django and Bootstrap
This commit is contained in:
24
marietje/songs/api/v1/serializers.py
Normal file
24
marietje/songs/api/v1/serializers.py
Normal file
@ -0,0 +1,24 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
from marietje.api.v1.serializers import UserRelatedFieldSerializer
|
||||
from songs.models import Song, ReportNote
|
||||
|
||||
|
||||
class SongSerializer(serializers.ModelSerializer):
|
||||
user = UserRelatedFieldSerializer()
|
||||
|
||||
class Meta:
|
||||
model = Song
|
||||
fields = ["id", "artist", "title", "duration", "hash", "user", "rg_gain", "rg_peak"]
|
||||
|
||||
|
||||
class ReportNoteSerializer(serializers.ModelSerializer):
|
||||
user = UserRelatedFieldSerializer(many=False, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = ReportNote
|
||||
fields = [
|
||||
"song",
|
||||
"note",
|
||||
"user",
|
||||
]
|
||||
10
marietje/songs/api/v1/urls.py
Normal file
10
marietje/songs/api/v1/urls.py
Normal file
@ -0,0 +1,10 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import SongsListAPIView, SongRetrieveAPIView, SongUploadAPIView, ReportNoteCreateAPIView
|
||||
|
||||
urlpatterns = [
|
||||
path("", SongsListAPIView.as_view(), name="song_list"),
|
||||
path("<int:pk>/", SongRetrieveAPIView.as_view(), name="song_retrieve"),
|
||||
path("report-notes/", ReportNoteCreateAPIView.as_view(), name="report_note_create"),
|
||||
path("upload/", SongUploadAPIView.as_view(), name="song_upload"),
|
||||
]
|
||||
96
marietje/songs/api/v1/views.py
Normal file
96
marietje/songs/api/v1/views.py
Normal file
@ -0,0 +1,96 @@
|
||||
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)
|
||||
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:
|
||||
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.",
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user