""" Media domain serializers for ThrillWiki API v1. This module contains serializers for photo uploads, media management, and related media functionality. """ from rest_framework import serializers from drf_spectacular.utils import ( extend_schema_serializer, extend_schema_field, OpenApiExample, ) # === MEDIA UPLOAD SERIALIZERS === @extend_schema_serializer( examples=[ OpenApiExample( "Photo Upload Example", summary="Example photo upload request", description="Upload a photo for a park or ride", value={ "photo": "file_upload", "app_label": "parks", "model": "park", "object_id": 123, "caption": "Beautiful view of the park entrance", "alt_text": "Park entrance with landscaping", "is_primary": True, "photo_type": "general", }, ) ] ) class PhotoUploadInputSerializer(serializers.Serializer): """Input serializer for photo uploads.""" photo = serializers.ImageField( help_text="The image file to upload" ) app_label = serializers.CharField( max_length=100, help_text="App label of the content object (e.g., 'parks', 'rides')" ) model = serializers.CharField( max_length=100, help_text="Model name of the content object (e.g., 'park', 'ride')" ) object_id = serializers.IntegerField( help_text="ID of the content object" ) caption = serializers.CharField( max_length=500, required=False, allow_blank=True, help_text="Optional caption for the photo" ) alt_text = serializers.CharField( max_length=255, required=False, allow_blank=True, help_text="Optional alt text for accessibility" ) is_primary = serializers.BooleanField( default=False, help_text="Whether this should be the primary photo" ) photo_type = serializers.CharField( max_length=50, default="general", required=False, help_text="Type of photo (for rides: 'general', 'on_ride', 'construction', etc.)" ) class PhotoUploadOutputSerializer(serializers.Serializer): """Output serializer for photo uploads.""" id = serializers.IntegerField() url = serializers.CharField() caption = serializers.CharField() alt_text = serializers.CharField() is_primary = serializers.BooleanField() message = serializers.CharField() # === PHOTO DETAIL SERIALIZERS === @extend_schema_serializer( examples=[ OpenApiExample( "Photo Detail Example", summary="Example photo detail response", description="A photo with full details", value={ "id": 1, "url": "https://example.com/media/photos/ride123.jpg", "thumbnail_url": "https://example.com/media/thumbnails/ride123_thumb.jpg", "caption": "Amazing view of Steel Vengeance", "alt_text": "Steel Vengeance roller coaster with blue sky", "is_primary": True, "uploaded_at": "2024-08-15T10:30:00Z", "uploaded_by": { "id": 1, "username": "coaster_photographer", "display_name": "Coaster Photographer", }, "content_type": "Ride", "object_id": 123, "file_size": 2048576, "width": 1920, "height": 1080, "format": "JPEG", }, ) ] ) class PhotoDetailOutputSerializer(serializers.Serializer): """Output serializer for photo details.""" id = serializers.IntegerField() url = serializers.URLField() thumbnail_url = serializers.URLField(required=False) caption = serializers.CharField() alt_text = serializers.CharField() is_primary = serializers.BooleanField() uploaded_at = serializers.DateTimeField() content_type = serializers.CharField() object_id = serializers.IntegerField() # File metadata file_size = serializers.IntegerField() width = serializers.IntegerField() height = serializers.IntegerField() format = serializers.CharField() # Uploader info uploaded_by = serializers.SerializerMethodField() @extend_schema_field(serializers.DictField()) def get_uploaded_by(self, obj) -> dict: """Get uploader information.""" return { "id": obj.uploaded_by.id, "username": obj.uploaded_by.username, "display_name": getattr( obj.uploaded_by, "get_display_name", lambda: obj.uploaded_by.username )(), } class PhotoListOutputSerializer(serializers.Serializer): """Output serializer for photo list view.""" id = serializers.IntegerField() url = serializers.URLField() thumbnail_url = serializers.URLField(required=False) caption = serializers.CharField() is_primary = serializers.BooleanField() uploaded_at = serializers.DateTimeField() uploaded_by = serializers.SerializerMethodField() @extend_schema_field(serializers.DictField()) def get_uploaded_by(self, obj) -> dict: """Get uploader information.""" return { "id": obj.uploaded_by.id, "username": obj.uploaded_by.username, } class PhotoUpdateInputSerializer(serializers.Serializer): """Input serializer for updating photos.""" caption = serializers.CharField(max_length=500, required=False, allow_blank=True) alt_text = serializers.CharField(max_length=255, required=False, allow_blank=True) is_primary = serializers.BooleanField(required=False) # === MEDIA STATS SERIALIZERS === class MediaStatsOutputSerializer(serializers.Serializer): """Output serializer for media statistics.""" total_photos = serializers.IntegerField() photos_by_content_type = serializers.DictField() recent_uploads = serializers.IntegerField() top_uploaders = serializers.ListField() storage_usage = serializers.DictField() # === BULK OPERATIONS SERIALIZERS === class BulkPhotoActionInputSerializer(serializers.Serializer): """Input serializer for bulk photo actions.""" photo_ids = serializers.ListField( child=serializers.IntegerField(), help_text="List of photo IDs to perform action on" ) action = serializers.ChoiceField( choices=[ ('delete', 'Delete'), ('approve', 'Approve'), ('reject', 'Reject'), ], help_text="Action to perform on selected photos" ) class BulkPhotoActionOutputSerializer(serializers.Serializer): """Output serializer for bulk photo actions.""" success_count = serializers.IntegerField() failed_count = serializers.IntegerField() errors = serializers.ListField(child=serializers.CharField(), required=False) message = serializers.CharField()