Files
2026-01-27 17:40:37 +01:00

97 lines
3.0 KiB
Python

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from sqlalchemy.orm import selectinload
from typing import List
from uuid import UUID
from app.db.session import get_db
from app.models.project import Project as ProjectModel
from app.models.scene import Scene as SceneModel
from app.models.shot import Shot as ShotModel
from app.schemas.project import Project, ProjectCreate
from app.schemas.script import ScriptAnalysisResponse
router = APIRouter()
@router.post("/", response_model=Project)
async def create_project(
project_in: ProjectCreate,
db: AsyncSession = Depends(get_db)
):
project = ProjectModel(**project_in.model_dump())
db.add(project)
await db.commit()
await db.refresh(project)
return project
@router.get("/", response_model=List[Project])
async def list_projects(
skip: int = 0,
limit: int = 100,
db: AsyncSession = Depends(get_db)
):
result = await db.execute(select(ProjectModel).offset(skip).limit(limit))
return result.scalars().all()
@router.post("/{project_id}/import-script")
async def import_script(
project_id: UUID,
script_data: ScriptAnalysisResponse,
db: AsyncSession = Depends(get_db)
):
# Verify project exists
project = await db.get(ProjectModel, project_id)
if not project:
raise HTTPException(status_code=404, detail="Project not found")
# Clear existing scenes/shots for simplicity in this MVP
existing_scenes = await db.execute(select(SceneModel).where(SceneModel.project_id == project_id))
for scene in existing_scenes.scalars():
await db.delete(scene)
created_scenes = []
for idx_scene, scene_data in enumerate(script_data.scenes):
scene_db = SceneModel(
project_id=project_id,
slugline=scene_data.heading,
raw_content=scene_data.description,
sequence_number=idx_scene + 1,
)
db.add(scene_db)
await db.flush() # get ID
for idx_shot, shot_data in enumerate(scene_data.shots):
shot_db = ShotModel(
scene_id=scene_db.id,
description=shot_data.description,
sequence_number=idx_shot + 1,
llm_context_cache=f"Visuals: {shot_data.visual_notes or 'None'}\nDialogue: {shot_data.dialogue or 'None'}",
status="draft"
)
db.add(shot_db)
created_scenes.append(scene_db)
await db.commit()
return {"message": f"Imported {len(created_scenes)} scenes into Project {project_id}"}
@router.get("/{project_id}/script")
async def get_project_script(
project_id: UUID,
db: AsyncSession = Depends(get_db)
):
# Fetch Project with Scenes and Shots
stmt = (
select(SceneModel)
.options(selectinload(SceneModel.shots))
.where(SceneModel.project_id == project_id)
.order_by(SceneModel.sequence_number)
)
result = await db.execute(stmt)
scenes = result.scalars().all()
return {"scenes": scenes}