Mercurial > mercurial > hgweb_kaigo.hg.cgi
comparison 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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:aaaa401818a1 |
|---|---|
| 1 /* | |
| 2 Last Change: 2020-06-23 火 15:48:49. | |
| 3 */ | |
| 4 | |
| 5 package main | |
| 6 | |
| 7 import ( | |
| 8 "bufio" | |
| 9 "bytes" | |
| 10 "compress/gzip" | |
| 11 "encoding/csv" | |
| 12 "fmt" | |
| 13 "io" | |
| 14 "io/ioutil" | |
| 15 "log" | |
| 16 "net" | |
| 17 "net/http" | |
| 18 "os" | |
| 19 "path/filepath" | |
| 20 "sort" | |
| 21 "strconv" | |
| 22 "strings" | |
| 23 "time" | |
| 24 ) | |
| 25 | |
| 26 type hhs struct { | |
| 27 No string | |
| 28 //Birth string | |
| 29 Name string | |
| 30 //Kana string | |
| 31 Addr string | |
| 32 //Sex string | |
| 33 Ccn []string | |
| 34 } | |
| 35 | |
| 36 func (h *hhs) GetData() string { | |
| 37 s := strings.Join(h.Ccn, "#") | |
| 38 s = strings.Join([]string{h.Name, h.Addr, s}, ":") | |
| 39 return s | |
| 40 } | |
| 41 | |
| 42 func (h *hhs) GetRecent() string { | |
| 43 ccn := "" | |
| 44 if len(h.Ccn) > 0 { | |
| 45 ccn = h.Ccn[0] | |
| 46 } | |
| 47 return strings.Join([]string{h.No, h.Name, ccn}, ",") | |
| 48 } | |
| 49 | |
| 50 var ( | |
| 51 server string | |
| 52 port string | |
| 53 hhsdb string | |
| 54 indexdb string | |
| 55 pwdb string | |
| 56 server_root string | |
| 57 hhash map[string]hhs | |
| 58 iymdhash map[string]string | |
| 59 iyhash map[string]string | |
| 60 logfile string | |
| 61 ) | |
| 62 | |
| 63 func init() { | |
| 64 port = ":3910" | |
| 65 hhsdb = "hhsdb.csv" | |
| 66 indexdb = "index.csv" | |
| 67 pwdb = "passwd" | |
| 68 logfile = "searcher.log" | |
| 69 } | |
| 70 | |
| 71 func main() { | |
| 72 server_root = filepath.Dir(os.Args[0]) | |
| 73 hhsdb = filepath.Join(server_root, hhsdb) | |
| 74 indexdb = filepath.Join(server_root, indexdb) | |
| 75 pwdb = filepath.Join(server_root, pwdb) | |
| 76 | |
| 77 // setting IP-Address & Port | |
| 78 addrs, err := net.InterfaceAddrs() | |
| 79 if err != nil { | |
| 80 log.Fatal(err) | |
| 81 } | |
| 82 for _, a := range addrs { | |
| 83 if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { | |
| 84 if strings.HasPrefix(ipnet.IP.String(), "169.254") { | |
| 85 continue | |
| 86 } | |
| 87 if ipnet.IP.To4() != nil { | |
| 88 server = ipnet.IP.String() + port | |
| 89 } | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 if err := loadDB(); err != nil { | |
| 94 log.Fatal(err) | |
| 95 } | |
| 96 | |
| 97 // Http-Handler | |
| 98 http.HandleFunc("/h/", hhs_handler) // Get /h/0800012345 -> name:addr:20200101#20210701#... | |
| 99 http.HandleFunc("/hn/", hhsnm_handler) // Get /hn/0800012345:0800098765:... -> name1:name2:... | |
| 100 http.HandleFunc("/ht/", hhstm_handler) // Get /ht/ -> 2020-03-14 12:34 (2020-04-02) | |
| 101 http.HandleFunc("/ha/", hhsdb_handler) // Get /ha/ -> hhsdb.csv for Mover | |
| 102 http.HandleFunc("/i/", image_handler) // Get /i/20200110/0800012345.tgz | |
| 103 http.HandleFunc("/r/", recent_handler) // Get /r/0800012345:0800067890:0800099999:... -> 0800012345,name1,20200101:0800067890,name2,20210405:... | |
| 104 http.HandleFunc("/d/", index_handler) // Get /d/20xx -> 20xx0401:20xx0408:... , /d/20xx0401 -> 0800012345:0800098765:... | |
| 105 http.HandleFunc("/dt/", indextm_handler) // Get /dt/ -> 2020-03-14 12:34 (2020-04-02) | |
| 106 http.HandleFunc("/hd/", hhsdbidx_handler)// Get /hd/ -> 20010401,0800012345,name1\n20010401,0300011111,name2\n... | |
| 107 http.HandleFunc("/ud/", upidx_handler) // Get /ud/20200402 | |
| 108 http.HandleFunc("/u/", uphhsdb_handler) // POST /u/ | |
| 109 http.HandleFunc("/ui/", upimage_handler) // POST /ui/20200401/0800012345.tgz | |
| 110 http.HandleFunc("/ci/", climage_handler) // Get /ci/20200402 -> remove dir | |
| 111 http.HandleFunc("/pw/", pw_handler) // Get /pw/ -> id1:pw1:id2:pw2:... | |
| 112 | |
| 113 log.Fatal(http.ListenAndServe(server, nil)) | |
| 114 } | |
| 115 | |
| 116 /** FUNCTIONS **/ | |
| 117 func loadDB() error { | |
| 118 hhash = make(map[string]hhs) | |
| 119 iymdhash = make(map[string]string) | |
| 120 iyhash = make(map[string]string) | |
| 121 | |
| 122 b, err := ioutil.ReadFile(hhsdb) | |
| 123 if err != nil { | |
| 124 return err | |
| 125 } | |
| 126 r := csv.NewReader(strings.NewReader(string(b))) | |
| 127 for { | |
| 128 record, err := r.Read() | |
| 129 if err == io.EOF { | |
| 130 break | |
| 131 } | |
| 132 if err != nil { | |
| 133 return err | |
| 134 } | |
| 135 h := hhs{ | |
| 136 No: record[0], //Birth: record[1], | |
| 137 Name: record[2], //Kana: record[3], | |
| 138 Addr: record[4], //Sex: record[5], | |
| 139 } | |
| 140 hhash[record[0]] = h | |
| 141 } | |
| 142 | |
| 143 b, err = ioutil.ReadFile(indexdb) | |
| 144 if err != nil { | |
| 145 return err | |
| 146 } | |
| 147 r = csv.NewReader(strings.NewReader(string(b))) | |
| 148 for { | |
| 149 record, err := r.Read() | |
| 150 if err == io.EOF { | |
| 151 break | |
| 152 } | |
| 153 if err != nil { | |
| 154 return err | |
| 155 } | |
| 156 h := hhash[record[0]] | |
| 157 ccn := h.Ccn | |
| 158 h.Ccn = append(ccn, record[1]) | |
| 159 hhash[record[0]] = h | |
| 160 | |
| 161 iymdhash[record[1]] += ":" + record[0] | |
| 162 } | |
| 163 | |
| 164 for ymd, _ := range iymdhash { | |
| 165 y := ymd[0:4] | |
| 166 if ymd[4:6] == "01" || ymd[4:6] == "02" || ymd[4:6] == "03" { | |
| 167 yy, _ := strconv.Atoi(y) | |
| 168 y = fmt.Sprintf("%d", yy - 1) | |
| 169 } | |
| 170 iyhash[y] += ":" + ymd | |
| 171 } | |
| 172 | |
| 173 return nil | |
| 174 } | |
| 175 | |
| 176 func write_errlog(no int, msg string) { | |
| 177 log := filepath.Join(server_root, logfile) | |
| 178 t := time.Now().Format("2006-01-02 15:04") | |
| 179 msg = fmt.Sprintf("%s [%02d] %s\n", t, no, msg) | |
| 180 f, _ := os.OpenFile(log, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) | |
| 181 f.Write([]byte(msg)) | |
| 182 f.Close() | |
| 183 } | |
| 184 | |
| 185 /** HTTP HANDLERS **/ | |
| 186 /* Get /h/0800012345 -> name:addr:20200101#20210701#... */ | |
| 187 func hhs_handler(w http.ResponseWriter, r *http.Request) { | |
| 188 hno := r.URL.Path[len("/h/"):] | |
| 189 s := "" | |
| 190 if h, ok := hhash[hno]; ok { | |
| 191 s = h.GetData() | |
| 192 } | |
| 193 w.Write([]byte(s)) | |
| 194 } | |
| 195 | |
| 196 /* Get /hn/0800012345:0800098765:... -> name1:name2:... */ | |
| 197 func hhsnm_handler(w http.ResponseWriter, r *http.Request) { | |
| 198 hnolist := strings.Split(r.URL.Path[len("/hn/"):], ":") | |
| 199 var buf []string | |
| 200 for _, hno := range hnolist { | |
| 201 var n string | |
| 202 if h, ok := hhash[hno]; ok { | |
| 203 n = h.Name | |
| 204 } | |
| 205 buf = append(buf, n) | |
| 206 } | |
| 207 w.Write([]byte(strings.Join(buf, ":"))) | |
| 208 } | |
| 209 | |
| 210 /* Get /ht/ -> 2020-03-14 12:34 (2020-04-02) */ | |
| 211 func hhstm_handler(w http.ResponseWriter, r *http.Request) { | |
| 212 date := "" | |
| 213 if fi, err := os.Stat(hhsdb); err == nil { | |
| 214 t := fi.ModTime() | |
| 215 latest := "0000000001" | |
| 216 | |
| 217 f, _ := os.Open(hhsdb) | |
| 218 defer f.Close() | |
| 219 input := bufio.NewScanner(f) | |
| 220 for input.Scan() { | |
| 221 s := strings.Split(input.Text(), ",") | |
| 222 if (strings.Compare(s[0], latest) > 0) { | |
| 223 latest = s[0] | |
| 224 } | |
| 225 } | |
| 226 | |
| 227 latest = "(" + latest + ")" | |
| 228 date = t.Format("2006-01-02 15:04 ") + latest | |
| 229 } | |
| 230 w.Write([]byte(date)) | |
| 231 } | |
| 232 | |
| 233 /* Get /ha/ -> hhsdb.csv for Mover */ | |
| 234 func hhsdb_handler(w http.ResponseWriter, r *http.Request) { | |
| 235 b, _ := ioutil.ReadFile(hhsdb) | |
| 236 w.Write(b) | |
| 237 } | |
| 238 | |
| 239 /* Get /i/20200110/0800012345.tgz */ | |
| 240 func image_handler(w http.ResponseWriter, r *http.Request) { | |
| 241 file := r.URL.Path[len("/i/"):] | |
| 242 file = filepath.Join(server_root, "images", filepath.FromSlash(file)) | |
| 243 | |
| 244 f, err := os.Open(file) | |
| 245 if err != nil { | |
| 246 write_errlog(1, "cannot open " + file) | |
| 247 http.NotFound(w, r) | |
| 248 return | |
| 249 } | |
| 250 defer f.Close() | |
| 251 | |
| 252 fi, _ := f.Stat() | |
| 253 | |
| 254 w.Header().Set("Content-Type", "rsearcher/octet-stream") | |
| 255 w.Header().Set("Content-Length", fmt.Sprintf("%d", fi.Size())) | |
| 256 io.Copy(w, f) | |
| 257 } | |
| 258 | |
| 259 /* Get /r/0800012345:0800067890:0800099999:... -> 0800012345,name1,20200101:0800067890,name2,20210405:... */ | |
| 260 func recent_handler(w http.ResponseWriter, r *http.Request) { | |
| 261 hnolist := strings.Split(r.URL.Path[len("/r/"):], ":") | |
| 262 var buf []string | |
| 263 for _, hno := range hnolist { | |
| 264 s := hno + ",," | |
| 265 if h, ok := hhash[hno]; ok { | |
| 266 s = h.GetRecent() | |
| 267 if h.No == "" { | |
| 268 s = hno + s | |
| 269 } | |
| 270 } | |
| 271 buf = append(buf, s) | |
| 272 } | |
| 273 w.Write([]byte(strings.Join(buf, ":"))) | |
| 274 } | |
| 275 | |
| 276 /* Get /d/20xx -> 20xx0401:20xx0408:... , /d/20xx0401 -> 0800012345:0800098765:... */ | |
| 277 func index_handler(w http.ResponseWriter, r *http.Request) { | |
| 278 var buf string | |
| 279 ymd := r.URL.Path[len("/d/"):] | |
| 280 if len(ymd) == 4 { | |
| 281 buf = iyhash[ymd] | |
| 282 } | |
| 283 if len(ymd) == 8 { | |
| 284 buf = iymdhash[ymd] | |
| 285 } | |
| 286 w.Write([]byte(buf[1:])) | |
| 287 } | |
| 288 | |
| 289 /* POST /u/ */ | |
| 290 func uphhsdb_handler(w http.ResponseWriter, r *http.Request) { | |
| 291 if r.Method != http.MethodPost { | |
| 292 write_errlog(10, "not post method") | |
| 293 http.NotFound(w, r) | |
| 294 return | |
| 295 } | |
| 296 | |
| 297 f, err := os.Create(hhsdb) | |
| 298 if err != nil { | |
| 299 write_errlog(11, "cannot create " + hhsdb) | |
| 300 http.NotFound(w, r) | |
| 301 return | |
| 302 } | |
| 303 defer f.Close() | |
| 304 | |
| 305 b, err := ioutil.ReadAll(r.Body) | |
| 306 r.Body.Close() | |
| 307 if err != nil { | |
| 308 write_errlog(12, "cannot read req-body") | |
| 309 http.NotFound(w, r) | |
| 310 return | |
| 311 } | |
| 312 | |
| 313 br := bytes.NewReader(b) | |
| 314 zr, err := gzip.NewReader(br) | |
| 315 if err != nil { | |
| 316 write_errlog(13, "gzip-reader error") | |
| 317 http.NotFound(w, r) | |
| 318 return | |
| 319 } | |
| 320 n, err := io.Copy(f, zr) | |
| 321 | |
| 322 if err := zr.Close(); err != nil { | |
| 323 write_errlog(14, "gzip-reader error") | |
| 324 http.NotFound(w, r) | |
| 325 return | |
| 326 } | |
| 327 | |
| 328 w.Write([]byte(fmt.Sprintf("%d bytes are recieved.\n", n))) | |
| 329 | |
| 330 loadDB(); | |
| 331 } | |
| 332 | |
| 333 /* POST /ui/20200401/0800012345.tgz */ | |
| 334 func upimage_handler(w http.ResponseWriter, r *http.Request) { | |
| 335 if r.Method != http.MethodPost { | |
| 336 write_errlog(20, "not post method") | |
| 337 http.NotFound(w, r) | |
| 338 return | |
| 339 } | |
| 340 | |
| 341 uri := r.URL.Path[len("/ui/"):] | |
| 342 ymd := uri[0:8] | |
| 343 tgz := uri[9:] | |
| 344 | |
| 345 dir := filepath.Join(server_root, "images", ymd) | |
| 346 | |
| 347 if _, err := os.Stat(dir); os.IsNotExist(err) { | |
| 348 os.Mkdir(dir, 0644) | |
| 349 } | |
| 350 | |
| 351 file := filepath.Join(server_root, "images", ymd, tgz) | |
| 352 f, err := os.Create(file) | |
| 353 if err != nil { | |
| 354 write_errlog(21, "cannot create " + file) | |
| 355 http.NotFound(w, r) | |
| 356 return | |
| 357 } | |
| 358 defer f.Close() | |
| 359 | |
| 360 n, err := io.Copy(f, r.Body) | |
| 361 if err != nil { | |
| 362 write_errlog(22, "cannot copy req-body") | |
| 363 http.NotFound(w, r) | |
| 364 return | |
| 365 } | |
| 366 w.Write([]byte(fmt.Sprintf("%d bytes are recieved.\n", n))) | |
| 367 } | |
| 368 | |
| 369 /* Get /dt/ -> 2020-03-14 12:34 (2020-04-02) */ | |
| 370 func indextm_handler(w http.ResponseWriter, r *http.Request) { | |
| 371 date := "" | |
| 372 if fi, err := os.Stat(indexdb); err == nil { | |
| 373 t := fi.ModTime() | |
| 374 latest := "20200101" | |
| 375 | |
| 376 f, _ := os.Open(indexdb) | |
| 377 defer f.Close() | |
| 378 input := bufio.NewScanner(f) | |
| 379 for input.Scan() { | |
| 380 s := strings.Split(input.Text(), ",") | |
| 381 if (strings.Compare(s[1], latest) > 0) { | |
| 382 latest = s[1] | |
| 383 } | |
| 384 } | |
| 385 | |
| 386 latest = "(" + latest[0:4] + "-" + latest[4:6] + "-" + latest[6:] + ")" | |
| 387 date = t.Format("2006-01-02 15:04 ") + latest | |
| 388 } | |
| 389 w.Write([]byte(date)) | |
| 390 } | |
| 391 | |
| 392 /* Get /hd/ -> 20010401,0800012345,name1\n20010401,0300011111,name2\n... */ | |
| 393 func hhsdbidx_handler(w http.ResponseWriter, r *http.Request) { | |
| 394 s := "" | |
| 395 b, err := ioutil.ReadFile(indexdb) | |
| 396 if err != nil { | |
| 397 return | |
| 398 } | |
| 399 rd := csv.NewReader(strings.NewReader(string(b))) | |
| 400 for { | |
| 401 record, err := rd.Read() | |
| 402 if err == io.EOF { | |
| 403 break | |
| 404 } | |
| 405 if err != nil { | |
| 406 return | |
| 407 } | |
| 408 s += strings.Join([]string{record[1], record[0], hhash[record[0]].Name}, ",") | |
| 409 s += "\n" | |
| 410 } | |
| 411 w.Write([]byte(s)) | |
| 412 } | |
| 413 | |
| 414 /* Get /ud/20200402 */ | |
| 415 func upidx_handler(w http.ResponseWriter, r *http.Request) { | |
| 416 date := r.URL.Path[len("/ud/"):] | |
| 417 var buf []string | |
| 418 | |
| 419 f, _ := os.Open(indexdb) | |
| 420 input := bufio.NewScanner(f) | |
| 421 for input.Scan() { | |
| 422 if !strings.HasSuffix(input.Text(), date) { | |
| 423 buf = append(buf, input.Text()) | |
| 424 } | |
| 425 } | |
| 426 f.Close() | |
| 427 | |
| 428 imgdir := filepath.Join(server_root, "images", date) | |
| 429 files, _ := ioutil.ReadDir(imgdir) | |
| 430 for _, file := range files { | |
| 431 i := file.Name()[0:10] + "," + date | |
| 432 buf = append(buf, i) | |
| 433 } | |
| 434 sort.Sort(sort.Reverse(sort.StringSlice(buf))) | |
| 435 | |
| 436 os.Remove(indexdb) | |
| 437 | |
| 438 s := strings.Join(buf, "\n") | |
| 439 ioutil.WriteFile(indexdb, []byte(s), 0644) | |
| 440 | |
| 441 loadDB(); | |
| 442 w.Write([]byte("update index done.")) | |
| 443 } | |
| 444 | |
| 445 /* Get /ci/20200402 */ | |
| 446 func climage_handler(w http.ResponseWriter, r *http.Request) { | |
| 447 date := r.URL.Path[len("/ci/"):] | |
| 448 dir := filepath.Join(server_root, "images", date) | |
| 449 os.RemoveAll(dir) | |
| 450 } | |
| 451 | |
| 452 /* Get /pw/ -> id1:pw1:id2:pw2:... */ | |
| 453 func pw_handler(w http.ResponseWriter, r *http.Request) { | |
| 454 b, err := ioutil.ReadFile(pwdb) | |
| 455 if err != nil { | |
| 456 write_errlog(30, "cannot read passwd-file") | |
| 457 http.NotFound(w, r) | |
| 458 return | |
| 459 } | |
| 460 w.Write([]byte(strings.ReplaceAll(string(b), "\n", ":"))) | |
| 461 } | |
| 462 |
