archive-backend/routers/search.py
2026-11-07 11:40:36 +00:00

71 lines
2.0 KiB
Python

# routers/search.py
from fastapi import APIRouter, Query
from fastapi.concurrency import run_in_threadpool
from pydantic import BaseModel
from ..search.search_client import videos_index
router = APIRouter(prefix="/search", tags=["search"])
class VideoHit(BaseModel):
id: int
title: str
filename: str
date: str | None
channel_id: int
channel_name: str
playlist_id: int | None
playlist_name: str | None
preview_path: str
_formatted: dict | None = None
class SearchResponse(BaseModel):
query: str
total: int
took_ms: int
items: list[VideoHit]
@router.get("/videos", response_model=SearchResponse)
async def search_videos(
q: str = Query("", max_length=200, description="Поисковый запрос; пусто = показать всё"),
channel_id: int | None = None,
playlist_id: int | None = None,
date_from: str | None = Query(None, pattern=r"^\d{4}-\d{2}-\d{2}$"),
date_to: str | None = Query(None, pattern=r"^\d{4}-\d{2}-\d{2}$"),
sort: str | None = Query(None, description="date:desc | date:asc | id:desc"),
limit: int = Query(20, le=100),
offset: int = Query(0, ge=0),
):
filters = []
if channel_id is not None:
filters.append(f"channel_id = {channel_id}")
if playlist_id is not None:
filters.append(f"playlist_id = {playlist_id}")
if date_from:
filters.append(f'date >= "{date_from}"')
if date_to:
filters.append(f'date <= "{date_to}"')
params = {
"limit": limit,
"offset": offset,
"attributesToHighlight": ["title", "filename"],
"highlightPreTag": "<mark>",
"highlightPostTag": "</mark>",
}
if filters:
params["filter"] = " AND ".join(filters)
if sort:
params["sort"] = [sort]
result = await run_in_threadpool(videos_index().search, q, params)
return {
"query": q,
"total": result["estimatedTotalHits"],
"took_ms": result["processingTimeMs"],
"items": result["hits"],
}