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", 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) } } } 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") } func (c SearchContext) HasJSONLaws() bool { _, ok := lawsByCC[c.TLD] return ok } type StartPageContext struct { Countries map[string]country Domain string } type SearchContext struct { TLD string Domain string Country country }