diff --git a/backend/playlist/serializers.py b/backend/playlist/serializers.py new file mode 100644 index 00000000..b4ae1c73 --- /dev/null +++ b/backend/playlist/serializers.py @@ -0,0 +1,51 @@ +"""playlist serializers""" + +# pylint: disable=abstract-method + +from common.serializers import PaginationSerializer +from rest_framework import serializers + + +class PlaylistEntrySerializer(serializers.Serializer): + """serialize single playlist entry""" + + youtube_id = serializers.CharField() + title = serializers.CharField() + uploader = serializers.CharField() + idx = serializers.IntegerField() + downloaded = serializers.BooleanField() + + +class PlaylistSerializer(serializers.Serializer): + """serialize playlist""" + + playlist_active = serializers.BooleanField() + playlist_channel = serializers.CharField() + playlist_channel_id = serializers.CharField() + playlist_description = serializers.CharField() + playlist_entries = PlaylistEntrySerializer(many=True) + playlist_id = serializers.CharField() + playlist_last_refresh = serializers.CharField() + playlist_name = serializers.CharField() + playlist_subscribed = serializers.BooleanField() + playlist_thumbnail = serializers.CharField() + playlist_type = serializers.ChoiceField(choices=["regular", "custom"]) + _index = serializers.CharField(required=False) + _score = serializers.IntegerField(required=False) + + +class PlaylistListSerializer(serializers.Serializer): + """serialize list of playlists""" + + data = PlaylistSerializer(many=True) + paginate = PaginationSerializer() + + +class PlaylistListQuerySerializer(serializers.Serializer): + """serialize playlist list query params""" + + channel = serializers.CharField(required=False) + subscribed = serializers.BooleanField(required=False) + type = serializers.ChoiceField( + choices=["regular", "custom"], required=False + ) diff --git a/backend/playlist/views.py b/backend/playlist/views.py index 79f6ea09..4718dfdf 100644 --- a/backend/playlist/views.py +++ b/backend/playlist/views.py @@ -2,8 +2,15 @@ import uuid +from common.serializers import ErrorResponseSerializer from common.views_base import AdminWriteOnly, ApiBaseView from download.src.subscriptions import PlaylistSubscription +from drf_spectacular.utils import OpenApiResponse, extend_schema +from playlist.serializers import ( + PlaylistListQuerySerializer, + PlaylistListSerializer, + PlaylistSerializer, +) from playlist.src.index import YoutubePlaylist from playlist.src.query_building import QueryBuilder from rest_framework import status @@ -25,17 +32,34 @@ class PlaylistApiListView(ApiBaseView): search_base = "ta_playlist/_search/" permission_classes = [AdminWriteOnly] + @extend_schema( + responses={ + 200: OpenApiResponse(PlaylistListSerializer()), + 400: OpenApiResponse( + ErrorResponseSerializer(), description="Bad request" + ), + }, + parameters=[PlaylistListQuerySerializer], + ) def get(self, request): - """get request""" + """get playlist list""" + query_serializer = PlaylistListQuerySerializer( + data=request.query_params + ) + query_serializer.is_valid(raise_exception=True) + validated_query = query_serializer.validated_data try: - data = QueryBuilder(**request.GET).build_data() + data = QueryBuilder(**validated_query).build_data() except ValueError as err: - return Response({"error": str(err)}, status=400) + error = ErrorResponseSerializer({"error": str(err)}) + return Response(error.data, status=400) self.data = data self.get_document_list(request) - return Response(self.response) + response_serializer = PlaylistListSerializer(self.response) + + return Response(response_serializer.data) def post(self, request): """subscribe/unsubscribe to list of playlists""" @@ -88,11 +112,25 @@ class PlaylistApiView(ApiBaseView): permission_classes = [AdminWriteOnly] valid_custom_actions = ["create", "remove", "up", "down", "top", "bottom"] + @extend_schema( + responses={ + 200: OpenApiResponse(PlaylistSerializer()), + 404: OpenApiResponse( + ErrorResponseSerializer(), description="playlist not found" + ), + }, + ) def get(self, request, playlist_id): # pylint: disable=unused-argument - """get request""" + """get playlist""" self.get_document(playlist_id) - return Response(self.response, status=self.status_code) + if not self.response: + error = ErrorResponseSerializer({"error": "playlist not found"}) + return Response(error.data, status=404) + + response_serializer = PlaylistSerializer(self.response) + + return Response(response_serializer.data) def post(self, request, playlist_id): """post to custom playlist to add a video to list"""