45 lines
1.3 KiB
Python
45 lines
1.3 KiB
Python
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()
|