Add Django backend: users, admin, OTIO + scene persistence
A Project (owner, OTIO file, fps, scene JSON) persists the timeline. Session API: list projects, GET/PUT scene, serve OTIO. Admin manages users/projects; seed_demo creates a project from the bundled one_two_three.otio. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
7a960afb5c
commit
57ef570539
21 changed files with 406 additions and 0 deletions
56
scenes/views.py
Normal file
56
scenes/views.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import json
|
||||
|
||||
from django.http import FileResponse, HttpResponseNotAllowed, JsonResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from .models import Project
|
||||
|
||||
|
||||
def _auth(request):
|
||||
"""None if logged in, else a 401 JSON response (so fetch() doesn't get a
|
||||
login redirect)."""
|
||||
if not request.user.is_authenticated:
|
||||
return JsonResponse({"detail": "authentication required"}, status=401)
|
||||
return None
|
||||
|
||||
|
||||
def _owned(request, pk):
|
||||
return get_object_or_404(Project, pk=pk, owner=request.user)
|
||||
|
||||
|
||||
def projects(request):
|
||||
"""GET /api/projects/ — the current user's projects."""
|
||||
if (resp := _auth(request)):
|
||||
return resp
|
||||
rows = Project.objects.filter(owner=request.user).values("id", "name", "fps", "updated")
|
||||
return JsonResponse(list(rows), safe=False)
|
||||
|
||||
|
||||
@csrf_exempt # dev convenience: session-auth API without a CSRF token round-trip
|
||||
def scene(request, pk):
|
||||
"""GET/PUT /api/projects/<pk>/scene/ — read or replace the timeline scene."""
|
||||
if (resp := _auth(request)):
|
||||
return resp
|
||||
project = _owned(request, pk)
|
||||
if request.method == "GET":
|
||||
return JsonResponse({"fps": project.fps, "scene": project.scene})
|
||||
if request.method == "PUT":
|
||||
data = json.loads(request.body or "{}")
|
||||
if "scene" in data:
|
||||
project.scene = data["scene"]
|
||||
if "fps" in data:
|
||||
project.fps = data["fps"]
|
||||
project.save(update_fields=["scene", "fps", "updated"])
|
||||
return JsonResponse({"ok": True, "updated": project.updated})
|
||||
return HttpResponseNotAllowed(["GET", "PUT"])
|
||||
|
||||
|
||||
def otio(request, pk):
|
||||
"""GET /api/projects/<pk>/otio/ — serve the uploaded OTIO file."""
|
||||
if (resp := _auth(request)):
|
||||
return resp
|
||||
project = _owned(request, pk)
|
||||
if not project.otio:
|
||||
return JsonResponse({"detail": "no otio uploaded"}, status=404)
|
||||
return FileResponse(project.otio.open("rb"), content_type="application/json")
|
||||
Loading…
Add table
Add a link
Reference in a new issue