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 |