Files
openserp/cmd/engines.go

79 lines
2.9 KiB
Go
Raw Permalink Normal View History

package cmd
import (
"context"
"io"
"github.com/karust/openserp/baidu"
"github.com/karust/openserp/bing"
"github.com/karust/openserp/core"
"github.com/karust/openserp/duckduckgo"
"github.com/karust/openserp/ecosia"
"github.com/karust/openserp/google"
"github.com/karust/openserp/yandex"
)
// engineSpec is the single registry row for a search engine, driving CLI search,
// raw dispatch, serve's browserEngineSpecs, and the alias/validation strings.
// cfg points into the live config global; rawSearchFn is nil when an engine has
// no browserless mode.
type engineSpec struct {
name string
aliases []string
factory func(core.Browser, core.SearchEngineOptions) core.SearchEngine
rawSearchFn func(context.Context, core.Query) ([]core.SearchResult, error)
parseHTMLFn func(io.Reader) ([]core.SearchResult, error)
cfg *EngineConfig
}
func (s engineSpec) opts() core.SearchEngineOptions {
return s.cfg.SearchEngineOptions
}
func engineSpecs() []engineSpec {
return []engineSpec{
{name: "google", factory: newEngine(google.New), rawSearchFn: google.Search, parseHTMLFn: google.ParseHTML, cfg: &config.GoogleConfig},
{name: "yandex", factory: newEngine(yandex.New), rawSearchFn: yandex.Search, parseHTMLFn: yandex.ParseHTML, cfg: &config.YandexConfig},
{name: "baidu", factory: newEngine(baidu.New), rawSearchFn: baidu.Search, parseHTMLFn: baidu.ParseHTML, cfg: &config.BaiduConfig},
{name: "bing", factory: newEngine(bing.New), parseHTMLFn: bing.ParseHTML, cfg: &config.BingConfig},
{name: "duckduckgo", aliases: []string{"duck", "ddg"}, factory: newEngine(duckduckgo.New), parseHTMLFn: duckduckgo.ParseHTML, cfg: &config.DuckDuckGoConfig},
{name: "ecosia", factory: newEngine(ecosia.New), rawSearchFn: ecosia.Search, parseHTMLFn: ecosia.ParseHTML, cfg: &config.EcosiaConfig},
}
}
// newEngine adapts a concrete pkg.New (returning *Engine) to the
// core.SearchEngine-typed factory the registry stores.
func newEngine[T core.SearchEngine](ctor func(core.Browser, core.SearchEngineOptions) T) func(core.Browser, core.SearchEngineOptions) core.SearchEngine {
return func(b core.Browser, o core.SearchEngineOptions) core.SearchEngine {
return ctor(b, o)
}
}
// engineValidArgs returns every accepted engine token (canonical names +
// aliases) for cobra's OnlyValidArgs validation.
func engineValidArgs() []string {
specs := engineSpecs()
args := make([]string, 0, len(specs))
for _, s := range specs {
args = append(args, s.name)
args = append(args, s.aliases...)
}
return args
}
// resolveEngineSpec returns the spec whose canonical name or alias matches raw
// (case/space already normalized by the caller), or false when unknown.
func resolveEngineSpec(raw string) (engineSpec, bool) {
for _, s := range engineSpecs() {
if s.name == raw {
return s, true
}
for _, alias := range s.aliases {
if alias == raw {
return s, true
}
}
}
return engineSpec{}, false
}