write banks diff for ledger, filter by bank
parent
bbd51ea9c5
commit
c5c77a2b9b
|
|
@ -33,6 +33,7 @@ type Config struct {
|
||||||
TodoTag string
|
TodoTag string
|
||||||
Uploader Uploader
|
Uploader Uploader
|
||||||
Storage storage.DB
|
Storage storage.DB
|
||||||
|
Banks map[Bank]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var config Config
|
var config Config
|
||||||
|
|
@ -51,6 +52,7 @@ 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, "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")
|
||||||
|
|
@ -81,6 +83,11 @@ func NewConfig() Config {
|
||||||
TodoTag: as.GetString("todotag"),
|
TodoTag: as.GetString("todotag"),
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
Uploader: ul,
|
Uploader: ul,
|
||||||
|
Banks: map[Bank]bool{
|
||||||
|
Chase: strings.Contains(strings.ToLower(as.GetString("banks")), strings.ToLower(Chase.String())),
|
||||||
|
Citi: strings.Contains(strings.ToLower(as.GetString("banks")), strings.ToLower(Citi.String())),
|
||||||
|
UCCU: strings.Contains(strings.ToLower(as.GetString("banks")), strings.ToLower(UCCU.String())),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Uploader == UploaderTodo {
|
if config.Uploader == UploaderTodo {
|
||||||
|
|
|
||||||
2
main.go
2
main.go
|
|
@ -17,7 +17,7 @@ func main() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
for email := range emails {
|
for email := range emails {
|
||||||
transactions, err := Scrape(email)
|
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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
scrape.go
12
scrape.go
|
|
@ -19,27 +19,27 @@ type chaseScraper struct{}
|
||||||
type citiScraper struct{}
|
type citiScraper struct{}
|
||||||
type uccuScraper struct{}
|
type uccuScraper struct{}
|
||||||
|
|
||||||
func Scrape(m *mail.Message) ([]*Transaction, error) {
|
func Scrape(m *mail.Message, banks map[Bank]bool) ([]*Transaction, error) {
|
||||||
scraper, err := buildScraper(m)
|
scraper, err := buildScraper(m, banks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return scraper.scrape(m)
|
return scraper.scrape(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildScraper(m *mail.Message) (scraper, error) {
|
func buildScraper(m *mail.Message, banks map[Bank]bool) (scraper, error) {
|
||||||
subject := fmt.Sprint(m.Header["Subject"])
|
subject := fmt.Sprint(m.Header["Subject"])
|
||||||
if !containsAny(subject, "transaction", "report", "Transaction") {
|
if !containsAny(subject, "transaction", "report", "Transaction") {
|
||||||
return nil, errors.New("cannot build scraper for subject " + subject)
|
return nil, errors.New("cannot build scraper for subject " + subject)
|
||||||
}
|
}
|
||||||
from := fmt.Sprint(m.Header["From"])
|
from := fmt.Sprint(m.Header["From"])
|
||||||
if strings.Contains(from, "Chase") {
|
if strings.Contains(from, "Chase") && banks[Chase] {
|
||||||
return newChaseScraper(), nil
|
return newChaseScraper(), nil
|
||||||
}
|
}
|
||||||
if strings.Contains(from, "Citi") {
|
if strings.Contains(from, "Citi") && banks[Citi] {
|
||||||
return newCitiScraper(), nil
|
return newCitiScraper(), nil
|
||||||
}
|
}
|
||||||
if strings.Contains(from, "Notifications@uccu.com") {
|
if strings.Contains(from, "Notifications@uccu.com") && banks[UCCU] {
|
||||||
return newUCCUScraper(), nil
|
return newUCCUScraper(), nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("unknown sender: " + from)
|
return nil, errors.New("unknown sender: " + from)
|
||||||
|
|
|
||||||
17
upload.go
17
upload.go
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"local/oauth2"
|
"local/oauth2"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -63,16 +62,20 @@ func uploadLedger(config Config, transaction *Transaction) error {
|
||||||
}
|
}
|
||||||
remote += strings.ReplaceAll(transaction.Account, " ", "")
|
remote += strings.ReplaceAll(transaction.Account, " ", "")
|
||||||
fmt.Fprintf(f, "%-50s%-s\n", formatGMailDate(transaction.Date), transaction.Account)
|
fmt.Fprintf(f, "%-50s%-s\n", formatGMailDate(transaction.Date), transaction.Account)
|
||||||
fmt.Fprintf(f, "%-50s%-50s$%.2f\n", "", transaction.Bank, amount)
|
fmt.Fprintf(f, "%-50s%-50s$%.2f\n", "", "AssetAccount:"+transaction.Bank.String(), amount)
|
||||||
fmt.Fprintf(f, "%-50s%-s\n", "", remote)
|
fmt.Fprintf(f, "%-50s%-s\n", "", remote)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatGMailDate(s string) string {
|
func formatGMailDate(s string) string {
|
||||||
time, err := time.Parse("[Mon, 2 Jan 2006 15:04:05 -0700 (MST)]", s)
|
for _, format := range []string{
|
||||||
if err != nil {
|
"[Mon, 2 Jan 2006 15:04:05 -0700 (MST)]",
|
||||||
log.Println(s, err)
|
"[Mon, 2 Jan 2006 15:04:05 -0700]",
|
||||||
return s
|
} {
|
||||||
|
time, err := time.Parse(format, s)
|
||||||
|
if err == nil {
|
||||||
|
return time.Format("2006-01-02")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return time.Format("2006-01-02")
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue