You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
9.2 KiB
268 lines
9.2 KiB
from rest_framework import generics, status
|
|
from rest_framework.response import Response
|
|
from drf_yasg import openapi
|
|
from drf_yasg.utils import swagger_auto_schema
|
|
from apps.library.pagination import NoPagination
|
|
from rest_framework.permissions import IsAuthenticated
|
|
|
|
|
|
from apps.podcast.models import *
|
|
from apps.podcast.serializers import *
|
|
|
|
|
|
class PodcastCategoryListAPIView(generics.ListAPIView):
|
|
"""
|
|
API view to list all podcast categories
|
|
"""
|
|
serializer_class = PodcastCategoryListSerializer
|
|
|
|
@swagger_auto_schema(
|
|
operation_description="Get a list of all active podcast categories",
|
|
responses={
|
|
200: openapi.Response(
|
|
description="List of podcast categories",
|
|
schema=PodcastCategoryListSerializer(many=True)
|
|
)
|
|
}
|
|
)
|
|
def get(self, request, *args, **kwargs):
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
return PodcastCategory.objects.filter(status=True).order_by('order')
|
|
|
|
|
|
|
|
class PinnedPodcastCollectionListView(generics.ListAPIView):
|
|
serializer_class = PinnedPodcastCollectionSerializer
|
|
permission_classes = (IsAuthenticated,)
|
|
pagination_class = NoPagination
|
|
|
|
|
|
def get_queryset(self):
|
|
return PinnedPodcastCollection.objects.filter(
|
|
status=True,
|
|
display_position=PodcastCollection.DisplayPosition.PINNED
|
|
).order_by('-order', '-id')
|
|
|
|
def list(self, request, *args, **kwargs):
|
|
response = super().list(request, *args, **kwargs)
|
|
categories_count = PodcastCategory.objects.filter(status=True).count()
|
|
# Count podcasts in the user's playlist
|
|
user_playlist_count = 0
|
|
if request.user.is_authenticated:
|
|
user_playlist_count = UserPlaylist.objects.filter(
|
|
user=request.user,
|
|
status=True
|
|
).count()
|
|
|
|
info = {
|
|
"categories_count": categories_count,
|
|
"user_playlist_count": user_playlist_count,
|
|
}
|
|
data = {
|
|
"count": response.data.get("count"),
|
|
"next": response.data.get("next"),
|
|
"previous": response.data.get("previous"),
|
|
"info": info,
|
|
"results": response.data.get("results")
|
|
}
|
|
return Response(data, status=status.HTTP_200_OK)
|
|
|
|
|
|
class MiddlePodcastCollectionListView(generics.ListAPIView):
|
|
serializer_class = MiddlePodcastCollectionSerializer
|
|
permission_classes = (IsAuthenticated,)
|
|
pagination_class = NoPagination
|
|
|
|
def get_queryset(self):
|
|
return PodcastCollection.objects.filter(
|
|
status=True,
|
|
display_position=PodcastCollection.DisplayPosition.MIDDLE
|
|
).order_by('order')
|
|
|
|
|
|
class PodcastListAPIView(generics.ListAPIView):
|
|
"""
|
|
API view to list all podcast playlists, with optional filtering by category, collection
|
|
"""
|
|
serializer_class = PodcastPlaylistListSerializer
|
|
permission_classes = (IsAuthenticated,)
|
|
|
|
@swagger_auto_schema(
|
|
operation_description="Get a list of podcast playlists with optional filtering",
|
|
manual_parameters=[
|
|
openapi.Parameter(
|
|
name='category',
|
|
in_=openapi.IN_QUERY,
|
|
description='Filter playlists by category slug',
|
|
type=openapi.TYPE_STRING,
|
|
required=False
|
|
),
|
|
openapi.Parameter(
|
|
name='collection',
|
|
in_=openapi.IN_QUERY,
|
|
description='Filter playlists by collection slug',
|
|
type=openapi.TYPE_STRING,
|
|
required=False
|
|
),
|
|
openapi.Parameter(
|
|
name='is_bookmark',
|
|
in_=openapi.IN_QUERY,
|
|
description='Filter playlists that are bookmarked by the user (true/false)',
|
|
type=openapi.TYPE_BOOLEAN,
|
|
required=False
|
|
),
|
|
openapi.Parameter(
|
|
name='search',
|
|
in_=openapi.IN_QUERY,
|
|
description='Search playlists by title',
|
|
type=openapi.TYPE_STRING,
|
|
required=False
|
|
)
|
|
],
|
|
responses={
|
|
200: openapi.Response(
|
|
description="List of podcast playlists",
|
|
schema=PodcastPlaylistListSerializer(many=True)
|
|
)
|
|
}
|
|
)
|
|
def get(self, request, *args, **kwargs):
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
queryset = PodcastPlaylist.objects.filter(status=True).order_by('-created_at')
|
|
|
|
# Search by title if search parameter is provided
|
|
search_query = self.request.query_params.get('search', None)
|
|
if search_query:
|
|
queryset = queryset.filter(title__icontains=search_query)
|
|
|
|
# Filter by category if provided
|
|
category_slug = self.request.query_params.get('category', None)
|
|
if category_slug:
|
|
queryset = queryset.filter(categories__slug=category_slug)
|
|
|
|
# Filter by collection if provided
|
|
collection_slug = self.request.query_params.get('collection', None)
|
|
if collection_slug:
|
|
queryset = queryset.filter(
|
|
collections__slug=collection_slug
|
|
)
|
|
|
|
# Filter by bookmarks if provided
|
|
is_bookmark = self.request.query_params.get('is_bookmark', '').lower()
|
|
if is_bookmark == 'true':
|
|
from apps.bookmark.models import Bookmark
|
|
|
|
bookmarked_ids = Bookmark.objects.filter(
|
|
user=self.request.user,
|
|
service=Bookmark.ServiceChoices.PODCAST_PLAYLIST,
|
|
status=True
|
|
).values_list('content_id', flat=True)
|
|
|
|
queryset = queryset.filter(id__in=bookmarked_ids)
|
|
|
|
return queryset
|
|
|
|
|
|
class PodcastDetailAPIView(generics.RetrieveAPIView):
|
|
"""
|
|
API view to retrieve details of a specific podcast playlist
|
|
"""
|
|
serializer_class = PodcastPlaylistDetailSerializer
|
|
lookup_field = 'slug'
|
|
permission_classes = (IsAuthenticated,)
|
|
|
|
def get_queryset(self):
|
|
return PodcastPlaylist.objects.filter(status=True)
|
|
|
|
def retrieve(self, request, *args, **kwargs):
|
|
instance = self.get_object()
|
|
instance.increment_view_count()
|
|
serializer = self.get_serializer(instance)
|
|
return Response(serializer.data)
|
|
|
|
|
|
class UserPlaylistListAPIView(generics.ListAPIView):
|
|
"""
|
|
API view to list all podcasts in the user's personal playlist
|
|
"""
|
|
serializer_class = PodcastListSerializer
|
|
permission_classes = (IsAuthenticated,)
|
|
|
|
@swagger_auto_schema(
|
|
operation_description="Get a list of podcasts in the user's personal playlist",
|
|
responses={
|
|
200: openapi.Response(
|
|
description="List of podcasts in the user's playlist",
|
|
schema=PodcastListSerializer(many=True)
|
|
)
|
|
}
|
|
)
|
|
def get(self, request, *args, **kwargs):
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
# Get all active podcasts that are in the user's playlist
|
|
user_playlist_podcasts = UserPlaylist.objects.filter(
|
|
user=self.request.user,
|
|
status=True
|
|
).values_list('podcast_id', flat=True)
|
|
|
|
return Podcast.objects.filter(
|
|
id__in=user_playlist_podcasts,
|
|
status=True
|
|
).order_by('-created_at')
|
|
|
|
|
|
class UserPlaylistCreateAPIView(generics.CreateAPIView):
|
|
"""
|
|
API view to add or update a podcast in a user's personal playlist
|
|
"""
|
|
serializer_class = UserPlaylistCreateSerializer
|
|
permission_classes = (IsAuthenticated,)
|
|
|
|
@swagger_auto_schema(
|
|
operation_description="Add or update a podcast in the user's personal playlist",
|
|
request_body=UserPlaylistCreateSerializer,
|
|
responses={
|
|
201: openapi.Response(
|
|
description="Podcast added to playlist successfully",
|
|
schema=UserPlaylistSerializer()
|
|
),
|
|
400: "Bad Request"
|
|
}
|
|
)
|
|
def post(self, request, *args, **kwargs):
|
|
return super().post(request, *args, **kwargs)
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
podcast_id = serializer.validated_data['podcast_id']
|
|
playlist_status = serializer.validated_data.get('status', True)
|
|
|
|
try:
|
|
podcast = Podcast.objects.get(id=podcast_id, status=True)
|
|
except Podcast.DoesNotExist:
|
|
return Response(
|
|
{"detail": "Podcast not found or not active."},
|
|
status=status.HTTP_404_NOT_FOUND
|
|
)
|
|
|
|
# Try to get existing user playlist entry or create a new one
|
|
user_playlist, created = UserPlaylist.objects.update_or_create(
|
|
user=request.user,
|
|
podcast=podcast,
|
|
defaults={'status': playlist_status}
|
|
)
|
|
|
|
# Return the user playlist entry
|
|
response_serializer = UserPlaylistSerializer(user_playlist)
|
|
return Response(
|
|
response_serializer.data,
|
|
status=status.HTTP_201_CREATED if created else status.HTTP_200_OK
|
|
)
|