110 lines
3.6 KiB
Python
110 lines
3.6 KiB
Python
from django.conf import settings
|
|
from django.utils import timezone
|
|
from rest_framework import serializers
|
|
from rest_framework_gis.serializers import GeoFeatureModelSerializer
|
|
|
|
from apps.utils.storage import generate_presigned_put_url, preview_url
|
|
from .models import Splat
|
|
|
|
|
|
class SplatJobSummarySerializer(serializers.Serializer):
|
|
"""Inlined job status — used in SplatMineSerializer."""
|
|
id = serializers.UUIDField()
|
|
status = serializers.CharField()
|
|
current_step = serializers.CharField()
|
|
progress = serializers.IntegerField()
|
|
error_message = serializers.CharField()
|
|
queued_at = serializers.DateTimeField()
|
|
started_at = serializers.DateTimeField()
|
|
finished_at = serializers.DateTimeField()
|
|
|
|
|
|
class SplatCreateSerializer(serializers.ModelSerializer):
|
|
challenge_id = serializers.UUIDField(required=False, allow_null=True)
|
|
capture_metadata = serializers.JSONField()
|
|
|
|
class Meta:
|
|
model = Splat
|
|
fields = ["challenge_id", "capture_metadata"]
|
|
|
|
def validate_capture_metadata(self, value):
|
|
frames = value.get("frames", [])
|
|
min_frames = settings.MIN_CAPTURE_FRAMES
|
|
if len(frames) < min_frames:
|
|
raise serializers.ValidationError(
|
|
f"capture_metadata must contain at least {min_frames} frames; "
|
|
f"got {len(frames)}."
|
|
)
|
|
return value
|
|
|
|
|
|
class SplatCreateResponseSerializer(serializers.Serializer):
|
|
"""Shape of the POST /splats/ response — not a ModelSerializer."""
|
|
id = serializers.UUIDField()
|
|
status = serializers.CharField()
|
|
upload_url = serializers.CharField(allow_null=True)
|
|
upload_expires_at = serializers.DateTimeField()
|
|
|
|
|
|
class SplatMapSerializer(GeoFeatureModelSerializer):
|
|
"""GeoJSON FeatureCollection for the map tile endpoint."""
|
|
preview_url = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Splat
|
|
geo_field = "location"
|
|
fields = ["id", "heading", "altitude", "preview_url", "splat_file_size", "created_at"]
|
|
|
|
def get_preview_url(self, obj):
|
|
return preview_url(obj.preview_key)
|
|
|
|
|
|
class SplatDetailSerializer(serializers.ModelSerializer):
|
|
coverage = serializers.SerializerMethodField()
|
|
preview_url = serializers.SerializerMethodField()
|
|
owner_username = serializers.CharField(source="owner.username", read_only=True)
|
|
challenge_id = serializers.UUIDField(read_only=True)
|
|
|
|
class Meta:
|
|
model = Splat
|
|
fields = [
|
|
"id", "owner_username", "challenge_id", "status", "is_published",
|
|
"location", "coverage", "heading", "altitude",
|
|
"preview_url", "splat_file_size",
|
|
"quality_score", "frame_count",
|
|
"created_at", "updated_at",
|
|
]
|
|
|
|
def get_coverage(self, obj):
|
|
if obj.coverage:
|
|
return obj.coverage.geojson
|
|
return None
|
|
|
|
def get_preview_url(self, obj):
|
|
return preview_url(obj.preview_key)
|
|
|
|
|
|
class SplatMineSerializer(serializers.ModelSerializer):
|
|
job = serializers.SerializerMethodField()
|
|
preview_url = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Splat
|
|
fields = [
|
|
"id", "status", "is_published",
|
|
"challenge_id", "preview_url",
|
|
"quality_score", "frame_count",
|
|
"created_at", "updated_at",
|
|
"job",
|
|
]
|
|
|
|
def get_job(self, obj):
|
|
try:
|
|
j = obj.job
|
|
except Splat.job.RelatedObjectDoesNotExist:
|
|
return None
|
|
return SplatJobSummarySerializer(j).data
|
|
|
|
def get_preview_url(self, obj):
|
|
return preview_url(obj.preview_key)
|