"""Tracking configuration CRUD API routes.""" from fastapi import APIRouter, Depends, HTTPException, status from pydantic import BaseModel from sqlmodel import select from sqlmodel.ext.asyncio.session import AsyncSession from ..auth.dependencies import get_current_user from ..database.engine import get_session from ..database.models import TrackingConfig, User router = APIRouter(prefix="/api/tracking-configs", tags=["tracking-configs"]) class TrackingConfigCreate(BaseModel): name: str track_assets_added: bool = True track_assets_removed: bool = False track_album_renamed: bool = True track_album_deleted: bool = True track_images: bool = True track_videos: bool = True notify_favorites_only: bool = False include_people: bool = True include_asset_details: bool = False max_assets_to_show: int = 5 assets_order_by: str = "none" assets_order: str = "descending" periodic_enabled: bool = False periodic_interval_days: int = 1 periodic_start_date: str = "2025-01-01" periodic_times: str = "12:00" scheduled_enabled: bool = False scheduled_times: str = "09:00" scheduled_album_mode: str = "per_album" scheduled_limit: int = 10 scheduled_favorite_only: bool = False scheduled_asset_type: str = "all" scheduled_min_rating: int = 0 scheduled_order_by: str = "random" scheduled_order: str = "descending" memory_enabled: bool = False memory_times: str = "09:00" memory_album_mode: str = "combined" memory_limit: int = 10 memory_favorite_only: bool = False memory_asset_type: str = "all" memory_min_rating: int = 0 class TrackingConfigUpdate(BaseModel): name: str | None = None track_assets_added: bool | None = None track_assets_removed: bool | None = None track_album_renamed: bool | None = None track_album_deleted: bool | None = None track_images: bool | None = None track_videos: bool | None = None notify_favorites_only: bool | None = None include_people: bool | None = None include_asset_details: bool | None = None max_assets_to_show: int | None = None assets_order_by: str | None = None assets_order: str | None = None periodic_enabled: bool | None = None periodic_interval_days: int | None = None periodic_start_date: str | None = None periodic_times: str | None = None scheduled_enabled: bool | None = None scheduled_times: str | None = None scheduled_album_mode: str | None = None scheduled_limit: int | None = None scheduled_favorite_only: bool | None = None scheduled_asset_type: str | None = None scheduled_min_rating: int | None = None scheduled_order_by: str | None = None scheduled_order: str | None = None memory_enabled: bool | None = None memory_times: str | None = None memory_album_mode: str | None = None memory_limit: int | None = None memory_favorite_only: bool | None = None memory_asset_type: str | None = None memory_min_rating: int | None = None @router.get("") async def list_configs( user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), ): result = await session.exec( select(TrackingConfig).where(TrackingConfig.user_id == user.id) ) return [_response(c) for c in result.all()] @router.post("", status_code=status.HTTP_201_CREATED) async def create_config( body: TrackingConfigCreate, user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), ): config = TrackingConfig(user_id=user.id, **body.model_dump()) session.add(config) await session.commit() await session.refresh(config) return _response(config) @router.get("/{config_id}") async def get_config( config_id: int, user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), ): return _response(await _get(session, config_id, user.id)) @router.put("/{config_id}") async def update_config( config_id: int, body: TrackingConfigUpdate, user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), ): config = await _get(session, config_id, user.id) for field, value in body.model_dump(exclude_unset=True).items(): setattr(config, field, value) session.add(config) await session.commit() await session.refresh(config) return _response(config) @router.delete("/{config_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_config( config_id: int, user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), ): config = await _get(session, config_id, user.id) await session.delete(config) await session.commit() def _response(c: TrackingConfig) -> dict: return {k: getattr(c, k) for k in TrackingConfig.model_fields if k != "user_id"} | { "created_at": c.created_at.isoformat() } async def _get(session: AsyncSession, config_id: int, user_id: int) -> TrackingConfig: config = await session.get(TrackingConfig, config_id) if not config or config.user_id != user_id: raise HTTPException(status_code=404, detail="Tracking config not found") return config