Search/text-quant.go

106 lines
2.7 KiB
Go
Raw Normal View History

2024-05-17 14:26:28 +02:00
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
)
// QwantTextAPIResponse represents the JSON response structure from Qwant API
type QwantTextAPIResponse struct {
Data struct {
Result struct {
2024-05-18 01:59:29 +02:00
Items struct {
Mainline []struct {
Items []struct {
URL string `json:"url"`
Title string `json:"title"`
Description string `json:"desc"`
} `json:"items"`
} `json:"mainline"`
2024-05-17 14:26:28 +02:00
} `json:"items"`
} `json:"result"`
} `json:"data"`
}
2024-05-18 01:59:29 +02:00
// PerformQwantTextSearch contacts the Qwant API and returns a slice of TextSearchResult
2024-06-09 12:43:46 +02:00
func PerformQwantTextSearch(query, safe, lang string) ([]TextSearchResult, error) {
2024-05-17 14:26:28 +02:00
const resultsPerPage = 10
2024-06-09 12:43:46 +02:00
const offset = 0
2024-05-18 01:59:29 +02:00
// Ensure safe search is disabled by default if not specified
if safe == "" {
safe = "0"
}
// Default to English Canada locale if not specified
if lang == "" {
lang = "en_CA"
}
2024-06-09 12:43:46 +02:00
apiURL := fmt.Sprintf("https://api.qwant.com/v3/search/web?q=%s&count=%d&locale=%s&offset=%d&device=desktop",
2024-05-17 14:26:28 +02:00
url.QueryEscape(query),
resultsPerPage,
lang,
2024-06-09 12:43:46 +02:00
offset)
2024-05-17 14:26:28 +02:00
req, err := http.NewRequest("GET", apiURL, nil)
if err != nil {
return nil, fmt.Errorf("creating request: %v", err)
}
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36")
2025-01-12 16:46:52 +01:00
// Perform the request using the appropriate client
var resp *http.Response
if config.MetaProxyEnabled && metaProxyClient != nil {
resp, err = metaProxyClient.Do(req)
} else {
client := &http.Client{Timeout: 10 * time.Second}
resp, err = client.Do(req)
}
2024-05-17 14:26:28 +02:00
if err != nil {
return nil, fmt.Errorf("making request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
var apiResp QwantTextAPIResponse
if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
return nil, fmt.Errorf("decoding response: %v", err)
}
2024-05-18 01:59:29 +02:00
// Extracting results from the nested JSON structure
if len(apiResp.Data.Result.Items.Mainline) == 0 {
return nil, fmt.Errorf("no search results found")
}
2024-05-17 14:26:28 +02:00
var results []TextSearchResult
2024-05-18 01:59:29 +02:00
for _, item := range apiResp.Data.Result.Items.Mainline[0].Items {
cleanURL := cleanQwantURL(item.URL)
2024-05-17 14:26:28 +02:00
results = append(results, TextSearchResult{
2024-05-18 01:59:29 +02:00
URL: cleanURL,
2024-05-17 14:26:28 +02:00
Header: item.Title,
2024-05-18 01:59:29 +02:00
Description: item.Description,
Source: "Qwant",
2024-05-17 14:26:28 +02:00
})
}
return results, nil
}
2024-05-18 01:59:29 +02:00
// cleanQwantURL extracts the main part of the URL, removing tracking information
func cleanQwantURL(rawURL string) string {
u, err := url.Parse(rawURL)
if err != nil {
return rawURL
}
return u.Scheme + "://" + u.Host + u.Path
}