mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-11-06 15:38:53 -05:00
201 lines
8.1 KiB
Python
201 lines
8.1 KiB
Python
from django.conf import settings
|
|
from django.db.models import Q
|
|
from drf_yasg import openapi
|
|
from drf_yasg.utils import swagger_auto_schema
|
|
from rest_framework import permissions, status
|
|
from rest_framework.exceptions import PermissionDenied
|
|
from rest_framework.parsers import (
|
|
FileUploadParser,
|
|
FormParser,
|
|
JSONParser,
|
|
MultiPartParser,
|
|
)
|
|
from rest_framework.response import Response
|
|
from rest_framework.settings import api_settings
|
|
from rest_framework.views import APIView
|
|
|
|
from cms.permissions import IsAuthorizedToAdd, IsUserOrEditor
|
|
|
|
from ..models import Media, Playlist, PlaylistMedia
|
|
from ..serializers import MediaSerializer, PlaylistDetailSerializer, PlaylistSerializer
|
|
|
|
|
|
class PlaylistList(APIView):
|
|
"""Playlists listings and creation views"""
|
|
|
|
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsAuthorizedToAdd)
|
|
parser_classes = (JSONParser, MultiPartParser, FormParser, FileUploadParser)
|
|
|
|
@swagger_auto_schema(
|
|
manual_parameters=[],
|
|
tags=['Playlists'],
|
|
operation_summary='to_be_written',
|
|
operation_description='to_be_written',
|
|
responses={
|
|
200: openapi.Response('response description', PlaylistSerializer(many=True)),
|
|
},
|
|
)
|
|
def get(self, request, format=None):
|
|
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
|
|
paginator = pagination_class()
|
|
playlists = Playlist.objects.filter().prefetch_related("user")
|
|
|
|
if "author" in self.request.query_params:
|
|
author = self.request.query_params["author"].strip()
|
|
playlists = playlists.filter(user__username=author)
|
|
|
|
page = paginator.paginate_queryset(playlists, request)
|
|
|
|
serializer = PlaylistSerializer(page, many=True, context={"request": request})
|
|
return paginator.get_paginated_response(serializer.data)
|
|
|
|
@swagger_auto_schema(
|
|
manual_parameters=[],
|
|
tags=['Playlists'],
|
|
operation_summary='to_be_written',
|
|
operation_description='to_be_written',
|
|
)
|
|
def post(self, request, format=None):
|
|
serializer = PlaylistSerializer(data=request.data, context={"request": request})
|
|
if serializer.is_valid():
|
|
serializer.save(user=request.user)
|
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
|
|
class PlaylistDetail(APIView):
|
|
"""Playlist related views"""
|
|
|
|
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsUserOrEditor)
|
|
parser_classes = (JSONParser, MultiPartParser, FormParser, FileUploadParser)
|
|
|
|
def get_playlist(self, friendly_token):
|
|
try:
|
|
playlist = Playlist.objects.get(friendly_token=friendly_token)
|
|
self.check_object_permissions(self.request, playlist)
|
|
return playlist
|
|
except PermissionDenied:
|
|
return Response({"detail": "not enough permissions"}, status=status.HTTP_400_BAD_REQUEST)
|
|
except BaseException:
|
|
return Response(
|
|
{"detail": "Playlist does not exist"},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
|
|
@swagger_auto_schema(
|
|
manual_parameters=[],
|
|
tags=['Playlists'],
|
|
operation_summary='to_be_written',
|
|
operation_description='to_be_written',
|
|
)
|
|
def get(self, request, friendly_token, format=None):
|
|
playlist = self.get_playlist(friendly_token)
|
|
if isinstance(playlist, Response):
|
|
return playlist
|
|
|
|
serializer = PlaylistDetailSerializer(playlist, context={"request": request})
|
|
|
|
# If user is the author, show all media; otherwise, show only public and unlisted media
|
|
if request.user.is_authenticated and request.user == playlist.user:
|
|
playlist_media = PlaylistMedia.objects.filter(playlist=playlist).prefetch_related("media__user").select_related("media")
|
|
else:
|
|
playlist_media = PlaylistMedia.objects.filter(playlist=playlist).filter(Q(media__state="public") | Q(media__state="unlisted")).prefetch_related("media__user").select_related("media")
|
|
|
|
playlist_media = [c.media for c in playlist_media]
|
|
|
|
playlist_media_serializer = MediaSerializer(playlist_media, many=True, context={"request": request})
|
|
ret = serializer.data
|
|
ret["playlist_media"] = playlist_media_serializer.data
|
|
|
|
return Response(ret)
|
|
|
|
@swagger_auto_schema(
|
|
manual_parameters=[],
|
|
tags=['Playlists'],
|
|
operation_summary='to_be_written',
|
|
operation_description='to_be_written',
|
|
)
|
|
def post(self, request, friendly_token, format=None):
|
|
playlist = self.get_playlist(friendly_token)
|
|
if isinstance(playlist, Response):
|
|
return playlist
|
|
serializer = PlaylistDetailSerializer(playlist, data=request.data, context={"request": request})
|
|
if serializer.is_valid():
|
|
serializer.save(user=request.user)
|
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
@swagger_auto_schema(
|
|
manual_parameters=[],
|
|
tags=['Playlists'],
|
|
operation_summary='to_be_written',
|
|
operation_description='to_be_written',
|
|
)
|
|
def put(self, request, friendly_token, format=None):
|
|
playlist = self.get_playlist(friendly_token)
|
|
if isinstance(playlist, Response):
|
|
return playlist
|
|
action = request.data.get("type")
|
|
media_friendly_token = request.data.get("media_friendly_token")
|
|
ordering = 0
|
|
if request.data.get("ordering"):
|
|
try:
|
|
ordering = int(request.data.get("ordering"))
|
|
except ValueError:
|
|
pass
|
|
|
|
if action in ["add", "remove", "ordering"]:
|
|
media = Media.objects.filter(friendly_token=media_friendly_token).first()
|
|
if media:
|
|
if action == "add":
|
|
media_in_playlist = PlaylistMedia.objects.filter(playlist=playlist).count()
|
|
if media_in_playlist >= settings.MAX_MEDIA_PER_PLAYLIST:
|
|
return Response(
|
|
{"detail": "max number of media for a Playlist reached"},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
else:
|
|
obj, created = PlaylistMedia.objects.get_or_create(
|
|
playlist=playlist,
|
|
media=media,
|
|
ordering=media_in_playlist + 1,
|
|
)
|
|
obj.save()
|
|
return Response(
|
|
{"detail": "media added to Playlist"},
|
|
status=status.HTTP_201_CREATED,
|
|
)
|
|
elif action == "remove":
|
|
PlaylistMedia.objects.filter(playlist=playlist, media=media).delete()
|
|
return Response(
|
|
{"detail": "media removed from Playlist"},
|
|
status=status.HTTP_201_CREATED,
|
|
)
|
|
elif action == "ordering":
|
|
if ordering:
|
|
playlist.set_ordering(media, ordering)
|
|
return Response(
|
|
{"detail": "new ordering set"},
|
|
status=status.HTTP_201_CREATED,
|
|
)
|
|
else:
|
|
return Response({"detail": "media is not valid"}, status=status.HTTP_400_BAD_REQUEST)
|
|
return Response(
|
|
{"detail": "invalid or not specified action"},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
|
|
@swagger_auto_schema(
|
|
manual_parameters=[],
|
|
tags=['Playlists'],
|
|
operation_summary='to_be_written',
|
|
operation_description='to_be_written',
|
|
)
|
|
def delete(self, request, friendly_token, format=None):
|
|
playlist = self.get_playlist(friendly_token)
|
|
if isinstance(playlist, Response):
|
|
return playlist
|
|
|
|
playlist.delete()
|
|
return Response(status=status.HTTP_204_NO_CONTENT)
|