Files
Strix/internal/search/search.go
T
2026-04-05 08:32:05 +00:00

109 lines
2.3 KiB
Go

package search
import (
"database/sql"
"net/http"
"strconv"
"strings"
"github.com/eduard256/strix/internal/api"
"github.com/eduard256/strix/internal/app"
"github.com/eduard256/strix/pkg/camdb"
"github.com/rs/zerolog"
_ "modernc.org/sqlite"
)
var log zerolog.Logger
var db *sql.DB
func Init() {
log = app.GetLogger("search")
var err error
db, err = sql.Open("sqlite", "file:"+app.DB+"?mode=ro&immutable=1")
if err != nil {
log.Fatal().Err(err).Msg("[search] db open")
}
// verify DB is readable
var count int
if err = db.QueryRow("SELECT COUNT(*) FROM brands").Scan(&count); err != nil {
log.Fatal().Err(err).Msg("[search] db verify")
}
log.Info().Int("brands", count).Msg("[search] loaded")
api.HandleFunc("api/search", apiSearch)
api.HandleFunc("api/streams", apiStreams)
}
func apiSearch(w http.ResponseWriter, r *http.Request) {
q := strings.TrimSpace(r.URL.Query().Get("q"))
var results []camdb.Result
var err error
if q == "" {
results, err = camdb.SearchAll(db)
} else {
results, err = camdb.SearchQuery(db, q)
}
if err != nil {
api.Error(w, err, http.StatusInternalServerError)
return
}
api.ResponseJSON(w, map[string]any{"results": results})
}
func apiStreams(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
ids := q.Get("ids")
if ids == "" {
http.Error(w, "ids required", http.StatusBadRequest)
return
}
ip := q.Get("ip")
if ip == "" {
http.Error(w, "ip required", http.StatusBadRequest)
return
}
channel, _ := strconv.Atoi(q.Get("channel"))
var portFilter map[int]bool
if ps := q.Get("ports"); ps != "" {
portFilter = map[int]bool{}
for _, p := range strings.Split(ps, ",") {
if v, err := strconv.Atoi(strings.TrimSpace(p)); err == nil {
portFilter[v] = true
}
}
}
streams, err := camdb.BuildStreams(db, &camdb.StreamParams{
IDs: ids,
IP: ip,
User: q.Get("user"),
Pass: q.Get("pass"),
Channel: channel,
Ports: portFilter,
})
if err != nil {
status := http.StatusInternalServerError
if strings.Contains(err.Error(), "not found") {
status = http.StatusNotFound
} else if strings.Contains(err.Error(), "invalid") || strings.Contains(err.Error(), "unknown") {
status = http.StatusBadRequest
}
http.Error(w, err.Error(), status)
return
}
api.ResponseJSON(w, map[string]any{"streams": streams})
}