Files
MeBox/internal/handler/search_extra.go
T
truewhile 44ca451cd4 优化
优化
2026-08-24 17:40:43 +08:00

86 lines
2.7 KiB
Go

// Package handler — unified search surface that mirrors the Python
// project's /api/search* endpoints. Internally we delegate to the
// existing media + site adapters; advanced/tmdb/sites variants exist
// so the upstream Vue UI's queries don't need rewriting.
package handler
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/ShukeBta/MMTL/internal/service"
)
// searchUnifiedHandler is the basic /api/search endpoint.
func searchUnifiedHandler(svc *service.Container) gin.HandlerFunc {
return func(c *gin.Context) {
q := c.Query("q")
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "30"))
if limit <= 0 || limit > 200 {
limit = 30
}
items, err := svc.Media.SearchMediaVisible(c.Request.Context(), q, limit, mediaVisibilityForRequest(c, svc))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"items": items, "total": len(items)})
}
}
// searchAdvancedHandler accepts query + optional filters
// (year, type, library_id) — currently it ignores the filters in the
// SQL but threads them through to the response so the UI can echo
// them back. This keeps API parity without a giant query builder.
func searchAdvancedHandler(svc *service.Container) gin.HandlerFunc {
return func(c *gin.Context) {
q := c.Query("q")
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "30"))
if limit <= 0 || limit > 200 {
limit = 30
}
items, err := svc.Media.SearchMediaVisible(c.Request.Context(), q, limit, mediaVisibilityForRequest(c, svc))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"items": items,
"filters": gin.H{
"year": c.Query("year"),
"type": c.Query("type"),
"library_id": c.Query("library_id"),
},
})
}
}
// searchTMDbHandler proxies the TMDb /search endpoint via the existing
// SearchMovie helper. Movies and TV use different URLs upstream but
// only the movie path is wired today; TV is best-effort.
func searchTMDbHandler(svc *service.Container) gin.HandlerFunc {
return func(c *gin.Context) {
q := c.Query("query")
if q == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "query required"})
return
}
if svc.TMDb == nil || !svc.TMDb.Enabled() {
c.JSON(http.StatusOK, gin.H{"items": []any{}, "note": "tmdb disabled"})
return
}
match, err := svc.TMDb.SearchMovie(c.Request.Context(), q, 0)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
out := make([]any, 0, 1)
if match != nil {
out = append(out, match)
}
c.JSON(http.StatusOK, gin.H{"items": out})
}
}