|
|
@ -286,13 +286,13 @@ class VideoListAPIView(generics.ListAPIView): |
|
|
""" |
|
|
""" |
|
|
API view to list all video playlists, with optional filtering by category or collection |
|
|
API view to list all video playlists, with optional filtering by category or collection |
|
|
""" |
|
|
""" |
|
|
serializer_class = VideoListSerializer |
|
|
|
|
|
|
|
|
serializer_class = VideoPlaylistListSerializer |
|
|
permission_classes = (IsAuthenticated,) |
|
|
permission_classes = (IsAuthenticated,) |
|
|
authentication_classes = [TokenAuthentication] |
|
|
authentication_classes = [TokenAuthentication] |
|
|
pagination_class = StandardResultsSetPagination |
|
|
pagination_class = StandardResultsSetPagination |
|
|
|
|
|
|
|
|
@swagger_auto_schema( |
|
|
@swagger_auto_schema( |
|
|
operation_description="Get a list of videos with optional filtering", |
|
|
|
|
|
|
|
|
operation_description="Get a list of video playlists with optional filtering", |
|
|
tags=["Dobodbi - Video"], |
|
|
tags=["Dobodbi - Video"], |
|
|
manual_parameters=[ |
|
|
manual_parameters=[ |
|
|
openapi.Parameter( |
|
|
openapi.Parameter( |
|
|
@ -322,6 +322,13 @@ class VideoListAPIView(generics.ListAPIView): |
|
|
description='Search playlists by title', |
|
|
description='Search playlists by title', |
|
|
type=openapi.TYPE_STRING, |
|
|
type=openapi.TYPE_STRING, |
|
|
required=False |
|
|
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={ |
|
|
responses={ |
|
|
@ -335,7 +342,7 @@ class VideoListAPIView(generics.ListAPIView): |
|
|
return super().get(request, *args, **kwargs) |
|
|
return super().get(request, *args, **kwargs) |
|
|
|
|
|
|
|
|
def get_queryset(self): |
|
|
def get_queryset(self): |
|
|
queryset = Video.objects.filter(status=True).order_by('-created_at') |
|
|
|
|
|
|
|
|
queryset = VideoPlaylist.objects.filter(status=True).order_by('order', '-created_at') |
|
|
|
|
|
|
|
|
# Search by title if search parameter is provided |
|
|
# Search by title if search parameter is provided |
|
|
search_query = self.request.query_params.get('search', None) |
|
|
search_query = self.request.query_params.get('search', None) |
|
|
@ -345,36 +352,35 @@ class VideoListAPIView(generics.ListAPIView): |
|
|
# Filter by category if provided |
|
|
# Filter by category if provided |
|
|
category_slug = self.request.query_params.get('category', None) |
|
|
category_slug = self.request.query_params.get('category', None) |
|
|
if category_slug: |
|
|
if category_slug: |
|
|
queryset = queryset.filter(playlist_appearances__playlist__categories__slug=category_slug) |
|
|
|
|
|
|
|
|
queryset = queryset.filter(categories__slug=category_slug) |
|
|
|
|
|
|
|
|
# Filter by collection if provided |
|
|
# Filter by collection if provided |
|
|
collection_slug = self.request.query_params.get('collection', None) |
|
|
collection_slug = self.request.query_params.get('collection', None) |
|
|
if collection_slug: |
|
|
if collection_slug: |
|
|
queryset = queryset.filter(playlist_appearances__playlist__collections__slug=collection_slug) |
|
|
|
|
|
|
|
|
queryset = queryset.filter(collections__slug=collection_slug) |
|
|
|
|
|
|
|
|
is_bookmark = self.request.query_params.get('is_bookmark', '').lower() |
|
|
is_bookmark = self.request.query_params.get('is_bookmark', '').lower() |
|
|
if is_bookmark == 'true': |
|
|
if is_bookmark == 'true': |
|
|
# Import Bookmark model here to avoid circular imports |
|
|
# Import Bookmark model here to avoid circular imports |
|
|
from apps.bookmark.models import Bookmark |
|
|
from apps.bookmark.models import Bookmark |
|
|
|
|
|
|
|
|
# Get all bookmarked video IDs for the current user |
|
|
|
|
|
|
|
|
# Get all bookmarked playlist IDs for the current user |
|
|
bookmarked_ids = Bookmark.objects.filter( |
|
|
bookmarked_ids = Bookmark.objects.filter( |
|
|
user=self.request.user, |
|
|
user=self.request.user, |
|
|
service=Bookmark.ServiceChoices.VIDEO, |
|
|
|
|
|
|
|
|
service=Bookmark.ServiceChoices.VIDEO_PLAYLIST, |
|
|
status=True |
|
|
status=True |
|
|
).values_list('content_id', flat=True) |
|
|
).values_list('content_id', flat=True) |
|
|
|
|
|
|
|
|
# Filter videos by these IDs |
|
|
|
|
|
|
|
|
# Filter playlists by these IDs |
|
|
queryset = queryset.filter(id__in=bookmarked_ids) |
|
|
queryset = queryset.filter(id__in=bookmarked_ids) |
|
|
sort = self.request.query_params.get('sort', '-created_at') |
|
|
sort = self.request.query_params.get('sort', '-created_at') |
|
|
allowed_sorts = [ |
|
|
allowed_sorts = [ |
|
|
'created_at', '-created_at', 'view_count', '-view_count', |
|
|
'created_at', '-created_at', 'view_count', '-view_count', |
|
|
'title', '-title', |
|
|
|
|
|
'total_time', '-total_time','-created_at','created_at' |
|
|
|
|
|
|
|
|
'title', '-title', 'order', '-order', |
|
|
|
|
|
'total_time', '-total_time' |
|
|
] |
|
|
] |
|
|
|
|
|
|
|
|
if sort in allowed_sorts: |
|
|
if sort in allowed_sorts: |
|
|
# Handle multiple sort fields (e.g., '-pin,-created_at') |
|
|
|
|
|
if ',' in sort: |
|
|
if ',' in sort: |
|
|
queryset = queryset.order_by(*sort.split(',')) |
|
|
queryset = queryset.order_by(*sort.split(',')) |
|
|
else: |
|
|
else: |
|
|
@ -382,7 +388,7 @@ class VideoListAPIView(generics.ListAPIView): |
|
|
else: |
|
|
else: |
|
|
queryset = queryset.order_by('-created_at') |
|
|
queryset = queryset.order_by('-created_at') |
|
|
|
|
|
|
|
|
return queryset.distinct() |
|
|
|
|
|
|
|
|
return queryset |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VideoPlaylistDetailAPIView(generics.RetrieveAPIView): |
|
|
class VideoPlaylistDetailAPIView(generics.RetrieveAPIView): |
|
|
@ -415,7 +421,7 @@ class VideoPlaylistDetailAPIView(generics.RetrieveAPIView): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VideoDetailAPIView(Gone410ViewMixin, CanonicalSlugViewSetMixin, generics.RetrieveAPIView): |
|
|
class VideoDetailAPIView(Gone410ViewMixin, CanonicalSlugViewSetMixin, generics.RetrieveAPIView): |
|
|
serializer_class = VideoDetailSerializer |
|
|
|
|
|
|
|
|
serializer_class = VideoPlaylistDetailSerializer |
|
|
permission_classes = (IsAuthenticated,) |
|
|
permission_classes = (IsAuthenticated,) |
|
|
authentication_classes = [TokenAuthentication] |
|
|
authentication_classes = [TokenAuthentication] |
|
|
lookup_field = 'slug' |
|
|
lookup_field = 'slug' |
|
|
@ -424,12 +430,12 @@ class VideoDetailAPIView(Gone410ViewMixin, CanonicalSlugViewSetMixin, generics.R |
|
|
active_expected_value = True |
|
|
active_expected_value = True |
|
|
|
|
|
|
|
|
@swagger_auto_schema( |
|
|
@swagger_auto_schema( |
|
|
operation_description="Get video details by slug", |
|
|
|
|
|
|
|
|
operation_description="Get video playlist details by slug", |
|
|
tags=["Dobodbi - Video"], |
|
|
tags=["Dobodbi - Video"], |
|
|
responses={ |
|
|
responses={ |
|
|
200: openapi.Response( |
|
|
200: openapi.Response( |
|
|
description="Video details", |
|
|
|
|
|
schema=VideoDetailSerializer() |
|
|
|
|
|
|
|
|
description="Video playlist details", |
|
|
|
|
|
schema=VideoPlaylistDetailSerializer() |
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|
) |
|
|
) |
|
|
@ -437,13 +443,13 @@ class VideoDetailAPIView(Gone410ViewMixin, CanonicalSlugViewSetMixin, generics.R |
|
|
return super().get(request, *args, **kwargs) |
|
|
return super().get(request, *args, **kwargs) |
|
|
|
|
|
|
|
|
def get_queryset(self): |
|
|
def get_queryset(self): |
|
|
return Video.objects.all() |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
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): |
|
|
class DovodiVideoCategoryViewSet(ModelViewSet): |
|
|
|