Add main.go by converting nm0i/searx-cli to go

This commit is contained in:
Jan Bader 2025-03-05 23:34:28 +01:00
parent d6def9a024
commit 27abc5cb40

116
main.go Normal file
View File

@ -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
}