feat: timeline and folder import
This commit is contained in:
@@ -4,30 +4,96 @@ Folders API router
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from typing import List
|
||||
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 folder tree"""
|
||||
result = await db.execute(select(Folder))
|
||||
folders = result.scalars().all()
|
||||
return folders
|
||||
"""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 folder"""
|
||||
from app.tasks.scan import scan_folder as scan_task
|
||||
"""Trigger manual re-scan of source root folder"""
|
||||
from app.tasks.celery import celery_app
|
||||
|
||||
result = await db.execute(select(Folder).where(Folder.id == folder_id))
|
||||
folder = result.scalar_one_or_none()
|
||||
result = await db.execute(select(SourceRoot).where(SourceRoot.id == folder_id))
|
||||
source_root = result.scalar_one_or_none()
|
||||
|
||||
if not folder:
|
||||
raise HTTPException(status_code=404, detail="Folder not found")
|
||||
if not source_root:
|
||||
raise HTTPException(status_code=404, detail="Source folder not found")
|
||||
|
||||
scan_task.delay(folder.path)
|
||||
return {"status": "success", "message": f"Scan queued for {folder.path}"}
|
||||
# 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}
|
||||
Reference in New Issue
Block a user