view src/kaigo/fwgo/fw_tmpl.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
##### C_SOURCE #####
*/
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
}