2 Commits
v0.6 ... v0.7

Author SHA1 Message Date
bel
3077343c89 add anti-patterns, print acc for ledger, fix chase 2021 from body.read double 2021-07-30 06:28:21 -06:00
bel
24b66d1c46 filter accounts by pattern 2021-07-30 00:07:34 -06:00
4 changed files with 38 additions and 20 deletions

View File

@@ -24,16 +24,18 @@ var uploaders = map[string]Uploader{
} }
type Config struct { type Config struct {
EmailUser string EmailUser string
EmailPass string EmailPass string
EmailIMAP string EmailIMAP string
TodoAddr string TodoAddr string
TodoToken string TodoToken string
TodoList string TodoList string
TodoTag string TodoTag string
Uploader Uploader Uploader Uploader
Storage storage.DB Storage storage.DB
Banks map[Bank]bool Banks map[Bank]bool
AccountsPattern string
AccountsAntiPattern string
} }
var config Config var config Config
@@ -52,7 +54,10 @@ func NewConfig() Config {
as.Append(args.STRING, "todotoken", "todo token", "") as.Append(args.STRING, "todotoken", "todo token", "")
as.Append(args.STRING, "todolist", "todo list", "") as.Append(args.STRING, "todolist", "todo list", "")
as.Append(args.STRING, "todotag", "todo tag", "expense") as.Append(args.STRING, "todotag", "todo tag", "expense")
as.Append(args.STRING, "banks", "uccu,citi,chase", "uccu,citi,chase") as.Append(args.STRING, "banks", "uccu,citi,chase", "uccu,citi,chase")
as.Append(args.STRING, "accounts", "regex to include filter accounts", ".*")
as.Append(args.STRING, "not-accounts", "regex to exclude filter accounts", "zzzzzz")
as.Append(args.STRING, "authaddr", "auth addr", "https://auth.remote.blapointe.com") as.Append(args.STRING, "authaddr", "auth addr", "https://auth.remote.blapointe.com")
as.Append(args.STRING, "store", "store type", "map") as.Append(args.STRING, "store", "store type", "map")
@@ -76,13 +81,15 @@ func NewConfig() Config {
} }
config = Config{ config = Config{
EmailUser: as.GetString("emailuser"), EmailUser: as.GetString("emailuser"),
EmailPass: as.GetString("emailpass"), EmailPass: as.GetString("emailpass"),
EmailIMAP: as.GetString("emailimap"), EmailIMAP: as.GetString("emailimap"),
TodoAddr: as.GetString("todoaddr"), TodoAddr: as.GetString("todoaddr"),
TodoTag: as.GetString("todotag"), TodoTag: as.GetString("todotag"),
Storage: storage, AccountsPattern: as.GetString("accounts"),
Uploader: ul, AccountsAntiPattern: as.GetString("not-accounts"),
Storage: storage,
Uploader: ul,
Banks: map[Bank]bool{ Banks: map[Bank]bool{
Chase: strings.Contains(strings.ToLower(as.GetString("banks")), strings.ToLower(Chase.String())), Chase: strings.Contains(strings.ToLower(as.GetString("banks")), strings.ToLower(Chase.String())),
Citi: strings.Contains(strings.ToLower(as.GetString("banks")), strings.ToLower(Citi.String())), Citi: strings.Contains(strings.ToLower(as.GetString("banks")), strings.ToLower(Citi.String())),

11
main.go
View File

@@ -3,6 +3,7 @@ package main
import ( import (
"local/sandbox/contact/contact" "local/sandbox/contact/contact"
"log" "log"
"regexp"
) )
func main() { func main() {
@@ -16,12 +17,22 @@ func main() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
patterns := regexp.MustCompile(config.AccountsPattern)
antipatterns := regexp.MustCompile(config.AccountsAntiPattern)
for email := range emails { for email := range emails {
transactions, err := Scrape(email, config.Banks) transactions, err := Scrape(email, config.Banks)
if err != nil { if err != nil {
log.Println("failed to scrape email:", err) log.Println("failed to scrape email:", err)
} }
for _, transaction := range transactions { for _, transaction := range transactions {
if !patterns.MatchString(transaction.Account) {
log.Printf("skipping unmatching account pattern %q vs %q", config.AccountsPattern, transaction.Account)
continue
}
if antipatterns.MatchString(transaction.Account) {
log.Printf("skipping match account antipattern %q vs %q", config.AccountsAntiPattern, transaction.Account)
continue
}
if _, err := config.Storage.Get(transaction.ID); err == nil { if _, err := config.Storage.Get(transaction.ID); err == nil {
log.Println("skipping duplicate transaction:", transaction) log.Println("skipping duplicate transaction:", transaction)
} else { } else {

View File

@@ -67,11 +67,11 @@ func containsAny(a string, b ...string) bool {
} }
func (c *chaseScraper) scrape(m *mail.Message) ([]*Transaction, error) { func (c *chaseScraper) scrape(m *mail.Message) ([]*Transaction, error) {
transactions, err := c.scrape2020(m) transactions, err := c.scrape2021(m)
if err == nil && len(transactions) > 0 { if err == nil && len(transactions) > 0 {
return transactions, err return transactions, err
} }
return c.scrape2021(m) return c.scrape2020(m)
} }
func (c *chaseScraper) scrape2021(m *mail.Message) ([]*Transaction, error) { func (c *chaseScraper) scrape2021(m *mail.Message) ([]*Transaction, error) {

View File

@@ -66,7 +66,7 @@ func uploadLedger(config Config, transaction *Transaction) error {
remote += substr remote += substr
} }
fmt.Fprintf(f, "%-50s%-s\n", formatGMailDate(transaction.Date), transaction.Vendor) fmt.Fprintf(f, "%-50s%-s\n", formatGMailDate(transaction.Date), transaction.Vendor)
fmt.Fprintf(f, "%-50s%-50s$%.2f\n", "", "AssetAccount:"+transaction.Bank.String(), amount) fmt.Fprintf(f, "%-50s%-50s$%.2f\n", "", "AssetAccount:"+transaction.Bank.String()+":"+transaction.Account, amount)
fmt.Fprintf(f, "%-50s%-s\n", "", remote) fmt.Fprintf(f, "%-50s%-s\n", "", remote)
return nil return nil
} }