Archived
Reviewed and merged by Reid (Hermes Reviewer) Co-authored-by: crisleo-hermes <hermes@codescripters.org> Co-committed-by: crisleo-hermes <hermes@codescripters.org>
120 lines
4.4 KiB
Python
120 lines
4.4 KiB
Python
from rest_framework import serializers
|
|
|
|
from apps.books.models import Book, EBook, FontStyle, BackgroundColor, ReadingProgress, ReadingSettings, ReadingStatus
|
|
|
|
|
|
class BookListSerializer(serializers.ModelSerializer):
|
|
reading_status_display = serializers.CharField(source="get_reading_status_display", read_only=True)
|
|
|
|
class Meta:
|
|
model = Book
|
|
fields = ["id", "title", "author", "genre", "reading_status", "reading_status_display", "cover_image"]
|
|
|
|
|
|
class BookDetailSerializer(serializers.ModelSerializer):
|
|
reading_status_display = serializers.CharField(source="get_reading_status_display", read_only=True)
|
|
|
|
class Meta:
|
|
model = Book
|
|
fields = ["id", "title", "author", "genre", "description", "reading_status", "reading_status_display", "cover_image", "total_pages", "created_at", "updated_at"]
|
|
read_only_fields = ["id", "created_at", "updated_at"]
|
|
|
|
|
|
class BookSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Book
|
|
fields = ["id", "title", "author", "genre", "description", "reading_status", "cover_image", "total_pages", "created_at", "updated_at"]
|
|
read_only_fields = ["id", "created_at", "updated_at"]
|
|
|
|
|
|
class EBookListSerializer(serializers.ModelSerializer):
|
|
filename = serializers.CharField(read_only=True)
|
|
progress = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = EBook
|
|
fields = ["id", "title", "author", "filename", "cover_image", "created_at", "progress"]
|
|
|
|
def get_progress(self, obj):
|
|
try:
|
|
return obj.reading_progress.current_position
|
|
except ReadingProgress.DoesNotExist:
|
|
return None
|
|
|
|
|
|
class EBookDetailSerializer(serializers.ModelSerializer):
|
|
filename = serializers.CharField(read_only=True)
|
|
file_url = serializers.SerializerMethodField()
|
|
progress = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = EBook
|
|
fields = ["id", "title", "author", "filename", "file_url", "cover_image", "created_at", "updated_at", "progress"]
|
|
|
|
def get_file_url(self, obj):
|
|
request = self.context.get("request")
|
|
if request and obj.file:
|
|
return request.build_absolute_uri(obj.file.url)
|
|
return ""
|
|
|
|
def get_progress(self, obj):
|
|
try:
|
|
rp = obj.reading_progress
|
|
return {"current_position": rp.current_position, "last_page": rp.last_page}
|
|
except ReadingProgress.DoesNotExist:
|
|
return None
|
|
|
|
|
|
class EBookUploadSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = EBook
|
|
fields = ["title", "author", "file", "cover_image"]
|
|
extra_kwargs = {"title": {"required": True}, "file": {"required": True}}
|
|
|
|
def validate_file(self, value):
|
|
import os
|
|
if value is None:
|
|
return value
|
|
ext = os.path.splitext(str(getattr(value, "name", "")))[1].lower()
|
|
if ext not in (".epub", ".pdf"):
|
|
raise serializers.ValidationError("Only EPUB and PDF files are supported.")
|
|
return value
|
|
|
|
def create(self, validated_data):
|
|
validated_data["user"] = self.context["request"].user
|
|
return super().create(validated_data)
|
|
|
|
|
|
class ReadingProgressSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = ReadingProgress
|
|
fields = ["current_position", "last_page"]
|
|
extra_kwargs = {"current_position": {"required": True, "min_value": 0.0, "max_value": 100.0}}
|
|
|
|
def validate_current_position(self, value):
|
|
if value < 0.0 or value > 100.0:
|
|
raise serializers.ValidationError("Position must be between 0.0 and 100.0.")
|
|
return value
|
|
|
|
|
|
class ReadingSettingsSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = ReadingSettings
|
|
fields = ["font_size", "font_style", "background_color"]
|
|
|
|
def validate_font_size(self, value):
|
|
if value < 12 or value > 36:
|
|
raise serializers.ValidationError("Font size must be between 12 and 36.")
|
|
return value
|
|
|
|
def validate_font_style(self, value):
|
|
valid = [s.value for s in FontStyle]
|
|
if value not in valid:
|
|
raise serializers.ValidationError(f"Font style must be one of: {', '.join(valid)}")
|
|
return value
|
|
|
|
def validate_background_color(self, value):
|
|
valid = [c.value for c in BackgroundColor]
|
|
if value not in valid:
|
|
raise serializers.ValidationError(f"Background color must be one of: {', '.join(valid)}")
|
|
return value |