Renamed the Go module to align with the updated repository path for better clarity and organization. This ensures consistency across the project and prevents potential import conflicts.
83 lines
1.5 KiB
Go
83 lines
1.5 KiB
Go
package search
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"gitea.stevedudenhoeffer.com/steve/answer/pkg/cache"
|
|
"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
|
|
}
|