Mercurial > mercurial > hgweb_golang.cgi
view src/kaigo/fwgo/fwgo.go @ 62:a2c9a535cdd3
add watcher.go
author | pyon@macmini |
---|---|
date | Wed, 14 Oct 2020 21:30:04 +0900 |
parents | 05f3d51ad966 |
children |
line wrap: on
line source
/* fwgo.go: Futan-Wariai de Go Last Change: 2020-07-14 火 15:04:09. */ package main /* #cgo LDFLAGS: -L. -lxdwapi -static #include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> #include <windows.h> #include <xdw_api.h> #include <xdwapian.h> #define MAXLINE 12000 #define BLOCKSZ 128 void xdw2txt(const char* xdwfile, const char* txtfile) { char in_path[_MAX_PATH]; _fullpath(in_path, xdwfile, _MAX_PATH); XDW_DOCUMENT_HANDLE h = NULL; XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_READONLY, XDW_AUTH_NODIALOGUE}; if (XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode)) { printf("XDW Error: cannot open %s\n", xdwfile); return; } int api_result = XDW_GetFullText(h, txtfile, NULL); if (api_result < 0) { printf("Error: cannot write text\n"); return; } XDW_CloseDocumentHandle(h, NULL); } void xdwsplit1(const char* xdwfile) { char in_path[_MAX_PATH]; _fullpath(in_path, xdwfile, _MAX_PATH); XDW_DOCUMENT_HANDLE h = NULL; XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_READONLY, XDW_AUTH_NODIALOGUE}; if (XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode)) { printf("Error: cannot open %s\n", xdwfile); return; } XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; XDW_GetDocumentInformation(h, &info); int nPage = info.nPages; char buf[_MAX_PATH]; for (int i = 1; i <= nPage; i++) { sprintf(buf, "fwtmp_%05d.xdw", i); _fullpath(in_path, buf, _MAX_PATH); int api_result = XDW_GetPage(h, i, in_path, NULL); if (api_result < 0) { printf("XDW Error: cannot get page\n"); return; } } XDW_CloseDocumentHandle(h, NULL); } void xdwmerge(const char* list, const char* output) { FILE *fp; if ((fp = fopen(list, "r")) == NULL) { fprintf(stderr, "can't open file [%s]\n", list); exit(1); } char *all_path = (char*)malloc(MAXLINE * sizeof(char) * _MAX_PATH); if (all_path == NULL) { fprintf(stderr, "can't allocate memory\n"); exit(1); } int n = 0; char *q; char buf[_MAX_PATH]; while (fgets(buf, sizeof buf, fp)) { if ((q = strchr(buf, '\n')) != NULL) { *q = '\0'; } _fullpath(buf, buf, _MAX_PATH); strncpy(&all_path[n * _MAX_PATH], buf, _MAX_PATH); n++; } fclose(fp); char *blk_path = (char*)malloc(BLOCKSZ * sizeof(char) * _MAX_PATH); const char **blk_path_addr = (const char**)malloc((n / BLOCKSZ + 1) * sizeof(char*) * _MAX_PATH); if (blk_path == NULL || blk_path_addr == NULL) { fprintf(stderr, "can't allocate memory\n"); exit(1); } // process by block int api_result; int bn = 0; for (int p = 0, m = 0; p < n; p++) { m = p % BLOCKSZ; if (m == 0 && p > 0) { sprintf(buf, "fwtmp_b%04d.xdw", ++bn); _fullpath(buf, buf, _MAX_PATH); api_result = XDW_MergeXdwFiles(blk_path_addr, BLOCKSZ, buf, NULL); if (api_result < 0) { fprintf(stderr, "can't merge [1] (p = %d, m = %d)\n", p, m); exit(1); } } strncpy(&blk_path[m * _MAX_PATH], &all_path[p * _MAX_PATH], _MAX_PATH); blk_path_addr[m] = &blk_path[m * _MAX_PATH]; } sprintf(buf, "fwtmp_b%04d.xdw", ++bn); _fullpath(buf, buf, _MAX_PATH); int mod = n % BLOCKSZ; if (mod == 0) mod = BLOCKSZ; api_result = XDW_MergeXdwFiles(blk_path_addr, mod, buf, NULL); if (api_result < 0) { fprintf(stderr, "can't merge [2]\n"); exit(1); } // merge blocks for (int b = 0; b < bn; b++) { sprintf(buf, "fwtmp_b%04d.xdw", b + 1); _fullpath(buf, buf, _MAX_PATH); strncpy(&blk_path[b * _MAX_PATH], buf, _MAX_PATH); blk_path_addr[b] = &blk_path[b * _MAX_PATH]; } _fullpath(buf, output, _MAX_PATH ); api_result = XDW_MergeXdwFiles(blk_path_addr, bn, buf, NULL); if (api_result < 0) { fprintf(stderr, "can't merge [3]\n"); exit(1); } free(all_path); free(blk_path); free(blk_path_addr); } int xdwaddannotation(XDW_DOCUMENT_HANDLE h, int page, int x, int y, char* string, int* sz, int tr) { XDW_ANNOTATION_HANDLE annoation; int api_result = XDW_AddAnnotation(h, XDW_AID_TEXT, page, x, y, NULL, &annoation, NULL); if (api_result < 0) { fprintf(stderr, "can't make annotation\n"); return -1; } api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_Text, XDW_ATYPE_STRING, string, 0, NULL); api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_FontSize, XDW_ATYPE_INT, (char*)(sz), 0, NULL); if (tr) { int color = XDW_COLOR_NONE; api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_BackColor, XDW_ATYPE_INT, (char*)(&color), 0, NULL); } return 0; } void xdwaddpage(const char* file, int sp, int atena) { XDW_DOCUMENT_HANDLE h = NULL; XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_UPDATE, XDW_AUTH_NODIALOGUE}; int api_result = XDW_OpenDocumentHandle(file, &h, (XDW_OPEN_MODE*)&mode); if (api_result < 0) { fprintf(stderr, "can't open file\n"); exit(1); } XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0}; XDW_GetDocumentInformation(h, &info); int last_page = info.nPages; int sz = 80; int tr = 1; char pagenum[10]; for (int p = 0; p < last_page; p++) { sprintf(pagenum, "FW-%05d", p + sp); api_result = xdwaddannotation(h, p + 1, 8598, 335, pagenum, &sz, tr); if (atena) api_result = xdwaddannotation(h, p + 1, 1270, 23615, pagenum, &sz, tr); if (api_result < 0) break; } if (api_result >= 0) api_result = XDW_SaveDocument(h, NULL); XDW_CloseDocumentHandle(h, NULL); } */ import "C" import ( "encoding/csv" "flag" "fmt" "io" "io/ioutil" "log" "os" "regexp" "strings" "time" "golang.org/x/text/encoding/japanese" "golang.org/x/text/transform" ) type Data struct { Hno string Page string Zip string SendTo string } func (d *Data) ToCsv() string { s := []string{d.Hno, d.Page, d.Zip, d.SendTo} return strings.Join(s, ",") } var ( ver = "0.1" clean bool skip bool debug bool xdwfile string txtfile = "fwtmp_txt.txt" infofile = "fwtmp_info.csv" orderfile = "order.csv" // input pagefile1 = "fwtmp_page1.txt" // send to sisetsu pagefile2 = "fwtmp_page2.txt" // send to home output1 = "output1.xdw" output2 = "output2.xdw" ) func init() { /* INITIALIZE FLAGS */ flag.BoolVar(&clean, "c", false, "clean temporary files & exit") flag.BoolVar(&skip, "e", false, "use existed files") flag.BoolVar(&debug, "d", false, "debug mode") flag.StringVar(&xdwfile, "i", "KBPV016G.xdw", "target xdw file") } func main() { flag.Parse() /* PRINT HEADER */ fmt.Println("=================================================") fmt.Println(" 負担割合証を... ") fmt.Printf(" - fwgo [ver %s] -\n", ver) fmt.Println("=================================================\n") print_time("now") fmt.Println("[0] start ...") /* CLEAN TEMPORARY DIRECTORY */ os.Remove(output1) os.Remove(output2) if !skip { clean_full() } if clean { os.Exit(0) } print_time("check done") fmt.Println("[1] extract ...") if !skip { C.xdw2txt(C.CString(xdwfile), C.CString(txtfile)) } print_time("extract done.") c := make(chan int) fmt.Println("[2] split ... (run background)") go func() { if !skip { C.xdwsplit1(C.CString(xdwfile)) } print_time("split done.") c <- 1 }() fmt.Println("[3] analize ...") data_hash, err := analize(txtfile, infofile) if err != nil { log.Fatal(err) } print_time("analize done.") debug_print(debug, fmt.Sprintf("len = %d", len(data_hash))) fmt.Println("[4] read order ...") h_order, n, err := read_order(orderfile) if err != nil { log.Fatal(err) } print_time("read order done.") debug_print(debug, fmt.Sprintf("len = %d / %d", len(h_order), n)) fmt.Println("[5] make_list ...") n, m, l, err := make_list(h_order, data_hash, pagefile1, pagefile2) if err != nil { log.Fatal(err) } print_time("make list done.") debug_print(debug, fmt.Sprintf("order, kunai, kugai = %d, %d, %d", n, m, l)) <-c fmt.Println("[6] merge ...") clean_mini() C.xdwmerge(C.CString(pagefile1), C.CString(output1)) print_time("merge 1/2 done.") clean_mini() C.xdwmerge(C.CString(pagefile2), C.CString(output2)) print_time("merge 2/2 done.") fmt.Println("[7] page ...") C.xdwaddpage(C.CString(output1), C.int(1), C.int(0)) print_time("page 1/2 done.") C.xdwaddpage(C.CString(output2), C.int(n + 1), C.int(1)) print_time("page 2/2 done.") if !debug { fmt.Println("[9] clean ...") clean_full() print_time("clean done.") } } func analize(txtfile, infofile string) (map[string]Data, error) { hash := make(map[string]Data) c, err := ioutil.ReadFile(txtfile) if err != nil { return hash, err } r := strings.NewReader(string(c)) tr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder()) b, err := ioutil.ReadAll(tr) if err != nil { return hash, err } regHid := regexp.MustCompile(`05[0-9]{4}0[1238][0-9]{8}`) regZip := regexp.MustCompile(`[0123456789]{3}-[0123456789]{4}`) var csv string buf := strings.Split(string(b), "生年月日年月日") for p, v := range buf[:len(buf)-1] { hid := regHid.FindString(v) hno := hid[6:16] zips := regZip.FindAllString(v, -1) if len(zips) != 2 { fmt.Println("warnig:", hno, "have not 2 zip-pattern") } s := strings.Split(v, zips[1]) s = strings.Split(s[len(s)-1], " 様 ") send := strings.ReplaceAll(s[0], " ", "") page := fmt.Sprintf("%05d", p + 1) data := Data { Hno: hno, Page: page, Zip: zips[1], SendTo: send, } hash[hno] = data csv += data.ToCsv() + "\n" } if err := ioutil.WriteFile(infofile, []byte(csv), 0644); err != nil { return hash, err } return hash, nil; } func read_order(csvfile string) ([]string, int, error) { var order []string c, err := ioutil.ReadFile(csvfile) if err != nil { return order, -1, err } r := strings.NewReader(string(c)) tr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder()) b, err := ioutil.ReadAll(tr) if err != nil { return order, -1, err } n := 0 cr := csv.NewReader(strings.NewReader(string(b))) for { record, err := cr.Read() if err == io.EOF { break } if err != nil { return order, n, err } if strings.HasPrefix(record[0], "0") { order = append(order, record[0]) } n++ } return order, n, nil } func make_list(h_order []string, hash map[string]Data, pagefile1, pagefile2 string) (int, int, int, error) { var n, m, l int var list1, list2 []string done := make(map[string]bool) for _, h := range h_order { if _, ok := done[h]; !ok { if data, ok := hash[h]; ok { list1 = append(list1, data.Page) done[h] = true n++ } } } for _, z := range []string{"014-00", "014-01", "014-08", "014-1413"} { for _, data := range hash { h := data.Hno if _, ok := done[h]; !ok { if strings.HasPrefix(data.Zip, z) { list2 = append(list2, data.Page) done[h] = true m++ } } } } for _, data := range hash { h := data.Hno if _, ok := done[h]; !ok { list2 = append(list2, data.Page) done[h] = true l++ } } if err := write_pagefile(pagefile1, list1); err != nil { return n, m, l, err } if err := write_pagefile(pagefile2, list2); err != nil { return n, m, l, err } return n, m, l, nil } func write_pagefile(file string, list []string) error { f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE, 0755) if err != nil { return err } for _, p := range list { fmt.Fprintf(f, "fwtmp_%s.xdw\n", p) } if err := f.Close(); err != nil { return err } return nil } func print_time(msg string) { now := time.Now() fmt.Printf("\t%v # %s\n", now, msg) } func debug_print(debug bool, msg string) { if debug { fmt.Printf("\t%s\n", msg) } } func clean_full() error { return clean_file("fwtmp_") } func clean_mini() error { return clean_file("fwtmp_b") } func clean_file(prefix string) error { files, err := ioutil.ReadDir(".") if err != nil { return err } for _, file := range files { if strings.HasPrefix(file.Name(), prefix) { os.Remove(file.Name()) continue } } return err }