sumaq/backend/routers/activities.py

191 lines
6.1 KiB
Python

import os
import shutil
from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, BackgroundTasks
from sqlalchemy.orm import Session
from typing import List, Optional
from database import get_db
from models import Activity, Evidence, User
from security import get_current_active_user
import schemas
import uuid
from services import activities
router = APIRouter(
prefix="/activities",
tags=["Activities"]
)
UPLOAD_DIR = "uploads"
if not os.path.exists(UPLOAD_DIR):
os.makedirs(UPLOAD_DIR)
@router.post("/", response_model=schemas.Activity)
def create_activity(
activity: schemas.ActivityCreate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
return activities.create_activity(db, activity, current_user)
@router.get("/", response_model=List[schemas.Activity])
def read_activities(
project_id: Optional[int] = None,
specialty_id: Optional[int] = None,
skip: int = 0,
limit: int = 100,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
db_activities = activities.get_activities(db, current_user, project_id, specialty_id, skip, limit)
return db_activities
@router.get("/{activity_id}", response_model=schemas.Activity)
def read_activity(
activity_id: int,
db: Session = Depends(get_db)
):
return activities.get_activity(db, activity_id)
@router.put("/{activity_id}", response_model=schemas.Activity)
def update_activity(
activity_id: int,
activity: schemas.ActivityUpdate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
db_activity = db.query(Activity).filter(Activity.id == activity_id).first()
if not db_activity:
raise HTTPException(status_code=404, detail="Activity not found")
update_data = activity.dict(exclude_unset=True)
for key, value in update_data.items():
setattr(db_activity, key, value)
db.commit()
db.refresh(db_activity)
return db_activity
@router.post("/{activity_id}/upload", response_model=schemas.Evidence)
async def upload_evidence(
activity_id: int,
background_tasks: BackgroundTasks,
file: UploadFile = File(...),
description: Optional[str] = None,
captured_at: Optional[str] = None,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
# Verify activity exists
db_activity = db.query(Activity).filter(Activity.id == activity_id).first()
if not db_activity:
raise HTTPException(status_code=404, detail="Activity not found")
# Generate unique filename
file_ext = os.path.splitext(file.filename)[1]
unique_filename = f"{uuid.uuid4()}{file_ext}"
file_path = os.path.join(UPLOAD_DIR, unique_filename)
# Save file
with open(file_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
import datetime
db_captured_at = None
if captured_at:
try:
db_captured_at = datetime.datetime.fromisoformat(captured_at.replace('Z', '+00:00'))
except:
db_captured_at = datetime.datetime.utcnow()
# Determine transcription status
initial_status = "none"
if file.content_type and "audio" in file.content_type:
initial_status = "pending"
# Save to database
db_evidence = Evidence(
activity_id=activity_id,
file_path=file_path,
media_type=file.content_type,
description=description,
captured_at=db_captured_at,
transcription_status=initial_status
)
db.add(db_evidence)
db.commit()
db.refresh(db_evidence)
# If it's audio, queue transcription
if initial_status == "pending":
from services.transcription_worker import process_transcription
background_tasks.add_task(process_transcription, db_evidence.id)
return db_evidence
@router.post("/evidence/{evidence_id}/retry-transcription", response_model=schemas.Evidence)
async def retry_transcription(
evidence_id: int,
background_tasks: BackgroundTasks,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
db_evidence = db.query(Evidence).filter(Evidence.id == evidence_id).first()
if not db_evidence:
raise HTTPException(status_code=404, detail="Evidence not found")
if not db_evidence.media_type or "audio" not in db_evidence.media_type:
raise HTTPException(status_code=400, detail="Only audio evidence can be transcribed")
# Update status to pending
db_evidence.transcription_status = "pending"
db_evidence.transcription = None
db.commit()
db.refresh(db_evidence)
# Queue transcription task
from services.transcription_worker import process_transcription
background_tasks.add_task(process_transcription, db_evidence.id)
return db_evidence
return db_evidence
@router.put("/evidence/{evidence_id}", response_model=schemas.Evidence)
def update_evidence(
evidence_id: int,
evidence: schemas.EvidenceUpdate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
db_evidence = db.query(Evidence).filter(Evidence.id == evidence_id).first()
if not db_evidence:
raise HTTPException(status_code=404, detail="Evidence not found")
update_data = evidence.dict(exclude_unset=True)
for key, value in update_data.items():
setattr(db_evidence, key, value)
db.commit()
db.refresh(db_evidence)
return db_evidence
@router.delete("/evidence/{evidence_id}")
def delete_evidence(
evidence_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_user)
):
db_evidence = db.query(Evidence).filter(Evidence.id == evidence_id).first()
if not db_evidence:
raise HTTPException(status_code=404, detail="Evidence not found")
# Optional: Delete file from disk
if db_evidence.file_path and os.path.exists(db_evidence.file_path):
try:
os.remove(db_evidence.file_path)
except:
pass
db.delete(db_evidence)
db.commit()
return {"detail": "Evidence deleted"}