""" Folders API router """ from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from typing import List, Optional from pydantic import BaseModel import os import uuid from app.database import get_db from app.models import Folder, SourceRoot router = APIRouter() class FolderCreate(BaseModel): path: str recursive: bool = True watch: bool = False class FolderResponse(BaseModel): id: str name: str path: str photo_count: int @router.get("") async def get_folders(db: AsyncSession = Depends(get_db)): """Get all source folders""" # Get source roots instead of regular folders result = await db.execute(select(SourceRoot).where(SourceRoot.is_active == True)) source_roots = result.scalars().all() folders_list = [] for root in source_roots: # Get photo count for this source root folder_result = await db.execute( select(Folder).where(Folder.source_root_id == root.id) ) folders = folder_result.scalars().all() photo_count = sum(f.photo_count for f in folders) folders_list.append({ "id": root.id, "name": root.name or os.path.basename(root.path), "path": root.path, "photo_count": photo_count }) return {"folders": folders_list} @router.post("") async def create_folder(folder: FolderCreate, db: AsyncSession = Depends(get_db)): """Add a new source folder""" # Check if path exists if not os.path.exists(folder.path): raise HTTPException(status_code=400, detail=f"Path does not exist: {folder.path}") # Check if path is already added result = await db.execute(select(SourceRoot).where(SourceRoot.path == folder.path)) existing = result.scalar_one_or_none() if existing: raise HTTPException(status_code=400, detail="Path already added as source folder") # Create source root source_root = SourceRoot( id=str(uuid.uuid4()), name=os.path.basename(folder.path), path=folder.path ) db.add(source_root) await db.commit() # Automatically trigger a scan for the new folder from app.tasks.celery import celery_app celery_app.send_task('scan_folder', args=[source_root.path, source_root.id]) return { "id": source_root.id, "name": source_root.name, "path": source_root.path, "photo_count": 0 } @router.post("/{folder_id}/scan") async def scan_folder(folder_id: str, db: AsyncSession = Depends(get_db)): """Trigger manual re-scan of source root folder""" from app.tasks.celery import celery_app result = await db.execute(select(SourceRoot).where(SourceRoot.id == folder_id)) source_root = result.scalar_one_or_none() if not source_root: raise HTTPException(status_code=404, detail="Source folder not found") # Queue scan task using the task name defined in the decorator task = celery_app.send_task('scan_folder', args=[source_root.path, source_root.id]) return {"status": "success", "message": f"Scan queued for {source_root.path}", "task_id": task.id}