from utils import get_thumbs from django.db.models import Avg, Q from rest_framework import serializers from apps.library.models import * from apps.bookmark.serializers import * from apps.account.models import User class CategorySerializer(serializers.ModelSerializer): books_count = serializers.SerializerMethodField() class Meta: model = Category fields = ('id', 'title', 'slug', 'status', 'books_count', 'created_at', 'updated_at') def get_books_count(self, obj): # Use the annotation if available, otherwise fall back to the property if hasattr(obj, 'books_count_annotation'): return obj.books_count_annotation return obj.books_count class PinnedBookCollectionSerializer(serializers.ModelSerializer): covers = serializers.SerializerMethodField() def get_covers(self, obj: BookCollection): books = obj.books.all().order_by('-view_count')[:3] images = [] for book in books: if book.thumbnail: url = get_thumbs(book.thumbnail, self.context.get('request')) if url.get('md'): images.append(url['md']) return images class Meta: model = BookCollection fields = ('id', 'title', 'summary', 'covers') class BookSerializer(serializers.ModelSerializer): thumbnail = serializers.SerializerMethodField() bookmark = serializers.SerializerMethodField() user_rate = serializers.SerializerMethodField() average_rate = serializers.SerializerMethodField() share_link = serializers.CharField(read_only=True) def get_thumbnail(self, obj): if obj.thumbnail: return get_thumbs(obj.thumbnail, self.context.get('request')) return None class Meta: model = Book fields = ( 'id', 'title', 'slug', 'summary', 'summary_title', 'thumbnail', 'slogan', 'status', 'pin', 'view_count', 'download_count', 'publisher', 'year_of_publication', 'author', 'isbn', 'numnber_of_volume', 'language', 'main_themes', 'notable_works', 'file_type', 'book_file', 'created_at', 'bookmark', 'user_rate', 'average_rate', 'share_link' ) def get_bookmark(self, obj): """ Get bookmark information for this book. """ # DEBUG: Hardcode user to root@admin.com # user = User.objects.get(email='root@admin.com') # # 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='library' ) 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 # DEBUG: Hardcode user to root@admin.com # user = User.objects.get(email='root@admin.com') # # 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='library', content_id=obj.id ) return rate_info def get_average_rate(self, obj): """ Get the average rate for this book. """ from apps.bookmark.models.rate import Rate # Get average rate using the Rate model's method avg_rate = Rate.get_average_rate( service='library', content_id=obj.id ) return avg_rate class MiddleBookCollectionSerializer(serializers.ModelSerializer): """Serializer for Middle Book Collections with their books""" books = serializers.SerializerMethodField() class Meta: model = BookCollection fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'books') def get_books(self, obj): """Get all books in this collection""" books = obj.books.filter(status=True).order_by('-view_count')[:8] return BookSerializer(books, many=True, context=self.context).data class BookDownloadSerializer(serializers.ModelSerializer): """Serializer for book downloads""" book_id = serializers.IntegerField(write_only=True) class Meta: model = BookDownload fields = ('id', 'book_id', 'created_at', 'updated_at', 'status') read_only_fields = ('id', 'created_at', 'updated_at', 'status') def validate_book_id(self, value): """Validate that the book exists and is active""" try: book = Book.objects.get(id=value, status=True) return value except Book.DoesNotExist: raise serializers.ValidationError("Book not found or inactive") def create(self, validated_data): """Create a new book download record""" book_id = validated_data.pop('book_id') # user = User.objects.get(email='root@admin.com') user = self.context['request'].user book = Book.objects.get(id=book_id) # Create or update the download record download, created = BookDownload.objects.update_or_create( user=user, book=book, defaults={'status': True} ) # Increment the book's download count book.download_count += 1 book.save(update_fields=['download_count']) return download