fixstmt

Tool to rename bank statements to yyyy-mm-dd format
git clone https://git.bracken.jp/fixstmt.git
Log | Files | Refs | LICENSE

commit a4f4ed2822641a131cc605bf8c45be7ef571e654
parent 80d5a3a3a9c9e458441bf33bc78e55b246d2fe8c
Author: Chris Bracken <chris@bracken.jp>
Date:   Thu, 30 Sep 2021 23:34:22 -0700

Better error handling, add tests

Skips files that don't match the expected RBC filename format. Handle
files with weird capitalisation.

Also adds some minimal tests.

Diffstat:
Mfixrbc.go | 57+++++++++++++++++++++++++++++++++++++--------------------
Afixrbc_test.go | 25+++++++++++++++++++++++++
2 files changed, 62 insertions(+), 20 deletions(-)

diff --git a/fixrbc.go b/fixrbc.go @@ -3,30 +3,47 @@ package main import ( + "errors" "fmt" "io/ioutil" "log" "os" + "regexp" "strings" ) +func IsValidFilename(n string) bool { + r := regexp.MustCompile(`\d+-\d{4}[A-Za-z]{3}\d\d-\d{4}[A-Za-z]{3}\d\d\.pdf`) + return r.MatchString(n) +} + +// SanitizedFilename returns a filename in YYYY-mm-dd.pdf format. As input, it +// takes a filename in default RBC format (ACCTNO-YYYYmmmDD-YYYYmmmDD.pdf). +func SanitizedFilename(n string) (string, error) { + if !IsValidFilename(n) { + return "", errors.New(fmt.Sprintf("invalid filename %s", n)) + } + date := strings.Split(n, "-")[2][0:9] + y := date[0:4] + m, err := getMonthNumber(strings.ToLower(date[4:7])) + if err != nil { + return "", err + } + d := date[7:9] + return fmt.Sprintf("%s-%s-%s.pdf", y, m, d), nil +} + func main() { files, err := ioutil.ReadDir("./") if err != nil { log.Fatal(err) } for _, f := range files { - if strings.HasSuffix(f.Name(), ".pdf") { - // Format: ACCTNO-YYYYmmmDD-YYYYmmmDD.pdf - date := strings.Split(f.Name(), "-")[2][0:9] - y := date[0:4] - m, err := getMonthNumber(date[4:7]) + if IsValidFilename(f.Name()) { + newFname, err := SanitizedFilename(f.Name()) if err != nil { log.Fatal(err) } - d := date[7:9] - - newFname := fmt.Sprintf("%s-%s-%s.pdf", y, m, d) os.Rename(f.Name(), newFname) } } @@ -34,29 +51,29 @@ func main() { func getMonthNumber(m string) (string, error) { switch { - case m == "Jan": + case m == "jan": return "01", nil - case m == "Feb": + case m == "feb": return "02", nil - case m == "Mar": + case m == "mar": return "03", nil - case m == "Apr": + case m == "apr": return "04", nil - case m == "May": + case m == "may": return "05", nil - case m == "Jun": + case m == "jun": return "06", nil - case m == "Jul": + case m == "jul": return "07", nil - case m == "Aug": + case m == "aug": return "08", nil - case m == "Sep": + case m == "sep": return "09", nil - case m == "Oct": + case m == "oct": return "10", nil - case m == "Nov": + case m == "nov": return "11", nil - case m == "Dec": + case m == "dec": return "12", nil } return "", fmt.Errorf("Bad month name: %s", m) diff --git a/fixrbc_test.go b/fixrbc_test.go @@ -0,0 +1,25 @@ +package main + +import "testing" + +func TestSanitizedFilename(t *testing.T) { + cases := []struct { + desc string + in string + expected string + }{ + {"TestJanFeb", "123456-2021jan01-2021feB02.pdf", "2021-02-02.pdf"}, + {"TestMarApr", "123456-2021mAr01-2021aPR02.pdf", "2021-04-02.pdf"}, + {"TestMayJun", "123456-2021May01-2021JuN02.pdf", "2021-06-02.pdf"}, + {"TestJulAug", "123456-2021Jul01-2021AUG02.pdf", "2021-08-02.pdf"}, + {"TestSepOct", "123456-2021sep01-2021ocT02.pdf", "2021-10-02.pdf"}, + {"TestNovDec", "123456-2021nOv01-2021dEC02.pdf", "2021-12-02.pdf"}, + } + + for _, tc := range cases { + actual, _ := SanitizedFilename(tc.in) + if actual != tc.expected { + t.Errorf("%s: expected: %s got %s for input: %s", tc.desc, tc.expected, actual, tc.in) + } + } +}