mirror of
https://github.com/karust/openserp.git
synced 2026-08-05 16:53:54 +08:00
149 lines
3.4 KiB
Go
149 lines
3.4 KiB
Go
package duckduckgo
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/karust/openserp/core"
|
|
)
|
|
|
|
const baseURL = "https://duckduckgo.com"
|
|
|
|
func BuildURL(q core.Query, page int) (string, error) {
|
|
base, err := url.Parse(baseURL)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
base.Path += ""
|
|
params := url.Values{}
|
|
|
|
// Set request text
|
|
if q.Text != "" || q.Site != "" || q.Filetype != "" {
|
|
text := q.Text
|
|
if q.Site != "" {
|
|
text += " site:" + q.Site
|
|
}
|
|
if q.Filetype != "" {
|
|
text += " filetype:" + q.Filetype
|
|
}
|
|
|
|
params.Add("q", text)
|
|
}
|
|
|
|
if len(params.Get("q")) == 0 {
|
|
return "", errors.New("empty query built")
|
|
}
|
|
|
|
// Set search date range
|
|
if q.DateInterval != "" {
|
|
intervals := strings.Split(q.DateInterval, "..")
|
|
if len(intervals) != 2 {
|
|
return "", errors.New("incorrect date interval provided")
|
|
}
|
|
|
|
// Convert from YYYYMMDD to YYYY-MM-DD format (DuckDuckGo requirement)
|
|
startDate, err := time.Parse("20060102", intervals[0])
|
|
if err != nil {
|
|
return "", errors.New("invalid start date format, expected YYYYMMDD")
|
|
}
|
|
|
|
endDate, err := time.Parse("20060102", intervals[1])
|
|
if err != nil {
|
|
return "", errors.New("invalid end date format, expected YYYYMMDD")
|
|
}
|
|
|
|
// DuckDuckGo uses YYYY-MM-DD..YYYY-MM-DD format
|
|
dateRange := fmt.Sprintf("%s..%s",
|
|
startDate.Format("2006-01-02"),
|
|
endDate.Format("2006-01-02"))
|
|
params.Add("df", dateRange)
|
|
}
|
|
|
|
// Set language
|
|
if q.LangCode != "" {
|
|
params.Add("kl", strings.ToLower(q.LangCode))
|
|
}
|
|
|
|
// DuckDuckGo specific parameters
|
|
params.Add("t", "h") // HTML format
|
|
params.Add("ia", "web") // Web search
|
|
|
|
// Add pagination parameter if not on first page
|
|
if page > 0 {
|
|
// DuckDuckGo uses 's' parameter for pagination (start offset)
|
|
// Each page has approximately 25-30 results, but we'll use conservative estimate
|
|
offset := page * 25
|
|
params.Add("s", fmt.Sprintf("%d", offset))
|
|
}
|
|
|
|
base.RawQuery = params.Encode()
|
|
return base.String(), nil
|
|
}
|
|
|
|
func BuildImageURL(q core.Query) (string, error) {
|
|
base, err := url.Parse(baseURL)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
base.Path += ""
|
|
params := url.Values{}
|
|
params.Add("t", "h") // HTML format
|
|
params.Add("iax", "images") // Image search
|
|
params.Add("ia", "images")
|
|
|
|
// Set request text
|
|
if q.Text != "" || q.Site != "" || q.Filetype != "" {
|
|
text := q.Text
|
|
if q.Site != "" {
|
|
text += " site:" + q.Site
|
|
}
|
|
if q.Filetype != "" {
|
|
text += " filetype:" + q.Filetype
|
|
}
|
|
|
|
params.Add("q", text)
|
|
}
|
|
|
|
if len(params.Get("q")) == 0 {
|
|
return "", errors.New("empty query built")
|
|
}
|
|
|
|
// Set search date range
|
|
if q.DateInterval != "" {
|
|
intervals := strings.Split(q.DateInterval, "..")
|
|
if len(intervals) != 2 {
|
|
return "", errors.New("incorrect date interval provided")
|
|
}
|
|
|
|
// Convert from YYYYMMDD to YYYY-MM-DD format (DuckDuckGo requirement)
|
|
startDate, err := time.Parse("20060102", intervals[0])
|
|
if err != nil {
|
|
return "", errors.New("invalid start date format, expected YYYYMMDD")
|
|
}
|
|
|
|
endDate, err := time.Parse("20060102", intervals[1])
|
|
if err != nil {
|
|
return "", errors.New("invalid end date format, expected YYYYMMDD")
|
|
}
|
|
|
|
// DuckDuckGo uses YYYY-MM-DD..YYYY-MM-DD format
|
|
dateRange := fmt.Sprintf("%s..%s",
|
|
startDate.Format("2006-01-02"),
|
|
endDate.Format("2006-01-02"))
|
|
params.Add("df", dateRange)
|
|
}
|
|
|
|
// Set language
|
|
if q.LangCode != "" {
|
|
params.Add("kl", strings.ToLower(q.LangCode))
|
|
}
|
|
|
|
base.RawQuery = params.Encode()
|
|
return base.String(), nil
|
|
}
|