Mercurial > mercurial > hgweb_golang.cgi
view src/kaigo/horori/searcher/server/searcher.go @ 59:48e46bfe97fa
kaigo: pre-release eraline.
author | pyon@macmini |
---|---|
date | Wed, 12 Aug 2020 19:57:58 +0900 |
parents | 7396e7407abd |
children | 0369656be06c |
line wrap: on
line source
/* Last Change: 2020-06-23 火 15:48:49. */ package main import ( "bufio" "bytes" "compress/gzip" "encoding/csv" "fmt" "io" "io/ioutil" "log" "net" "net/http" "os" "path/filepath" "sort" "strconv" "strings" "time" ) type hhs struct { No string //Birth string Name string //Kana string Addr string //Sex string Ccn []string } func (h *hhs) GetData() string { s := strings.Join(h.Ccn, "#") s = strings.Join([]string{h.Name, h.Addr, s}, ":") return s } func (h *hhs) GetRecent() string { ccn := "" if len(h.Ccn) > 0 { ccn = h.Ccn[0] } return strings.Join([]string{h.No, h.Name, ccn}, ",") } var ( server string port string hhsdb string indexdb string pwdb string server_root string hhash map[string]hhs iymdhash map[string]string iyhash map[string]string logfile string ) func init() { port = ":3910" hhsdb = "hhsdb.csv" indexdb = "index.csv" pwdb = "passwd" logfile = "searcher.log" } func main() { server_root = filepath.Dir(os.Args[0]) hhsdb = filepath.Join(server_root, hhsdb) indexdb = filepath.Join(server_root, indexdb) pwdb = filepath.Join(server_root, pwdb) // setting IP-Address & Port addrs, err := net.InterfaceAddrs() if err != nil { log.Fatal(err) } for _, a := range addrs { if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if strings.HasPrefix(ipnet.IP.String(), "169.254") { continue } if ipnet.IP.To4() != nil { server = ipnet.IP.String() + port } } } if err := loadDB(); err != nil { log.Fatal(err) } // Http-Handler http.HandleFunc("/h/", hhs_handler) // Get /h/0800012345 -> name:addr:20200101#20210701#... http.HandleFunc("/hn/", hhsnm_handler) // Get /hn/0800012345:0800098765:... -> name1:name2:... http.HandleFunc("/ht/", hhstm_handler) // Get /ht/ -> 2020-03-14 12:34 (2020-04-02) http.HandleFunc("/ha/", hhsdb_handler) // Get /ha/ -> hhsdb.csv for Mover http.HandleFunc("/i/", image_handler) // Get /i/20200110/0800012345.tgz http.HandleFunc("/r/", recent_handler) // Get /r/0800012345:0800067890:0800099999:... -> 0800012345,name1,20200101:0800067890,name2,20210405:... http.HandleFunc("/d/", index_handler) // Get /d/20xx -> 20xx0401:20xx0408:... , /d/20xx0401 -> 0800012345:0800098765:... http.HandleFunc("/dt/", indextm_handler) // Get /dt/ -> 2020-03-14 12:34 (2020-04-02) http.HandleFunc("/hd/", hhsdbidx_handler)// Get /hd/ -> 20010401,0800012345,name1\n20010401,0300011111,name2\n... http.HandleFunc("/ud/", upidx_handler) // Get /ud/20200402 http.HandleFunc("/u/", uphhsdb_handler) // POST /u/ http.HandleFunc("/ui/", upimage_handler) // POST /ui/20200401/0800012345.tgz http.HandleFunc("/ci/", climage_handler) // Get /ci/20200402 -> remove dir http.HandleFunc("/pw/", pw_handler) // Get /pw/ -> id1:pw1:id2:pw2:... log.Fatal(http.ListenAndServe(server, nil)) } /** FUNCTIONS **/ func loadDB() error { hhash = make(map[string]hhs) iymdhash = make(map[string]string) iyhash = make(map[string]string) b, err := ioutil.ReadFile(hhsdb) if err != nil { return err } r := csv.NewReader(strings.NewReader(string(b))) for { record, err := r.Read() if err == io.EOF { break } if err != nil { return err } h := hhs{ No: record[0], //Birth: record[1], Name: record[2], //Kana: record[3], Addr: record[4], //Sex: record[5], } hhash[record[0]] = h } b, err = ioutil.ReadFile(indexdb) if err != nil { return err } r = csv.NewReader(strings.NewReader(string(b))) for { record, err := r.Read() if err == io.EOF { break } if err != nil { return err } h := hhash[record[0]] ccn := h.Ccn h.Ccn = append(ccn, record[1]) hhash[record[0]] = h iymdhash[record[1]] += ":" + record[0] } for ymd, _ := range iymdhash { y := ymd[0:4] if ymd[4:6] == "01" || ymd[4:6] == "02" || ymd[4:6] == "03" { yy, _ := strconv.Atoi(y) y = fmt.Sprintf("%d", yy - 1) } iyhash[y] += ":" + ymd } return nil } func write_errlog(no int, msg string) { log := filepath.Join(server_root, logfile) t := time.Now().Format("2006-01-02 15:04") msg = fmt.Sprintf("%s [%02d] %s\n", t, no, msg) f, _ := os.OpenFile(log, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) f.Write([]byte(msg)) f.Close() } /** HTTP HANDLERS **/ /* Get /h/0800012345 -> name:addr:20200101#20210701#... */ func hhs_handler(w http.ResponseWriter, r *http.Request) { hno := r.URL.Path[len("/h/"):] s := "" if h, ok := hhash[hno]; ok { s = h.GetData() } w.Write([]byte(s)) } /* Get /hn/0800012345:0800098765:... -> name1:name2:... */ func hhsnm_handler(w http.ResponseWriter, r *http.Request) { hnolist := strings.Split(r.URL.Path[len("/hn/"):], ":") var buf []string for _, hno := range hnolist { var n string if h, ok := hhash[hno]; ok { n = h.Name } buf = append(buf, n) } w.Write([]byte(strings.Join(buf, ":"))) } /* Get /ht/ -> 2020-03-14 12:34 (2020-04-02) */ func hhstm_handler(w http.ResponseWriter, r *http.Request) { date := "" if fi, err := os.Stat(hhsdb); err == nil { t := fi.ModTime() latest := "0000000001" f, _ := os.Open(hhsdb) defer f.Close() input := bufio.NewScanner(f) for input.Scan() { s := strings.Split(input.Text(), ",") if (strings.Compare(s[0], latest) > 0) { latest = s[0] } } latest = "(" + latest + ")" date = t.Format("2006-01-02 15:04 ") + latest } w.Write([]byte(date)) } /* Get /ha/ -> hhsdb.csv for Mover */ func hhsdb_handler(w http.ResponseWriter, r *http.Request) { b, _ := ioutil.ReadFile(hhsdb) w.Write(b) } /* Get /i/20200110/0800012345.tgz */ func image_handler(w http.ResponseWriter, r *http.Request) { file := r.URL.Path[len("/i/"):] file = filepath.Join(server_root, "images", filepath.FromSlash(file)) f, err := os.Open(file) if err != nil { write_errlog(1, "cannot open " + file) http.NotFound(w, r) return } defer f.Close() fi, _ := f.Stat() w.Header().Set("Content-Type", "rsearcher/octet-stream") w.Header().Set("Content-Length", fmt.Sprintf("%d", fi.Size())) io.Copy(w, f) } /* Get /r/0800012345:0800067890:0800099999:... -> 0800012345,name1,20200101:0800067890,name2,20210405:... */ func recent_handler(w http.ResponseWriter, r *http.Request) { hnolist := strings.Split(r.URL.Path[len("/r/"):], ":") var buf []string for _, hno := range hnolist { s := hno + ",," if h, ok := hhash[hno]; ok { s = h.GetRecent() if h.No == "" { s = hno + s } } buf = append(buf, s) } w.Write([]byte(strings.Join(buf, ":"))) } /* Get /d/20xx -> 20xx0401:20xx0408:... , /d/20xx0401 -> 0800012345:0800098765:... */ func index_handler(w http.ResponseWriter, r *http.Request) { var buf string ymd := r.URL.Path[len("/d/"):] if len(ymd) == 4 { buf = iyhash[ymd] } if len(ymd) == 8 { buf = iymdhash[ymd] } w.Write([]byte(buf[1:])) } /* POST /u/ */ func uphhsdb_handler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { write_errlog(10, "not post method") http.NotFound(w, r) return } f, err := os.Create(hhsdb) if err != nil { write_errlog(11, "cannot create " + hhsdb) http.NotFound(w, r) return } defer f.Close() b, err := ioutil.ReadAll(r.Body) r.Body.Close() if err != nil { write_errlog(12, "cannot read req-body") http.NotFound(w, r) return } br := bytes.NewReader(b) zr, err := gzip.NewReader(br) if err != nil { write_errlog(13, "gzip-reader error") http.NotFound(w, r) return } n, err := io.Copy(f, zr) if err := zr.Close(); err != nil { write_errlog(14, "gzip-reader error") http.NotFound(w, r) return } w.Write([]byte(fmt.Sprintf("%d bytes are recieved.\n", n))) loadDB(); } /* POST /ui/20200401/0800012345.tgz */ func upimage_handler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { write_errlog(20, "not post method") http.NotFound(w, r) return } uri := r.URL.Path[len("/ui/"):] ymd := uri[0:8] tgz := uri[9:] dir := filepath.Join(server_root, "images", ymd) if _, err := os.Stat(dir); os.IsNotExist(err) { os.Mkdir(dir, 0644) } file := filepath.Join(server_root, "images", ymd, tgz) f, err := os.Create(file) if err != nil { write_errlog(21, "cannot create " + file) http.NotFound(w, r) return } defer f.Close() n, err := io.Copy(f, r.Body) if err != nil { write_errlog(22, "cannot copy req-body") http.NotFound(w, r) return } w.Write([]byte(fmt.Sprintf("%d bytes are recieved.\n", n))) } /* Get /dt/ -> 2020-03-14 12:34 (2020-04-02) */ func indextm_handler(w http.ResponseWriter, r *http.Request) { date := "" if fi, err := os.Stat(indexdb); err == nil { t := fi.ModTime() latest := "20200101" f, _ := os.Open(indexdb) defer f.Close() input := bufio.NewScanner(f) for input.Scan() { s := strings.Split(input.Text(), ",") if (strings.Compare(s[1], latest) > 0) { latest = s[1] } } latest = "(" + latest[0:4] + "-" + latest[4:6] + "-" + latest[6:] + ")" date = t.Format("2006-01-02 15:04 ") + latest } w.Write([]byte(date)) } /* Get /hd/ -> 20010401,0800012345,name1\n20010401,0300011111,name2\n... */ func hhsdbidx_handler(w http.ResponseWriter, r *http.Request) { s := "" b, err := ioutil.ReadFile(indexdb) if err != nil { return } rd := csv.NewReader(strings.NewReader(string(b))) for { record, err := rd.Read() if err == io.EOF { break } if err != nil { return } s += strings.Join([]string{record[1], record[0], hhash[record[0]].Name}, ",") s += "\n" } w.Write([]byte(s)) } /* Get /ud/20200402 */ func upidx_handler(w http.ResponseWriter, r *http.Request) { date := r.URL.Path[len("/ud/"):] var buf []string f, _ := os.Open(indexdb) input := bufio.NewScanner(f) for input.Scan() { if !strings.HasSuffix(input.Text(), date) { buf = append(buf, input.Text()) } } f.Close() imgdir := filepath.Join(server_root, "images", date) files, _ := ioutil.ReadDir(imgdir) for _, file := range files { i := file.Name()[0:10] + "," + date buf = append(buf, i) } sort.Sort(sort.Reverse(sort.StringSlice(buf))) os.Remove(indexdb) s := strings.Join(buf, "\n") ioutil.WriteFile(indexdb, []byte(s), 0644) loadDB(); w.Write([]byte("update index done.")) } /* Get /ci/20200402 */ func climage_handler(w http.ResponseWriter, r *http.Request) { date := r.URL.Path[len("/ci/"):] dir := filepath.Join(server_root, "images", date) os.RemoveAll(dir) } /* Get /pw/ -> id1:pw1:id2:pw2:... */ func pw_handler(w http.ResponseWriter, r *http.Request) { b, err := ioutil.ReadFile(pwdb) if err != nil { write_errlog(30, "cannot read passwd-file") http.NotFound(w, r) return } w.Write([]byte(strings.ReplaceAll(string(b), "\n", ":"))) }