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.
 
 

266 lines
9.3 KiB

from rest_framework import serializers
from utils import get_thumbs
from .models import VideoCategory, Video, VideoCollection, VideoPlaylist, PlaylistItem, PinnedVideoCollection
from apps.bookmark.serializers import *
class VideoCategoryListSerializer(serializers.ModelSerializer):
playlist_count = serializers.SerializerMethodField()
class Meta:
model = VideoCategory
fields = ['id', 'title', 'slug', 'playlist_count']
def get_playlist_count(self, obj):
return obj.playlists.filter(status=True).count()
class VideoListSerializer(serializers.ModelSerializer):
thumbnail = serializers.SerializerMethodField()
class Meta:
model = Video
fields = ['id', 'title', 'slug', 'thumbnail', 'description', 'video_time', 'view_count', 'created_at']
def get_thumbnail(self, obj):
return get_thumbs(obj.thumbnail, self.context.get('request'))
class VideoPlaylistListSerializer(serializers.ModelSerializer):
thumbnail = serializers.SerializerMethodField()
total_time_formatted = serializers.SerializerMethodField()
class Meta:
model = VideoPlaylist
fields = ['id', 'title', 'slug', 'thumbnail', 'slogan', 'view_count', 'total_time_formatted', 'order', 'created_at']
def get_thumbnail(self, obj):
return get_thumbs(obj.thumbnail, self.context.get('request'))
def get_total_time_formatted(self, obj):
"""Format total_time as HH:MM:SS string"""
if obj.total_time:
total_seconds = int(obj.total_time.total_seconds())
hours = total_seconds // 3600
minutes = (total_seconds % 3600) // 60
seconds = total_seconds % 60
return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
return "00:00:00"
class VideoPlaylistDetailSerializer(serializers.ModelSerializer):
categories = VideoCategoryListSerializer(many=True, read_only=True)
thumbnail = serializers.SerializerMethodField()
bookmark = serializers.SerializerMethodField()
user_rate = serializers.SerializerMethodField()
average_rate = serializers.SerializerMethodField()
videos = serializers.SerializerMethodField()
total_time_formatted = serializers.SerializerMethodField()
class Meta:
model = VideoPlaylist
fields = ['id', 'title', 'slug', 'thumbnail', 'slogan', 'description',
'view_count', 'total_time_formatted', 'order', 'status',
'categories', 'created_at', 'user_rate', 'average_rate', 'bookmark', 'videos']
def get_thumbnail(self, obj):
return get_thumbs(obj.thumbnail, self.context.get('request'))
def get_total_time_formatted(self, obj):
"""Format total_time as HH:MM:SS string"""
if obj.total_time:
total_seconds = int(obj.total_time.total_seconds())
hours = total_seconds // 3600
minutes = (total_seconds % 3600) // 60
seconds = total_seconds % 60
return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
return "00:00:00"
def get_bookmark(self, obj):
"""Get bookmark information for this playlist."""
request = self.context.get('request')
user = request.user if request else None
book_mark = BookmarkStatusSerializer.get_bookmark_info(
obj=obj,
user=user,
service='video_playlist'
)
return book_mark.get('is_bookmarked', False)
def get_user_rate(self, obj):
"""Get rate information for this playlist from the current user."""
from apps.bookmark.models.rate import Rate
request = self.context.get('request')
user = request.user if request and request.user.is_authenticated else None
if not user:
return {
'is_rated': False,
'rate': None
}
rate_info = Rate.get_user_rate(
user=user,
service='video_playlist',
content_id=obj.id
)
return rate_info
def get_average_rate(self, obj):
"""Get the average rate for this playlist."""
from apps.bookmark.models.rate import Rate
return Rate.get_average_rate(
service='video_playlist',
content_id=obj.id
)
def get_videos(self, obj):
"""Get all videos in this playlist ordered by priority."""
videos = Video.objects.filter(
playlist_appearances__playlist=obj
).distinct().order_by('playlist_appearances__priority')
return VideoListSerializer(
videos,
many=True,
context=self.context
).data
class VideoDetailSerializer(serializers.ModelSerializer):
categories = VideoCategoryListSerializer(many=True, read_only=True)
thumbnail = serializers.SerializerMethodField()
bookmark = serializers.SerializerMethodField()
user_rate = serializers.SerializerMethodField()
average_rate = serializers.SerializerMethodField()
is_in_playlist = serializers.SerializerMethodField()
playlist_videos = serializers.SerializerMethodField()
class Meta:
model = Video
fields = ['id', 'title', 'slug', 'thumbnail', 'description', 'video_type',
'video_file', 'video_url', 'video_time', 'view_count',
'categories', 'created_at', 'user_rate', 'average_rate', 'bookmark',
'is_in_playlist', 'playlist_videos']
def get_thumbnail(self, obj):
return get_thumbs(obj.thumbnail, self.context.get('request'))
def get_bookmark(self, obj):
"""
Get bookmark information for this book.
"""
# Get the current user from the request context
request = self.context.get('request')
user = request.user if request else None
book_mark = BookmarkStatusSerializer.get_bookmark_info(
obj=obj,
user=user,
service='video'
)
return book_mark.get('is_bookmarked', False)
def get_user_rate(self, obj):
"""
Get rate information for this book from the current user.
"""
from apps.bookmark.models.rate import Rate
# Get the current user from the request context
request = self.context.get('request')
user = request.user if request and request.user.is_authenticated else None
if not user:
return {
'is_rated': False,
'rate': None
}
# Get rate information using the Rate model's method
rate_info = Rate.get_user_rate(
user=user,
service='video',
content_id=obj.id
)
return rate_info
def get_average_rate(self, obj):
"""
Get the average rate for this video.
"""
from apps.bookmark.models.rate import Rate
# Get average rate information using the Rate model
return Rate.get_average_rate(
service='video',
content_id=obj.id
)
def get_is_in_playlist(self, obj):
"""
Check if the video is in any playlist.
Returns True if the video is in at least one playlist, False otherwise.
"""
return PlaylistItem.objects.filter(video=obj).exists()
def get_playlist_videos(self, obj):
"""
If the video is in a playlist, return all videos from the first playlist it belongs to,
excluding the current video itself. Videos are ordered by their priority in the playlist.
Returns null if the video is not in any playlist.
"""
# Check if the video is in any playlist
if not self.get_is_in_playlist(obj):
return None
# Get the first playlist that contains this video
playlist_item = PlaylistItem.objects.filter(video=obj).first()
if not playlist_item:
return None
playlist = playlist_item.playlist
# Get all videos in this playlist except the current one, ordered by priority
playlist_videos = Video.objects.filter(
playlist_appearances__playlist=playlist
).exclude(
id=obj.id
).distinct().order_by('playlist_appearances__priority')
# Serialize the videos
return VideoListSerializer(
playlist_videos,
many=True,
context=self.context
).data
class PinnedVideoCollectionSerializer(serializers.ModelSerializer):
thumbnail = serializers.SerializerMethodField()
class Meta:
model = VideoCollection
fields = ['id', 'title', 'slug', 'summary', 'thumbnail', 'order', 'created_at']
def get_thumbnail(self, obj):
return get_thumbs(obj.thumbnail, self.context.get('request'))
class MiddleVideoCollectionSerializer(serializers.ModelSerializer):
playlists = serializers.SerializerMethodField()
class Meta:
model = VideoCollection
fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'pin_top','playlists')
def get_playlists(self, obj):
playlists = obj.related_playlists.filter(status=True).order_by('order', '-created_at')
return VideoPlaylistListSerializer(playlists, many=True, context=self.context).data