package main import ( "encoding/json" "io/ioutil" "log" "net/http" "net/url" "strings" "text/template" ) var countries = map[string]country{} var lawsByCC = map[string]map[string]law{} 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.Redir != "" { lawsByCC[cc][law.Redir] = law } } } http.HandleFunc("/", handler) println("listening on 8000") log.Fatal(http.ListenAndServe(":8000", nil)) } 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", map[string]any{ "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) } } _, hasJSONLaws := lawsByCC[cc] err := tpl.ExecuteTemplate(w, "search.html", map[string]any{ "TLD": cc, "Domain": host, "Country": countries[cc], "HasJSONLaws": hasJSONLaws, }) if err != nil { log.Fatal(err) } } } type law struct { Url string Title string Abbr string Redir string } type country struct { Name string SearchURL string `json:"search_url"` } func (c country) HasPlaceholder() bool { return strings.Contains(c.SearchURL, "%s") }