~mendelmaleh/pfin

ref: parallel pfin/cmd/main/main.go -rw-r--r-- 1.8 KiB
95ffe938Mendel E Parallelize directory parsing 7 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"sort"
	"sync"
	"text/tabwriter"

	"git.sr.ht/~mendelmaleh/pfin"
	"git.sr.ht/~mendelmaleh/pfin/util"

	_ "git.sr.ht/~mendelmaleh/pfin/parser/amex"
	_ "git.sr.ht/~mendelmaleh/pfin/parser/bofa"
	_ "git.sr.ht/~mendelmaleh/pfin/parser/capitalone"
	_ "git.sr.ht/~mendelmaleh/pfin/parser/personal"
)

type Opts struct {
	Users, Accounts util.StringFilter
}

func main() {
	// flags
	var opts Opts
	flag.StringVar(&opts.Users.String, "user", "", "filter user")
	flag.StringVar(&opts.Accounts.String, "account", "", "filter account")

	flag.Parse()

	// config
	config, err := pfin.ParseConfig("")
	if err != nil {
		log.Fatal("error parsing config: ", err)
	}

	// collect
	ch := make(chan []pfin.Transaction, len(config.Account))
	var wg sync.WaitGroup

	for name, acc := range config.Account {
		if opts.Accounts.Filter(name) {
			continue
		}

		wg.Add(1)
		go func(acc pfin.Account, root string) {
			defer wg.Done()
			tx, err := util.ParseDir(acc, root)
			if err != nil {
				panic(err)
			}

			ch <- tx
		}(acc, config.Pfin.Root)
	}

	wg.Wait()
	close(ch)

	var txns []pfin.Transaction
	for tx := range ch {
		txns = append(txns, tx...)
	}

	// sort oldest to newest
	sort.SliceStable(txns, func(i, j int) bool {
		return txns[i].Date().Before(txns[j].Date())
	})

	tw := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)

	var sum = map[string]float64{}

	for _, tx := range txns {
		if opts.Users.Filter(tx.User()) {
			continue
		}

		if _, ok := sum[tx.User()]; !ok {
			sum[tx.User()] = 0
		}

		sum[tx.User()] += tx.Amount()
		fmt.Fprintln(tw, util.FormatTx(tx, "\t"))
	}

	tw.Flush()
	fmt.Println()

	tw.Init(os.Stdout, 0, 8, 1, '\t', 0)
	for user, total := range sum {
		fmt.Fprintf(tw, "%s\t%.2f\n", user, total)
	}

	tw.Flush()
}