Initial commit: Aurora Moments self-hosted photo/video sharing platform
Django/DRF + PostgreSQL/Redis/Celery backend with accounts, library, moments, and notifications apps; React/TypeScript/Vite frontend with Instagram-style sidebar nav, feed, profiles, nested comment replies, notifications, and photo/video upload with ffmpeg-generated posters. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import hashlib
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from apps.accounts.models import User
|
||||
from apps.accounts.serializers import UserSerializer
|
||||
|
||||
from .models import Album, AlbumCollaborator, AlbumItem, LibraryItem, MediaRendition
|
||||
|
||||
|
||||
class MediaRenditionSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = MediaRendition
|
||||
fields = ["kind", "file", "width", "height"]
|
||||
|
||||
|
||||
class LibraryItemSerializer(serializers.ModelSerializer):
|
||||
renditions = MediaRenditionSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = LibraryItem
|
||||
fields = [
|
||||
"id", "file", "media_type", "original_filename", "file_size",
|
||||
"width", "height", "duration_seconds", "captured_at",
|
||||
"latitude", "longitude", "camera_make", "camera_model",
|
||||
"processing_status", "renditions", "created_at",
|
||||
]
|
||||
read_only_fields = [
|
||||
"id", "width", "height", "duration_seconds", "captured_at",
|
||||
"camera_make", "camera_model", "processing_status", "renditions", "created_at",
|
||||
]
|
||||
|
||||
def create(self, validated_data):
|
||||
upload = validated_data["file"]
|
||||
checksum = hashlib.sha256(upload.read()).hexdigest()
|
||||
upload.seek(0)
|
||||
validated_data["checksum"] = checksum
|
||||
validated_data["file_size"] = upload.size
|
||||
validated_data.setdefault("original_filename", upload.name)
|
||||
validated_data["owner"] = self.context["request"].user
|
||||
library_item, _created = LibraryItem.objects.get_or_create(
|
||||
owner=validated_data["owner"],
|
||||
checksum=checksum,
|
||||
defaults=validated_data,
|
||||
)
|
||||
return library_item
|
||||
|
||||
|
||||
class AlbumItemSerializer(serializers.ModelSerializer):
|
||||
library_item = LibraryItemSerializer(read_only=True)
|
||||
library_item_id = serializers.PrimaryKeyRelatedField(
|
||||
queryset=LibraryItem.objects.all(), source="library_item", write_only=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = AlbumItem
|
||||
fields = ["id", "album", "library_item", "library_item_id", "added_by", "added_at"]
|
||||
read_only_fields = ["id", "album", "added_by", "added_at"]
|
||||
|
||||
|
||||
class AlbumCollaboratorSerializer(serializers.ModelSerializer):
|
||||
user = UserSerializer(read_only=True)
|
||||
user_id = serializers.PrimaryKeyRelatedField(
|
||||
queryset=User.objects.all(), source="user", write_only=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = AlbumCollaborator
|
||||
fields = ["id", "album", "user", "user_id", "role", "status", "invited_by"]
|
||||
read_only_fields = ["id", "album", "status", "invited_by"]
|
||||
|
||||
|
||||
class AlbumSerializer(serializers.ModelSerializer):
|
||||
items = AlbumItemSerializer(many=True, read_only=True)
|
||||
collaborators = AlbumCollaboratorSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Album
|
||||
fields = [
|
||||
"id", "owner", "name", "description", "cover_item", "audience",
|
||||
"items", "collaborators", "created_at", "updated_at",
|
||||
]
|
||||
read_only_fields = ["id", "owner", "items", "collaborators", "created_at", "updated_at"]
|
||||
Reference in New Issue
Block a user