From 27abc5cb405c950a12c22582091aedb41cb41f55 Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Wed, 5 Mar 2025 23:34:28 +0100 Subject: [PATCH] Add main.go by converting nm0i/searx-cli to go --- main.go | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 main.go diff --git a/main.go b/main.go new file mode 100644 index 0000000..07bcbde --- /dev/null +++ b/main.go @@ -0,0 +1,116 @@ +package main + +import ( + "encoding/json" + "flag" + "fmt" + "io" + "net/http" + "os" + "strings" +) + +const searxEnvVar = "SEARX_ENDPOINT" +const defaultWrap = 72 +const defaultMaxResults = 10 + +type Result struct { + Title string `json:"title"` + Content string `json:"content"` + URL string `json:"url"` +} + +type Response struct { + Results []Result `json:"results"` +} + +func main() { + // Define command-line flags + //pagePtr := flag.Int("p", 1, "Search page number") + enginesPtr := flag.String("e", "", "Comma-separated list of engines to query") + wrapPtr := flag.Int("c", defaultWrap, "Wrap column for description") + noDescPtr := flag.Bool("nd", false, "Do not display descriptions") + maxResultsPtr := flag.Int("n", defaultMaxResults, "Limit number of displayed results") + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), "Usage: searx [options] query ...\nOptions:\n") + flag.PrintDefaults() + } + flag.Parse() + + // Validate SEARX_ENDPOINT + searxEndpoint := os.Getenv(searxEnvVar) + if searxEndpoint == "" { + fmt.Printf("Environmental variable %s must be defined:\n\n", searxEnvVar) + fmt.Printf(" export %s=https://example.com/search\n\n", searxEnvVar) + os.Exit(1) + } + + // Prepare the query + query := strings.Join(flag.Args(), " ") + if query == "" { + fmt.Println("The query is empty\n") + flag.Usage() + os.Exit(1) + } + + // Build query parameters + queryParams := fmt.Sprintf("q=%s&format=json", query) + if *enginesPtr != "" { + queryParams += "&engines=" + *enginesPtr + } + + url := searxEndpoint + "?" + queryParams + fmt.Printf("Querying %s\n", url) + // Make HTTP request + resp, err := http.Get(url) + if err != nil { + fmt.Println("Error making request:", err) + os.Exit(1) + } + defer resp.Body.Close() + + // Read and parse response + body, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println("Error reading response:", err) + os.Exit(1) + } + + fmt.Printf("body: %v\n\n", string(body)) + + var reply Response + if err := json.Unmarshal(body, &reply); err != nil { + fmt.Println("Error parsing response:", err) + os.Exit(1) + } + + // Display results + for i, result := range reply.Results { + fmt.Printf("\033[1m%d: %s\033[0m\n", i+1, result.Title) + if !*noDescPtr && result.Content != "" { + fmt.Println(wordWrap(result.Content, *wrapPtr)) + } + fmt.Printf("\033[4m%s\033[0m\n\n", result.URL) + + if i+1 >= *maxResultsPtr { + break + } + } +} + +func wordWrap(text string, limit int) string { + if len(text) > limit { + words := strings.Fields(text) + var result, line string + for _, word := range words { + if len(line)+len(word)+1 > limit { + result += line + "\n" + line = "" + } + line += word + " " + } + result += line + return result + } + return text +}