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.
501 lines
19 KiB
501 lines
19 KiB
from rest_framework import generics, status
|
|
from rest_framework.authentication import TokenAuthentication
|
|
from rest_framework.decorators import action
|
|
from rest_framework.parsers import FormParser, JSONParser, MultiPartParser
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
from rest_framework.viewsets import ModelViewSet
|
|
from drf_yasg import openapi
|
|
from drf_yasg.utils import swagger_auto_schema
|
|
from apps.library.pagination import NoPagination
|
|
from utils.mixins import CanonicalSlugViewSetMixin, Gone410ViewMixin
|
|
from utils.pagination import StandardResultsSetPagination
|
|
|
|
|
|
from apps.video.models import *
|
|
from apps.video.serializers import *
|
|
from apps.video.serializers_admin import (
|
|
AdminVideoCategorySerializer,
|
|
AdminVideoCollectionSerializer,
|
|
AdminVideoListSerializer,
|
|
)
|
|
from apps.video.serializers_dovodi import DovodiVideoCategorySerializer, DovodiVideoCollectionSerializer, DovodiVideoItemSerializer
|
|
|
|
|
|
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 = 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
|
|
),
|
|
openapi.Parameter(
|
|
name='sort',
|
|
in_=openapi.IN_QUERY,
|
|
description='Sort playlists by field. Options: created_at, -created_at, view_count, -view_count, title, -title, order, -order',
|
|
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'
|
|
]
|
|
|
|
if sort in allowed_sorts:
|
|
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(Gone410ViewMixin, CanonicalSlugViewSetMixin, generics.RetrieveAPIView):
|
|
serializer_class = VideoPlaylistDetailSerializer
|
|
permission_classes = (IsAuthenticated,)
|
|
authentication_classes = [TokenAuthentication]
|
|
lookup_field = 'slug'
|
|
|
|
active_field_name = 'status'
|
|
active_expected_value = True
|
|
|
|
@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.all()
|
|
|
|
def retrieve(self, request, *args, **kwargs):
|
|
instance = self.get_object()
|
|
instance.increment_view_count()
|
|
serializer = self.get_serializer(instance)
|
|
return Response(serializer.data)
|
|
|
|
|
|
class DovodiVideoCategoryViewSet(ModelViewSet):
|
|
serializer_class = DovodiVideoCategorySerializer
|
|
permission_classes = [IsAuthenticated]
|
|
authentication_classes = [TokenAuthentication]
|
|
pagination_class = None
|
|
|
|
def get_queryset(self):
|
|
queryset = VideoCategory.objects.all().order_by("order", "title")
|
|
search_query = self.request.query_params.get("search")
|
|
if search_query:
|
|
queryset = queryset.filter(Q(title__icontains=search_query) | Q(slug__icontains=search_query))
|
|
return queryset
|
|
|
|
|
|
class DovodiVideoCollectionViewSet(ModelViewSet):
|
|
serializer_class = DovodiVideoCollectionSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
authentication_classes = [TokenAuthentication]
|
|
pagination_class = None
|
|
parser_classes = (MultiPartParser, FormParser, JSONParser)
|
|
|
|
def get_queryset(self):
|
|
queryset = VideoCollection.objects.all().order_by("display_position", "order", "title")
|
|
search_query = self.request.query_params.get("search")
|
|
if search_query:
|
|
queryset = queryset.filter(Q(title__icontains=search_query) | Q(slug__icontains=search_query))
|
|
return queryset
|
|
|
|
|
|
class DovodiVideoItemViewSet(ModelViewSet):
|
|
serializer_class = DovodiVideoItemSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
authentication_classes = [TokenAuthentication]
|
|
pagination_class = None
|
|
parser_classes = (MultiPartParser, FormParser, JSONParser)
|
|
|
|
def get_queryset(self):
|
|
queryset = Video.objects.all().order_by("-created_at")
|
|
search_query = self.request.query_params.get("search")
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(title__icontains=search_query)
|
|
| Q(slug__icontains=search_query)
|
|
| Q(description__icontains=search_query)
|
|
)
|
|
return queryset
|
|
|