package search import ( "answer/pkg/cache" "context" "fmt" "time" "gitea.stevedudenhoeffer.com/steve/go-extractor" "gitea.stevedudenhoeffer.com/steve/go-extractor/sites/duckduckgo" ) type duckDuckGo struct { Cache cache.Cache Browser extractor.Browser } func NewDuckDuckGo(c cache.Cache) (Search, error) { timeout := 60 * time.Second browser, err := extractor.NewPlayWrightBrowser(extractor.PlayWrightBrowserOptions{Timeout: &timeout}) if err != nil { return nil, fmt.Errorf("failed to create browser: %w", err) } return duckDuckGo{ Cache: c, Browser: browser, }, nil } var _ Search = duckDuckGo{} func (d duckDuckGo) Search(ctx context.Context, search string) ([]Result, error) { var res []Result key := "duckduckgo:" + search err := d.Cache.GetJSON(key, &res) if err == nil { return res, nil } results, err := d.searchDuckDuckGo(ctx, search) if err != nil { return nil, err } for _, r := range results { res = append(res, Result{ Title: r.Title, URL: r.URL, Description: r.Description, }) } _ = d.Cache.SetJSON(key, res) return res, nil } func (d duckDuckGo) searchDuckDuckGo(ctx context.Context, search string) ([]Result, error) { cfg := duckduckgo.DefaultConfig r, err := cfg.Search(ctx, d.Browser, search) if err != nil { return nil, err } res := make([]Result, len(r)) for i, v := range r { res[i] = Result{ URL: v.URL, Title: v.Title, Description: v.Description, } } return res, nil }