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.
 
 

434 lines
16 KiB

from rest_framework import generics, status
from rest_framework.response import Response
from rest_framework.authentication import TokenAuthentication
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from apps.library.pagination import NoPagination
from utils.pagination import StandardResultsSetPagination
from rest_framework.permissions import IsAuthenticated
from apps.video.models import *
from apps.video.serializers import *
class VideoCategoryListAPIView(generics.ListAPIView):
"""
API view to list all video categories
"""
serializer_class = VideoCategoryListSerializer
pagination_class = StandardResultsSetPagination
@swagger_auto_schema(
operation_description="Get a list of all active video categories",
tags=["Dobodbi - Video"],
responses={
200: openapi.Response(
description="List of video categories",
schema=VideoCategoryListSerializer(many=True)
)
}
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
"""
Optimized queryset with prefetch_related for playlists
"""
return VideoCategory.objects.filter(status=True).prefetch_related(
'playlists'
).order_by('order')
class PinnedVideoCollectionListView(generics.ListAPIView):
serializer_class = PinnedVideoCollectionSerializer
permission_classes = (IsAuthenticated,)
authentication_classes = [TokenAuthentication]
pagination_class = NoPagination
@swagger_auto_schema(
operation_description="Get a list of pinned video collections",
tags=["Dobodbi - Video"],
manual_parameters=[
openapi.Parameter(
name='is_bookmark',
in_=openapi.IN_QUERY,
description='Filter collections that contain bookmarked playlists (true/false)',
type=openapi.TYPE_BOOLEAN,
required=False
),
],
responses={
200: openapi.Response(
description="List of pinned video collections",
schema=PinnedVideoCollectionSerializer(many=True)
)
}
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
queryset = PinnedVideoCollection.objects.filter(
status=True,
display_position=VideoCollection.DisplayPosition.PINNED
).order_by('-order', '-id')
# Filter by bookmarks if requested
is_bookmark = self.request.query_params.get('is_bookmark', '').lower()
if is_bookmark == 'true' and self.request.user.is_authenticated:
from apps.bookmark.models import Bookmark
bookmarked_ids = Bookmark.objects.filter(
user=self.request.user,
service=Bookmark.ServiceChoices.VIDEO_PLAYLIST,
status=True
).values_list('content_id', flat=True)
# Only include collections that contain at least one bookmarked playlist
queryset = queryset.filter(related_playlists__id__in=bookmarked_ids).distinct()
return queryset
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
categories_count = VideoCategory.objects.filter(status=True).count()
from apps.bookmark.models import Bookmark
bookmarks_count = Bookmark.objects.filter(
service=Bookmark.ServiceChoices.VIDEO,
).count()
info = {
"categories_count": categories_count,
"bookmarks_count": bookmarks_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 MiddleVideoCollectionListView(generics.ListAPIView):
serializer_class = MiddleVideoCollectionSerializer
permission_classes = (IsAuthenticated,)
authentication_classes = [TokenAuthentication]
pagination_class = NoPagination
@swagger_auto_schema(
operation_description="Get a list of middle video collections",
tags=["Dobodbi - Video"],
manual_parameters=[
openapi.Parameter(
name='is_bookmark',
in_=openapi.IN_QUERY,
description='Filter collections that contain bookmarked playlists (true/false)',
type=openapi.TYPE_BOOLEAN,
required=False
),
],
responses={
200: openapi.Response(
description="List of middle video collections",
schema=MiddleVideoCollectionSerializer(many=True)
)
}
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
return VideoCollection.objects.filter(
status=True,
display_position=VideoCollection.DisplayPosition.MIDDLE
).order_by('order')
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
# Pass is_bookmark to serializer context
is_bookmark = request.query_params.get('is_bookmark', '').lower()
# If is_bookmark=true, we filter the queryset to only include collections that
# have at least one bookmarked playlist
if is_bookmark == 'true' and request.user.is_authenticated:
from apps.bookmark.models import Bookmark
bookmarked_ids = Bookmark.objects.filter(
user=request.user,
service=Bookmark.ServiceChoices.VIDEO_PLAYLIST,
status=True
).values_list('content_id', flat=True)
# Filter collections that have any of these playlists
queryset = queryset.filter(related_playlists__id__in=bookmarked_ids).distinct()
serializer = self.get_serializer(queryset, many=True, context={'request': request, 'is_bookmark': is_bookmark})
return Response(serializer.data)
class VideoPlaylistListAPIView(generics.ListAPIView):
"""
API view to list all video playlists, with optional filtering by category or collection
"""
serializer_class = VideoPlaylistListSerializer
permission_classes = (IsAuthenticated,)
authentication_classes = [TokenAuthentication]
pagination_class = StandardResultsSetPagination
@swagger_auto_schema(
operation_description="Get a list of video playlists with optional filtering",
tags=["Dobodbi - Video"],
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 video playlists",
schema=VideoPlaylistListSerializer(many=True)
)
}
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
queryset = VideoPlaylist.objects.filter(status=True).order_by('order', '-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)
is_bookmark = self.request.query_params.get('is_bookmark', '').lower()
if is_bookmark == 'true':
# Import Bookmark model here to avoid circular imports
from apps.bookmark.models import Bookmark
# Get all bookmarked playlist IDs for the current user
bookmarked_ids = Bookmark.objects.filter(
user=self.request.user,
service=Bookmark.ServiceChoices.VIDEO_PLAYLIST,
status=True
).values_list('content_id', flat=True)
# Filter playlists by these IDs
queryset = queryset.filter(id__in=bookmarked_ids)
sort = self.request.query_params.get('sort', '-created_at')
allowed_sorts = [
'created_at', '-created_at', 'view_count', '-view_count',
'title', '-title','order' , 'order',
'total_time', '-total_time','-created_at','created_at'
]
if sort in allowed_sorts:
# Handle multiple sort fields (e.g., '-pin,-created_at')
if ',' in sort:
queryset = queryset.order_by(*sort.split(','))
else:
queryset = queryset.order_by(sort)
else:
queryset = queryset.order_by('-created_at')
return queryset
class VideoListAPIView(generics.ListAPIView):
"""
API view to list all video playlists, with optional filtering by category or collection
"""
serializer_class = VideoListSerializer
permission_classes = (IsAuthenticated,)
authentication_classes = [TokenAuthentication]
pagination_class = StandardResultsSetPagination
@swagger_auto_schema(
operation_description="Get a list of videos with optional filtering",
tags=["Dobodbi - Video"],
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 video playlists",
schema=VideoPlaylistListSerializer(many=True)
)
}
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
queryset = Video.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)
is_bookmark = self.request.query_params.get('is_bookmark', '').lower()
if is_bookmark == 'true':
# Import Bookmark model here to avoid circular imports
from apps.bookmark.models import Bookmark
# Get all bookmarked video IDs for the current user
bookmarked_ids = Bookmark.objects.filter(
user=self.request.user,
service=Bookmark.ServiceChoices.VIDEO,
status=True
).values_list('content_id', flat=True)
# Filter videos by these IDs
queryset = queryset.filter(id__in=bookmarked_ids)
sort = self.request.query_params.get('sort', '-created_at')
allowed_sorts = [
'created_at', '-created_at', 'view_count', '-view_count',
'title', '-title',
'total_time', '-total_time','-created_at','created_at'
]
if sort in allowed_sorts:
# Handle multiple sort fields (e.g., '-pin,-created_at')
if ',' in sort:
queryset = queryset.order_by(*sort.split(','))
else:
queryset = queryset.order_by(sort)
else:
queryset = queryset.order_by('-created_at')
return queryset
class VideoPlaylistDetailAPIView(generics.RetrieveAPIView):
serializer_class = VideoPlaylistDetailSerializer
permission_classes = (IsAuthenticated,)
authentication_classes = [TokenAuthentication]
lookup_field = 'slug'
@swagger_auto_schema(
operation_description="Get video playlist details by slug",
tags=["Dobodbi - Video"],
responses={
200: openapi.Response(
description="Video playlist details",
schema=VideoPlaylistDetailSerializer()
)
}
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
return VideoPlaylist.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 VideoDetailAPIView(generics.RetrieveAPIView):
serializer_class = VideoDetailSerializer
permission_classes = (IsAuthenticated,)
authentication_classes = [TokenAuthentication]
lookup_field = 'slug'
@swagger_auto_schema(
operation_description="Get video details by slug",
tags=["Dobodbi - Video"],
responses={
200: openapi.Response(
description="Video details",
schema=VideoDetailSerializer()
)
}
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
return Video.objects.filter(slug = self.kwargs.get('slug'))
# def retrieve(self, request, *args, **kwargs):
# instance = self.get_object()
# instance.increment_view_count()
# serializer = self.get_serializer(instance)
# return Response(serializer.data)