from fastapi import APIRouter, Depends, Query from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from sqlalchemy.orm import selectinload from app.database import get_db from app.models import MediaItem, media_item_tags from app.schemas import MediaItemOut router = APIRouter(prefix="/search", tags=["search"]) @router.get("", response_model=list[MediaItemOut]) async def search( q: str = Query(default=""), tags: str = Query(default=""), library_id: int | None = Query(default=None), db: AsyncSession = Depends(get_db), ): stmt = ( select(MediaItem) .options(selectinload(MediaItem.tags)) .where(MediaItem.missing == False) # noqa: E712 ) if q: stmt = stmt.where(MediaItem.filename.ilike(f"%{q}%")) if library_id is not None: stmt = stmt.where(MediaItem.library_id == library_id) if tags: tag_ids = [int(t.strip()) for t in tags.split(",") if t.strip().isdigit()] for tag_id in tag_ids: stmt = stmt.where( MediaItem.id.in_( select(media_item_tags.c.media_item_id).where( media_item_tags.c.tag_id == tag_id ) ) ) result = await db.execute(stmt.order_by(MediaItem.filename).limit(200)) return result.scalars().all()