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.
 
 

327 lines
12 KiB

from rest_framework import serializers
from utils import get_thumbs
from apps.podcast.models import *
from apps.bookmark.serializers import *
class PodcastCategoryListSerializer(serializers.ModelSerializer):
playlist_count = serializers.SerializerMethodField()
class Meta:
model = PodcastCategory
fields = ['id', 'title', 'slug', 'playlist_count']
def get_playlist_count(self, obj):
return obj.playlists.filter(status=True).count()
class PodcastListSerializer(serializers.ModelSerializer):
thumbnail = serializers.SerializerMethodField()
audio_file = serializers.SerializerMethodField()
in_user_playlist = serializers.SerializerMethodField()
share_link = serializers.CharField(read_only=True)
class Meta:
model = Podcast
fields = ['id', 'title', 'slug', 'thumbnail', 'description', 'audio_file',
'audio_time', 'view_count', 'created_at', 'in_user_playlist', 'share_link']
def get_thumbnail(self, obj):
return get_thumbs(obj.thumbnail, self.context.get('request'))
def get_audio_file(self, obj):
"""Get full URL for audio file if it exists"""
if obj.audio_file:
request = self.context.get('request')
if request:
return request.build_absolute_uri(obj.audio_file.url)
return obj.audio_file.url
return None
def get_in_user_playlist(self, obj):
"""
Check if the podcast is in the user's personal playlist.
Returns True if the podcast is in the user's playlist and active, False otherwise.
"""
request = self.context.get('request')
user = request.user if request and request.user.is_authenticated else None
if not user:
return False
return UserPlaylist.is_in_user_playlist(user, obj)
class PodcastDetailSerializer(serializers.ModelSerializer):
categories = PodcastCategoryListSerializer(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_podcasts = serializers.SerializerMethodField()
in_user_playlist = serializers.SerializerMethodField()
share_link = serializers.CharField(read_only=True)
class Meta:
model = Podcast
fields = ['id', 'title', 'slug', 'thumbnail', 'description',
'audio_file', 'audio_time', 'view_count', 'download_count',
'categories', 'created_at', 'user_rate', 'average_rate', 'bookmark',
'is_in_playlist', 'playlist_podcasts', 'in_user_playlist', 'share_link']
def get_thumbnail(self, obj):
return get_thumbs(obj.thumbnail, self.context.get('request'))
def get_bookmark(self, obj):
"""
Get bookmark information for this podcast.
"""
# 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='podcast'
)
return book_mark.get('is_bookmarked', False)
def get_user_rate(self, obj):
"""
Get rate information for this podcast 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='podcast',
content_id=obj.id
)
return rate_info
def get_average_rate(self, obj):
"""
Get the average rate for this podcast.
"""
from apps.bookmark.models.rate import Rate
# Get average rate information using the Rate model
return Rate.get_average_rate(
service='podcast',
content_id=obj.id
)
def get_is_in_playlist(self, obj):
"""
Check if the podcast is in any playlist.
Returns True if the podcast is in at least one playlist, False otherwise.
"""
return PlaylistItem.objects.filter(podcast=obj).exists()
def get_playlist_podcasts(self, obj):
"""
If the podcast is in a playlist, return all podcasts from the first playlist it belongs to,
excluding the current podcast itself. Podcasts are ordered by their priority in the playlist.
Returns null if the podcast is not in any playlist.
"""
# Check if the podcast is in any playlist
if not self.get_is_in_playlist(obj):
return None
# Get the first playlist that contains this podcast
playlist_item = PlaylistItem.objects.filter(podcast=obj).first()
if not playlist_item:
return None
playlist = playlist_item.playlist
# Get all podcasts in this playlist except the current one, ordered by priority
playlist_podcasts = Podcast.objects.filter(
playlist_appearances__playlist=playlist
).exclude(
id=obj.id
).distinct().order_by('playlist_appearances__priority')
# Serialize the podcasts
return PodcastListSerializer(
playlist_podcasts,
many=True,
context=self.context
).data
def get_in_user_playlist(self, obj):
"""
Check if the podcast is in the user's personal playlist.
Returns True if the podcast is in the user's playlist and active, False otherwise.
"""
request = self.context.get('request')
user = request.user if request and request.user.is_authenticated else None
if not user:
return False
return UserPlaylist.is_in_user_playlist(user, obj)
class PinnedPodcastCollectionSerializer(serializers.ModelSerializer):
thumbnail = serializers.SerializerMethodField()
class Meta:
model = PodcastCollection
fields = ['id', 'title', 'slug', 'summary', 'thumbnail', 'order', 'created_at']
def get_thumbnail(self, obj):
return get_thumbs(obj.thumbnail, self.context.get('request'))
class PodcastPlaylistListSerializer(serializers.ModelSerializer):
thumbnail = serializers.SerializerMethodField()
total_time_formatted = serializers.SerializerMethodField()
episodes_count = serializers.SerializerMethodField()
class Meta:
model = PodcastPlaylist
fields = ['id', 'title', 'slug', 'thumbnail', 'slogan', 'view_count', 'total_time_formatted', 'episodes_count', '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"
def get_episodes_count(self, obj):
"""Return the number of episodes (podcasts) in this playlist"""
return obj.playlist_items.count()
class PodcastPlaylistDetailSerializer(serializers.ModelSerializer):
categories = PodcastCategoryListSerializer(many=True, read_only=True)
thumbnail = serializers.SerializerMethodField()
bookmark = serializers.SerializerMethodField()
user_rate = serializers.SerializerMethodField()
average_rate = serializers.SerializerMethodField()
podcasts = serializers.SerializerMethodField()
total_time_formatted = serializers.SerializerMethodField()
class Meta:
model = PodcastPlaylist
fields = ['id', 'title', 'slug', 'thumbnail', 'slogan', 'description',
'view_count', 'total_time_formatted', 'order', 'status',
'categories', 'created_at', 'user_rate', 'average_rate', 'bookmark', 'podcasts']
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='podcast'
)
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='podcast',
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='podcast',
content_id=obj.id
)
def get_podcasts(self, obj):
"""Get all podcasts in this playlist ordered by priority."""
podcasts = Podcast.objects.filter(
playlist_appearances__playlist=obj
).distinct().order_by('playlist_appearances__priority')
return PodcastListSerializer(
podcasts,
many=True,
context=self.context
).data
class MiddlePodcastCollectionSerializer(serializers.ModelSerializer):
playlists = serializers.SerializerMethodField()
class Meta:
model = PodcastCollection
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 PodcastPlaylistListSerializer(playlists, many=True, context=self.context).data
class UserPlaylistSerializer(serializers.ModelSerializer):
class Meta:
model = UserPlaylist
fields = ('id', 'podcast', 'status', 'created_at', 'updated_at')
read_only_fields = ('id', 'created_at', 'updated_at')
class UserPlaylistCreateSerializer(serializers.Serializer):
podcast_id = serializers.IntegerField()
status = serializers.BooleanField(default=True)
def validate_podcast_id(self, value):
try:
podcast = Podcast.objects.get(id=value, status=True)
return value
except Podcast.DoesNotExist:
raise serializers.ValidationError("Podcast with this ID does not exist or is not active.")