From 03f9ef85749b037bbe6ac364ffc745e7b2a8f7f0 Mon Sep 17 00:00:00 2001 From: Simon Bruder Date: Sun, 26 May 2019 20:36:46 +0000 Subject: [PATCH] add evaluator --- .drone.yml | 10 ++++++ Dockerfile | 22 +++++++++++++ evaluator/evaluator.go | 74 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 Dockerfile create mode 100644 evaluator/evaluator.go diff --git a/.drone.yml b/.drone.yml index e6f8fe3..73011dc 100644 --- a/.drone.yml +++ b/.drone.yml @@ -19,3 +19,13 @@ steps: target: /bangs/ path_style: true endpoint: https://s3.sbruder.de + + - name: docker + image: plugins/docker + settings: + registry: r.sbruder.de + username: + from_secret: docker_username + password: + from_secret: docker_password + repo: r.sbruder.de/bang-evaluator diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ecce4f1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM golang:alpine as builder + +WORKDIR /go/src/git.sbruder.de/simon/bangs/evaluator/ + +COPY evaluator/evaluator.go . + +RUN apk add --no-cache git upx + +RUN go get -v \ + && CGO_ENABLED=0 go build -v -ldflags="-s -w" \ + && upx --ultra-brute evaluator + +FROM scratch + +COPY --from=builder /go/src/git.sbruder.de/simon/bangs/evaluator/evaluator /evaluator +copy bangs.json /bangs.json + +USER 1000 + +ENTRYPOINT ["/evaluator"] + +EXPOSE 8081 diff --git a/evaluator/evaluator.go b/evaluator/evaluator.go new file mode 100644 index 0000000..5b193fc --- /dev/null +++ b/evaluator/evaluator.go @@ -0,0 +1,74 @@ +package main + +import ( + "net/http" + "log" + "strings" + "encoding/json" + "io/ioutil" + "regexp" +) + +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) { + return strings.Replace(template, "%s", query, 1) +} + +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 { + return string(endBang[2]), string(endBang[1]) + } else if len(startBang) == 3 { + return string(startBang[1]), string(startBang[2]) + } else { + return "", searchQuery + } +} + +func evaluateBang(searchQuery string, searchEngine string) (query string, engine string) { + bang, query := parseBang(searchQuery) + if bang == "" { + return query, searchEngine + } else { + return query, bangs[bang] + } +}