summaryrefslogtreecommitdiff
path: root/lexsurf.go
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-02-28 09:18:48 +0100
committerMartin Fischer <martin@push-f.com>2021-03-03 12:52:46 +0100
commit4d43e952fff25b5b131e8699858da663a5ac2c42 (patch)
treeacff62119061480a1cd7580f25c16c539aabc2ae /lexsurf.go
initial commit
Diffstat (limited to 'lexsurf.go')
-rw-r--r--lexsurf.go138
1 files changed, 138 insertions, 0 deletions
diff --git a/lexsurf.go b/lexsurf.go
new file mode 100644
index 0000000..1772878
--- /dev/null
+++ b/lexsurf.go
@@ -0,0 +1,138 @@
+package main
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "net/url"
+ "strings"
+ "text/template"
+)
+
+type law struct {
+ Url string
+ Title string
+ Abbr string
+}
+
+type country struct {
+ Name string
+ SearchURL string `json:"search_url"`
+}
+
+func (c country) HasPlaceholder() bool {
+ return strings.Contains(c.SearchURL, "%s")
+}
+
+var countries = map[string]country{}
+var lawsByCC = map[string]map[string]law{}
+
+type StartPageContext struct {
+ Countries map[string]country
+ Domain string
+}
+
+type SearchContext struct {
+ TLD string
+ Domain string
+ Country country
+}
+
+var tpl, _ = template.New("").Funcs(template.FuncMap{
+ "ToUpper": strings.ToUpper,
+}).ParseGlob("views/*")
+
+func handler(w http.ResponseWriter, r *http.Request) {
+ if r.Host == "lex.surf" || r.Host == "lex.localhost" {
+ if r.URL.Path != "/" {
+ w.WriteHeader(http.StatusNotFound)
+ w.Write([]byte("page not found"))
+ return
+ }
+ err := tpl.ExecuteTemplate(w, "index.html", StartPageContext{
+ Countries: countries,
+ Domain: r.Host,
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+ return
+ }
+
+ parts := strings.SplitN(r.Host, ".", 2)
+ if len(parts) != 2 {
+ w.Write([]byte("unknown host"))
+ return
+ }
+ cc := parts[0]
+ host := parts[1]
+ key := strings.TrimLeft(r.URL.Path, "/")
+ if len(key) > 0 {
+ val, ok := lawsByCC[cc][key]
+ if !ok {
+ w.WriteHeader(http.StatusNotFound)
+ w.Write([]byte("unknown law"))
+ return
+ }
+ http.Redirect(w, r, val.Url, 302)
+ } else {
+ query := r.URL.Query().Get("q")
+ if query != "" {
+ country, ok := countries[cc]
+ if !ok {
+ w.WriteHeader(http.StatusNotFound)
+ w.Write([]byte("search not implemented for this country"))
+ return
+ }
+ if country.HasPlaceholder() {
+ http.Redirect(w, r, strings.Replace(country.SearchURL, "%s", url.QueryEscape(query), 1), 302)
+ return
+ } else {
+ w.WriteHeader(http.StatusBadRequest)
+ }
+ }
+ err := tpl.ExecuteTemplate(w, "search.html", SearchContext{
+ TLD: cc,
+ Domain: host,
+ Country: countries[cc],
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+ }
+}
+
+func main() {
+ text, _ := ioutil.ReadFile("countries.json")
+ err := json.Unmarshal(text, &countries)
+ if err != nil {
+ log.Fatal("search.json", err)
+ }
+
+ lawFiles, err := ioutil.ReadDir("laws")
+ if err != nil {
+ log.Fatal(err)
+ }
+ for _, file := range lawFiles {
+ text, err := ioutil.ReadFile("laws/" + file.Name())
+ if err != nil {
+ log.Fatal(file.Name(), err)
+ }
+ var laws []law
+ err = json.Unmarshal([]byte(text), &laws)
+ if err != nil {
+ log.Fatal(file.Name(), err)
+ }
+ cc := strings.SplitN(file.Name(), ".", 2)[0]
+ lawsByCC[cc] = map[string]law{}
+ for _, law := range laws {
+ if law.Abbr != "" {
+ lawsByCC[cc][law.Abbr] = law
+ }
+ }
+ }
+ http.HandleFunc("/", handler)
+ println("listening on 8000")
+ log.Fatal(http.ListenAndServe(":8000", nil))
+}