Mercurial > mercurial > hgweb_kaigo.hg.cgi
diff horori/searcher/server/searcher.go @ 0:aaaa401818a1 draft
first commit.
author | pyon <pyon@macmini> |
---|---|
date | Mon, 24 May 2021 21:32:58 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/horori/searcher/server/searcher.go Mon May 24 21:32:58 2021 +0900 @@ -0,0 +1,462 @@ + /* + 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", ":"))) +} +