99 lines
3.2 KiB
Python
99 lines
3.2 KiB
Python
"""
|
|
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} |