Initial commit: DeepRes Go backend — bot + worker + embed service

This commit is contained in:
Emil Shanaty
2026-05-28 14:48:51 +03:00
commit 34577871f1
21 changed files with 1287 additions and 0 deletions
+104
View File
@@ -0,0 +1,104 @@
package search
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
type SearXNGClient struct {
baseURL string
client *http.Client
}
type SearXNGResult struct {
Title string `json:"title"`
URL string `json:"url"`
Content string `json:"content"`
Engine string `json:"engine"`
}
type SearXNGResponse struct {
Results []SearXNGResult `json:"results"`
}
func NewSearXNGClient(baseURL string) *SearXNGClient {
return &SearXNGClient{
baseURL: baseURL,
client: &http.Client{Timeout: 15 * time.Second},
}
}
func (c *SearXNGClient) Search(ctx context.Context, query string, limit int) ([]SearXNGResult, error) {
u, err := url.Parse(c.baseURL + "/search")
if err != nil {
return nil, fmt.Errorf("parse url: %w", err)
}
q := u.Query()
q.Set("q", query)
q.Set("format", "json")
q.Set("language", "ru-RU,en-US")
q.Set("categories", "general,news")
if limit > 0 {
q.Set("pageno", "1")
}
u.RawQuery = q.Encode()
req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil)
if err != nil {
return nil, fmt.Errorf("create request: %w", err)
}
req.Header.Set("User-Agent", "DeepRes/1.0")
resp, err := c.client.Do(req)
if err != nil {
return nil, fmt.Errorf("search request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("searxng returned %d: %s", resp.StatusCode, string(body))
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read response: %w", err)
}
var sr SearXNGResponse
if err := json.Unmarshal(body, &sr); err != nil {
return nil, fmt.Errorf("parse response: %w", err)
}
if len(sr.Results) > limit {
sr.Results = sr.Results[:limit]
}
return sr.Results, nil
}
// SearchWithVariations запускает несколько поисковых запросов с разными формулировками
func (c *SearXNGClient) SearchWithVariations(ctx context.Context, baseQuery string, variations []string, limit int) ([]SearXNGResult, error) {
seen := make(map[string]bool)
var allResults []SearXNGResult
queries := append([]string{baseQuery}, variations...)
for _, q := range queries {
results, err := c.Search(ctx, q, limit)
if err != nil {
// Логируем но продолжаем — один упавший запрос не ломает весь ресерч
continue
}
for _, r := range results {
if !seen[r.URL] {
seen[r.URL] = true
allResults = append(allResults, r)
}
}
}
return allResults, nil
}