Files
glpi-neural-brain/internal/research/searxng.go
T
2026-08-04 03:43:12 +02:00

62 lines
1.4 KiB
Go

package research
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
"time"
"github.com/local/glpi-neural-brain/internal/model"
)
type Client struct {
BaseURL string
HTTP *http.Client
}
func New(base string) *Client {
return &Client{BaseURL: strings.TrimRight(base, "/"), HTTP: &http.Client{Timeout: 45 * time.Second}}
}
func (c *Client) Search(ctx context.Context, q string, limit int) ([]model.ResearchResult, error) {
if c == nil || c.BaseURL == "" {
return nil, nil
}
u := c.BaseURL + "/search?format=json&language=de-DE&q=" + url.QueryEscape(q)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
if err != nil {
return nil, err
}
resp, err := c.HTTP.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode/100 != 2 {
return nil, fmt.Errorf("searxng HTTP %d", resp.StatusCode)
}
var env struct {
Results []struct {
Title string `json:"title"`
URL string `json:"url"`
Content string `json:"content"`
} `json:"results"`
}
if err := json.NewDecoder(resp.Body).Decode(&env); err != nil {
return nil, err
}
out := []model.ResearchResult{}
for _, r := range env.Results {
if strings.TrimSpace(r.URL) == "" {
continue
}
out = append(out, model.ResearchResult{Title: r.Title, URL: r.URL, Content: r.Content})
if limit > 0 && len(out) >= limit {
break
}
}
return out, nil
}