Mercurial > mercurial > hgweb_golang.cgi
comparison src/kaigo/Perori/bk.go @ 41:34a474fb83c3
add perori/porori/nk.
| author | pyon@macmini |
|---|---|
| date | Wed, 04 Mar 2020 23:46:59 +0900 |
| parents | |
| children | c58172a59534 |
comparison
equal
deleted
inserted
replaced
| 40:c6df3bae683e | 41:34a474fb83c3 |
|---|---|
| 1 /* | |
| 2 bk.go: Insert Biko & Hatsuban | |
| 3 | |
| 4 Last Change: 2020-03-04 水 16:48:05. | |
| 5 */ | |
| 6 | |
| 7 package main | |
| 8 | |
| 9 /* | |
| 10 #cgo LDFLAGS: -L. -lxdwapi -static | |
| 11 #include <stdio.h> | |
| 12 #include <stdlib.h> | |
| 13 #include <string.h> | |
| 14 #include <io.h> | |
| 15 #include <windows.h> | |
| 16 #include <xdw_api.h> | |
| 17 #include <xdwapian.h> | |
| 18 | |
| 19 #define MAXCOL 1024 | |
| 20 #define MAXLINE 9999 | |
| 21 #define BLOCKSZ 128 | |
| 22 | |
| 23 char* xdw2txt(const char* file) { | |
| 24 char in_path[_MAX_PATH]; | |
| 25 _fullpath(in_path, file, _MAX_PATH); | |
| 26 | |
| 27 XDW_DOCUMENT_HANDLE h = NULL; // 文書ハンドルを開く | |
| 28 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_READONLY, XDW_AUTH_NODIALOGUE}; | |
| 29 if (XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode)) { | |
| 30 printf("Error: cannot open %s\n", file); | |
| 31 return NULL; | |
| 32 } | |
| 33 | |
| 34 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; // 総ページ数を得る | |
| 35 XDW_GetDocumentInformation(h, &info); | |
| 36 int nPage = info.nPages; | |
| 37 | |
| 38 // メイン処理 | |
| 39 char *lpszvalue, *all_lpszvalue; | |
| 40 long datasize[9999]; | |
| 41 for (int i = 1; i <= nPage; i++) { | |
| 42 datasize[i] = XDW_GetPageTextToMemory(h, i, NULL, 0, NULL); | |
| 43 datasize[0] += datasize[i]; | |
| 44 } | |
| 45 datasize[0] += nPage - 1; // for "\n" | |
| 46 all_lpszvalue = (char*)malloc(sizeof(char)*datasize[0]); | |
| 47 all_lpszvalue[0] = '\0'; | |
| 48 for (int i = 1; i <= nPage; i++) { | |
| 49 if (i<nPage) datasize[i]++; // for "\n" | |
| 50 lpszvalue = (char*)malloc(sizeof(char)*(datasize[i])); | |
| 51 XDW_GetPageTextToMemory(h, i, lpszvalue, datasize[i], NULL); | |
| 52 strcat(all_lpszvalue, lpszvalue); | |
| 53 if (i < nPage) strcat(all_lpszvalue, "\n"); | |
| 54 free(lpszvalue); | |
| 55 } | |
| 56 | |
| 57 XDW_CloseDocumentHandle(h, NULL); // 文書ハンドルを閉じる | |
| 58 return all_lpszvalue; | |
| 59 } | |
| 60 | |
| 61 int xdwhb(const char* in_file, const char* out_file, char* hb, const char* stxt) { | |
| 62 int x = 18000; | |
| 63 int y = 1200; | |
| 64 int sz = 110; | |
| 65 | |
| 66 char in_path[_MAX_PATH], out_path[_MAX_PATH]; | |
| 67 _fullpath(in_path, in_file, _MAX_PATH); | |
| 68 _fullpath(out_path, out_file, _MAX_PATH); | |
| 69 | |
| 70 XDW_DOCUMENT_HANDLE h = NULL; | |
| 71 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_UPDATE, XDW_AUTH_NODIALOGUE}; | |
| 72 | |
| 73 int api_result = XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode); | |
| 74 if (api_result < 0) return api_result; | |
| 75 | |
| 76 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; | |
| 77 XDW_GetDocumentInformation(h, &info); | |
| 78 | |
| 79 XDW_FOUND_HANDLE pFoundHandle = NULL; | |
| 80 for (int i = 0; i < info.nPages; i++) { | |
| 81 api_result = XDW_FindTextInPage(h, i + 1, stxt, NULL, &pFoundHandle, NULL); | |
| 82 if (pFoundHandle == NULL) continue; | |
| 83 | |
| 84 XDW_ANNOTATION_HANDLE annoation; | |
| 85 int api_result = XDW_AddAnnotation(h, XDW_AID_TEXT, i + 1, x, y, NULL, &annoation, NULL); | |
| 86 if (api_result < 0) return api_result; | |
| 87 | |
| 88 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_Text, XDW_ATYPE_STRING, hb, 0, NULL); | |
| 89 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_FontSize, XDW_ATYPE_INT, (char*)&sz, 0, NULL); | |
| 90 | |
| 91 int color = XDW_COLOR_NONE; | |
| 92 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_BackColor, XDW_ATYPE_INT, (char*)&color, 0, NULL); | |
| 93 } | |
| 94 | |
| 95 XDW_SaveDocument(h, NULL); | |
| 96 XDW_CloseDocumentHandle(h, NULL); | |
| 97 | |
| 98 api_result = XDW_OptimizeDocument(in_path, out_path, NULL); | |
| 99 return 0; | |
| 100 } | |
| 101 | |
| 102 int xdwbiko(const char* in_file, const int page, const int r, char* biko, char* kubun) { | |
| 103 int x1 = 2000; | |
| 104 int y1 = 4680 + r * 2720; | |
| 105 int sz = 90; | |
| 106 int x2 = 18950; | |
| 107 int y2 = 5090 + r * 2720; | |
| 108 | |
| 109 char in_path[_MAX_PATH]; | |
| 110 _fullpath(in_path, in_file, _MAX_PATH); | |
| 111 | |
| 112 XDW_DOCUMENT_HANDLE h = NULL; | |
| 113 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_UPDATE, XDW_AUTH_NODIALOGUE}; | |
| 114 | |
| 115 int api_result = XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode); | |
| 116 if (api_result < 0) return api_result; | |
| 117 | |
| 118 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; | |
| 119 XDW_GetDocumentInformation(h, &info); | |
| 120 | |
| 121 XDW_ANNOTATION_HANDLE annoation1, annoation2; | |
| 122 int color = XDW_COLOR_NONE; | |
| 123 | |
| 124 api_result = XDW_AddAnnotation(h, XDW_AID_TEXT, page, x1, y1, NULL, &annoation1, NULL); | |
| 125 if (api_result < 0) return api_result; | |
| 126 api_result = XDW_AddAnnotation(h, XDW_AID_TEXT, page, x2, y2, NULL, &annoation2, NULL); | |
| 127 if (api_result < 0) return api_result; | |
| 128 | |
| 129 api_result = XDW_SetAnnotationAttribute(h, annoation1, XDW_ATN_Text, XDW_ATYPE_STRING, biko, 0, NULL); | |
| 130 api_result = XDW_SetAnnotationAttribute(h, annoation1, XDW_ATN_FontSize, XDW_ATYPE_INT, (char*)&sz, 0, NULL); | |
| 131 api_result = XDW_SetAnnotationAttribute(h, annoation1, XDW_ATN_BackColor, XDW_ATYPE_INT, (char*)&color, 0, NULL); | |
| 132 | |
| 133 api_result = XDW_SetAnnotationAttribute(h, annoation2, XDW_ATN_Text, XDW_ATYPE_STRING, kubun, 0, NULL); | |
| 134 api_result = XDW_SetAnnotationAttribute(h, annoation2, XDW_ATN_FontSize, XDW_ATYPE_INT, (char*)&sz, 0, NULL); | |
| 135 api_result = XDW_SetAnnotationAttribute(h, annoation2, XDW_ATN_BackColor, XDW_ATYPE_INT, (char*)&color, 0, NULL); | |
| 136 | |
| 137 XDW_SaveDocument(h, NULL); | |
| 138 XDW_CloseDocumentHandle(h, NULL); | |
| 139 | |
| 140 return 0; | |
| 141 } | |
| 142 | |
| 143 */ | |
| 144 import "C" | |
| 145 | |
| 146 import ( | |
| 147 "bufio" | |
| 148 "encoding/csv" | |
| 149 "fmt" | |
| 150 "flag" | |
| 151 "io/ioutil" | |
| 152 "log" | |
| 153 "os" | |
| 154 "regexp" | |
| 155 "strconv" | |
| 156 "strings" | |
| 157 "time" | |
| 158 | |
| 159 "golang.org/x/text/encoding/japanese" | |
| 160 "golang.org/x/text/transform" | |
| 161 ) | |
| 162 | |
| 163 // Constants | |
| 164 const ( | |
| 165 version = "0.3" | |
| 166 default_ccsvfile = "chosairai.csv" | |
| 167 default_icsvfile = "ikenshoirai.csv" | |
| 168 default_cxdwfile = "KBPC116G.xdw" | |
| 169 default_ixdwfile = "KBPB116G.xdw" | |
| 170 default_tmpxdw = "tmp.xdw" | |
| 171 default_cout = "outc.xdw" | |
| 172 default_iout = "outi.xdw" | |
| 173 default_lout = "xyz.csv" | |
| 174 ) | |
| 175 | |
| 176 var ( | |
| 177 hbi, hbc string // 発番 | |
| 178 start time.Time | |
| 179 | |
| 180 flg_hb int | |
| 181 flg_time bool | |
| 182 | |
| 183 re_hhsno, re_date, re_city, re_name, re_zensp *regexp.Regexp | |
| 184 ) | |
| 185 | |
| 186 func init(){ | |
| 187 os.Remove(default_cout) | |
| 188 os.Remove(default_iout) | |
| 189 os.Remove(default_lout) | |
| 190 | |
| 191 re_hhsno = regexp.MustCompile(`0[1238]\d{8}`) | |
| 192 re_date = regexp.MustCompile(`((明治)|(大正)|(昭和)|(平成)|(令和)).{1,2}年.\d月.\d日`) | |
| 193 re_city = regexp.MustCompile(`(((平成)|(令和)).{1,2}年.\d月.\d日){2}...`) | |
| 194 re_name = regexp.MustCompile(`0[1238]\d{8}.*((平成)|(令和)).{1,2}年.\d月.\d日`) | |
| 195 re_zensp = regexp.MustCompile(` {2,}`) | |
| 196 } | |
| 197 | |
| 198 func main() { | |
| 199 start = time.Now() | |
| 200 /* PRINT HEADER */ | |
| 201 fmt.Println("=======================================") | |
| 202 fmt.Println(" 備考を...する") | |
| 203 fmt.Printf(" - bk [ver %s] -\n", version) | |
| 204 fmt.Println("=======================================\n") | |
| 205 | |
| 206 | |
| 207 /* INITIALIZE FLAGS */ | |
| 208 today := time.Now().Format("20060102") | |
| 209 | |
| 210 flag.StringVar(&today, "d", today, "irai ymd (default today)") | |
| 211 flag.IntVar(&flg_hb, "b", 0, "set hatsuban (default 0)") | |
| 212 flag.BoolVar(&flg_time, "t", false, "print time") | |
| 213 | |
| 214 flag.Parse() | |
| 215 | |
| 216 /* USER INPUT */ | |
| 217 hbi = fmt.Sprintf("%d", flg_hb) | |
| 218 if flg_hb == 0 { | |
| 219 fmt.Print("発番 > ") | |
| 220 fmt.Scan(&hbi) | |
| 221 } | |
| 222 i, err := strconv.Atoi(hbi) | |
| 223 if err != nil { | |
| 224 log.Fatal(err) | |
| 225 } | |
| 226 hbc = fmt.Sprintf("%d", i + 1) | |
| 227 | |
| 228 /* READ BIKO FROM CSV */ | |
| 229 bhash, err := getBiko_fromCSV(default_ccsvfile, today) | |
| 230 if err != nil { | |
| 231 log.Fatal(err) | |
| 232 } | |
| 233 fmt.Println(" 備考データ読込") | |
| 234 step_start := print_time(start) | |
| 235 | |
| 236 /* READ KUBUN FROM CSV */ | |
| 237 khash, err := getKubun_fromCSV(default_icsvfile, bhash) | |
| 238 if err != nil { | |
| 239 log.Fatal(err) | |
| 240 } | |
| 241 fmt.Println(" 申請区分データ読込") | |
| 242 step_start = print_time(start) | |
| 243 | |
| 244 /* INSERT BIKO */ | |
| 245 var ctxt []string | |
| 246 copy_tmp(default_cxdwfile) | |
| 247 for p, t := range xdw2txt(default_cxdwfile) { | |
| 248 for r, hno := range re_hhsno.FindAllString(t, -1) { | |
| 249 if bk, ok := bhash[hno]; ok { | |
| 250 C.xdwbiko(C.CString(default_tmpxdw), C.int(p + 1), C.int(r), C.CString(bk), C.CString(khash[hno])) | |
| 251 } | |
| 252 } | |
| 253 ctxt = append(ctxt, t) | |
| 254 } | |
| 255 fmt.Println(" 備考と申請区分を追加") | |
| 256 | |
| 257 /* INSERT HATSU-BAN & OPTIMIZE */ | |
| 258 stxt, _, _ := transform.String(japanese.ShiftJIS.NewEncoder(), "大仙広介") | |
| 259 C.xdwhb(C.CString(default_tmpxdw), C.CString(default_cout), C.CString(hbi), C.CString(stxt)) | |
| 260 fmt.Println(" 発番追加(調査依頼ファイル)") | |
| 261 step_start = print_time(step_start) | |
| 262 | |
| 263 copy_tmp(default_ixdwfile) | |
| 264 C.xdwhb(C.CString(default_tmpxdw), C.CString(default_iout), C.CString(hbc), C.CString(stxt)) | |
| 265 fmt.Println(" 発番追加( 意見書依頼ファイル)") | |
| 266 step_start = print_time(step_start) | |
| 267 | |
| 268 /* CHOSA IRAI LIST */ | |
| 269 f, err := os.Create(default_lout) | |
| 270 if err != nil { | |
| 271 log.Fatal(err) | |
| 272 } | |
| 273 defer f.Close() | |
| 274 w := bufio.NewWriter(transform.NewWriter(f, japanese.ShiftJIS.NewEncoder())) | |
| 275 | |
| 276 header := []string{"申請日", "被保番", "氏名", "生年月日", "市町村", "-", "-", "-", "依頼日"} | |
| 277 fmt.Fprintln(w, strings.Join(header, ",")) | |
| 278 | |
| 279 var req string | |
| 280 for _, txt := range ctxt { | |
| 281 str := strings.TrimRight(txt, " ") | |
| 282 if strings.HasSuffix(str, "依頼書") { | |
| 283 req = re_date.FindString(str) | |
| 284 req = strings.Replace(req, " ", "", -1) | |
| 285 } else { | |
| 286 row := strings.Split(str, "〒") | |
| 287 for i := 0; i < len(row) - 1; i++ { | |
| 288 var app, hhsno, name, birth, city, empty string | |
| 289 | |
| 290 d := re_date.FindAllString(row[i], -1) | |
| 291 if len(d) > 0 { | |
| 292 birth = strings.Replace(d[0], " ", "", -1) | |
| 293 app = strings.Replace(d[1], " ", "", -1) | |
| 294 } | |
| 295 if re_hhsno.MatchString(row[i]) { | |
| 296 hhsno = "=\"" + re_hhsno.FindString(row[i]) + "\"" | |
| 297 } | |
| 298 if re_name.MatchString(row[i]) { | |
| 299 n := []rune(re_name.FindString(row[i])) | |
| 300 kana := string(n[10:36]) | |
| 301 kana = strings.Trim(kana, " ") | |
| 302 name = string(n[37:55]) | |
| 303 name = strings.Trim(name, " ") | |
| 304 name = re_zensp.ReplaceAllString(name, "") | |
| 305 name += "(" + kana + ")" | |
| 306 } | |
| 307 if re_city.MatchString(row[i]) { | |
| 308 c := []rune(re_city.FindString(row[i])) | |
| 309 city = string(c[len(c)-3:]) | |
| 310 city = strings.Replace(city, "仙北郡", "美郷町", -1) | |
| 311 } | |
| 312 | |
| 313 if hhsno != "" { | |
| 314 fields := []string{app, hhsno, name, birth, city, empty, empty, empty, req} | |
| 315 fmt.Fprintln(w, strings.Join(fields, ",")) | |
| 316 } | |
| 317 } | |
| 318 } | |
| 319 } | |
| 320 w.Flush() | |
| 321 | |
| 322 fmt.Println(" 調査依頼リスト作成") | |
| 323 step_start = print_time(step_start) | |
| 324 | |
| 325 /* CLEAN */ | |
| 326 os.Remove(default_tmpxdw) | |
| 327 fmt.Println(" 終了") | |
| 328 step_start = print_time(step_start) | |
| 329 } | |
| 330 | |
| 331 func getBiko_fromCSV(file, date string) (bikohash map[string]string, err error) { | |
| 332 bikohash = make(map[string]string) | |
| 333 | |
| 334 data, err := ioutil.ReadFile(file) | |
| 335 if err != nil { | |
| 336 return bikohash, err | |
| 337 } | |
| 338 | |
| 339 r := csv.NewReader(strings.NewReader(string(data))) | |
| 340 records, err := r.ReadAll() | |
| 341 if err != nil { | |
| 342 return bikohash, err | |
| 343 } | |
| 344 | |
| 345 for _, record := range records { | |
| 346 hno := strings.TrimSpace(record[0]) | |
| 347 iraiymd := strings.TrimSpace(record[5]) | |
| 348 if iraiymd != date { | |
| 349 continue | |
| 350 } | |
| 351 bikohash[hno] = record[3] | |
| 352 } | |
| 353 | |
| 354 return bikohash, nil | |
| 355 } | |
| 356 | |
| 357 func getKubun_fromCSV(file string, hhshash map[string]string) (kubunhash map[string]string, err error) { | |
| 358 kubunhash = make(map[string]string) | |
| 359 ymdhash := make(map[string]string) | |
| 360 | |
| 361 data, err := ioutil.ReadFile(file) | |
| 362 if err != nil { | |
| 363 return kubunhash, err | |
| 364 } | |
| 365 | |
| 366 r := csv.NewReader(strings.NewReader(string(data))) | |
| 367 records, err := r.ReadAll() | |
| 368 if err != nil { | |
| 369 return kubunhash, err | |
| 370 } | |
| 371 | |
| 372 for _, record := range records { | |
| 373 hno := strings.TrimSpace(record[0]) | |
| 374 if _, ok := hhshash[hno]; !ok { | |
| 375 continue | |
| 376 } | |
| 377 if ymd, ok := ymdhash[hno]; !ok || ymd < record[8] { | |
| 378 ymdhash[hno] = record[8] | |
| 379 } | |
| 380 var buf string | |
| 381 switch strings.TrimSpace(record[9]) { | |
| 382 case "01": | |
| 383 buf = "[新規]" | |
| 384 case "02": | |
| 385 buf = "[更新]" | |
| 386 case "10": | |
| 387 buf = "[支介]" | |
| 388 case "05": | |
| 389 buf = "[区変]" | |
| 390 case "03": | |
| 391 buf = "[転入]" | |
| 392 case "09": | |
| 393 buf = "[証交]" | |
| 394 } | |
| 395 kubun, _, _ := transform.String(japanese.ShiftJIS.NewEncoder(), buf) | |
| 396 kubunhash[hno] = kubun | |
| 397 } | |
| 398 | |
| 399 return kubunhash, nil | |
| 400 } | |
| 401 | |
| 402 | |
| 403 func copy_tmp(file string) error { | |
| 404 os.Remove(default_tmpxdw) | |
| 405 b, err := ioutil.ReadFile(file) | |
| 406 if err != nil { | |
| 407 return err | |
| 408 } | |
| 409 if err := ioutil.WriteFile(default_tmpxdw, b, 0644); err != nil { | |
| 410 return err | |
| 411 } | |
| 412 return nil | |
| 413 } | |
| 414 | |
| 415 func xdw2txt(file string) (txt []string) { | |
| 416 s := C.GoString(C.xdw2txt(C.CString(file))) | |
| 417 r := strings.NewReader(s) | |
| 418 tr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder()) | |
| 419 buf := bufio.NewScanner(tr) | |
| 420 for buf.Scan() { | |
| 421 txt = append(txt, buf.Text()) | |
| 422 } | |
| 423 return | |
| 424 } | |
| 425 | |
| 426 func print_time(t time.Time) time.Time { | |
| 427 now := time.Now() | |
| 428 if !flg_time { | |
| 429 return now | |
| 430 } | |
| 431 elapsed := now.Sub(t) | |
| 432 total := now.Sub(start) | |
| 433 s := fmt.Sprintf("---- Elapsed: %v (total = %v) @ %02d:%02d\n", elapsed, total, now.Hour(), now.Minute()) | |
| 434 fmt.Print(s) | |
| 435 return now | |
| 436 } | |
| 437 |
