2019-05-26 22:36:46 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"io/ioutil"
|
2019-06-12 13:49:00 +02:00
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
2019-05-26 22:36:46 +02:00
|
|
|
"regexp"
|
2019-06-12 13:49:00 +02:00
|
|
|
"strings"
|
2019-05-26 22:36:46 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
var bangs = loadBangs()
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
http.HandleFunc("/eval", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
searchQuery := r.URL.Query().Get("query")
|
|
|
|
searchEngine := r.URL.Query().Get("engine")
|
|
|
|
|
|
|
|
if (searchQuery == "" || searchEngine == "") {
|
|
|
|
http.Error(w, "400 Bad Request", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
searchQuery, searchEngine = evaluateBang(searchQuery, searchEngine)
|
|
|
|
|
|
|
|
searchURL := buildSearchURL(searchEngine, searchQuery)
|
|
|
|
http.Redirect(w, r, searchURL, http.StatusSeeOther)
|
|
|
|
})
|
|
|
|
|
|
|
|
log.Fatalf("Failed to start http server: %v", http.ListenAndServe(":8081", nil))
|
|
|
|
}
|
|
|
|
|
|
|
|
func loadBangs() (bangs map[string]string) {
|
|
|
|
data, err := ioutil.ReadFile("bangs.json")
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Failed to read bangs: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = json.Unmarshal(data, &bangs)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Failed to decode bangs: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func buildSearchURL(template string, query string) (searchUrl string) {
|
2019-06-13 15:04:52 +02:00
|
|
|
searchUrl = strings.Replace(template, "%s", url.QueryEscape(query), 1)
|
2019-06-13 16:00:24 +02:00
|
|
|
searchUrl = strings.Replace(searchUrl, "%S", query, 1)
|
|
|
|
return searchUrl
|
2019-05-26 22:36:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func parseBang(searchQuery string) (bang string, query string) {
|
|
|
|
regexStartBang, _ := regexp.Compile("\\!(.*) (.*)")
|
|
|
|
regexEndBang, _ := regexp.Compile("(.*) \\!(.*)")
|
|
|
|
|
|
|
|
startBang := regexStartBang.FindSubmatch([]byte(searchQuery))
|
|
|
|
endBang := regexEndBang.FindSubmatch([]byte(searchQuery))
|
|
|
|
|
|
|
|
if len(endBang) == 3 {
|
2019-05-30 21:04:16 +02:00
|
|
|
bang = strings.ToLower(string(endBang[2]))
|
|
|
|
query = string(endBang[1])
|
|
|
|
return
|
2019-05-26 22:36:46 +02:00
|
|
|
} else if len(startBang) == 3 {
|
2019-05-30 21:04:16 +02:00
|
|
|
bang = strings.ToLower(string(startBang[1]))
|
|
|
|
query = string(startBang[2])
|
|
|
|
return
|
2019-05-26 22:36:46 +02:00
|
|
|
} else {
|
|
|
|
return "", searchQuery
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func evaluateBang(searchQuery string, searchEngine string) (query string, engine string) {
|
|
|
|
bang, query := parseBang(searchQuery)
|
2019-05-27 15:33:19 +02:00
|
|
|
engine = bangs[bang]
|
|
|
|
|
|
|
|
if (bang == "" || engine == ""){
|
|
|
|
return searchQuery, searchEngine
|
2019-05-26 22:36:46 +02:00
|
|
|
} else {
|
2019-05-27 15:33:19 +02:00
|
|
|
return query, engine
|
2019-05-26 22:36:46 +02:00
|
|
|
}
|
|
|
|
}
|