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() in_user_playlist = serializers.SerializerMethodField() class Meta: model = Podcast fields = ['id', 'title', 'slug', 'thumbnail', 'description', 'audio_time', 'view_count', 'created_at', 'in_user_playlist'] def get_thumbnail(self, obj): return get_thumbs(obj.thumbnail, self.context.get('request')) 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() 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'] 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() class Meta: model = PodcastPlaylist 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 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_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='podcast_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='podcast_playlist', 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.")