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 )