import os import uuid import shutil import datetime from sqlalchemy.orm import Session from typing import Optional from fastapi import HTTPException, File, BackgroundTasks, UploadFile from app.models.models import Activity, User, Evidence from app.schemas import ActivityCreate, ActivityUpdate from app.db.database import get_db from app.security import get_current_active_user UPLOAD_DIR = "uploads" class ActivityService: def __init__(self, db: Session, current_user: User): self._db = db self._current_user = current_user def get_activities(self, project_id: Optional[int] = None, specialty_id: Optional[int] = None, skip: int = 0, limit: int = 100): query = self._db.query(Activity) if project_id: query = query.filter(Activity.project_id == project_id) if specialty_id: query = query.filter(Activity.specialty_id == specialty_id) activities = query.offset(skip).limit(limit).all() return activities def get_activity(self, activity_id: int): db_activity = self._db.query(Activity).filter(Activity.id == activity_id).first() if db_activity is None: raise HTTPException(status_code=404, detail="Activity not found") return db_activity def create_activity(self, activity: ActivityCreate): db_activity = Activity( **activity.dict(), user_id=self._current_user.id ) self._db.add(db_activity) self._db.commit() self._db.refresh(db_activity) return db_activity def update_activity(self, activity_id: int, activity: ActivityUpdate): db_activity = self._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) self._db.commit() self._db.refresh(db_activity) return db_activity def upload_evidence( self, activity_id: int, background_tasks: BackgroundTasks, file: UploadFile = File(...), description: Optional[str] = None, captured_at: Optional[str] = None): # Verify activity exists db_activity = self._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 if not os.path.exists(UPLOAD_DIR): os.makedirs(UPLOAD_DIR) with open(file_path, "wb") as buffer: shutil.copyfileobj(file.file, buffer) 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() else: 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 ) self._db.add(db_evidence) self._db.commit() self._db.refresh(db_evidence) # If it's audio, queue transcription if initial_status == "pending": from app.services.transcription_worker import process_transcription background_tasks.add_task(process_transcription, db_evidence.id) return db_evidence