Browse Source

Added option print month directly from CLI

Simon Watson 1 year ago
parent
commit
06fc5dc2b3
2 changed files with 26 additions and 15 deletions
  1. 1 0
      .gitignore
  2. 25 15
      fin-lisp.lisp

+ 1 - 0
.gitignore

@@ -2,3 +2,4 @@ bks/
 *.enc
 auth.json
 fr-bk.txt
+fl

+ 25 - 15
fin-lisp.lisp

@@ -15,8 +15,6 @@
 ;;; - Upload/download support like perl version
 ;;; TODO
 ;;; - Non interactive CLI Interface
-;;; - Interface is not good, and doesn't protect the user from
-;;;   data entry mistakes
 
 ;;;; Reimplementation of my bills tracker in Lisp
 
@@ -30,6 +28,11 @@
 (defvar *api-url* NIL)
 (defvar *api-key* NIL)
 
+;;; Used for input checking (mostly)
+(defvar *old-month-line-regex* (ppcre:create-scanner "^([A-Z][a-z]{1,})[0-9]{4}$"))
+(defvar *old-exp-line-regex* (ppcre:create-scanner "^([A-Z].*)\ -\ \\\$([0-9]{1,4}) - PAID"))
+(defvar *new-month-line-regex* (ppcre:create-scanner "20[0-9]{4}"))
+
 ;;; Taken from: https://gist.github.com/WetHat/a49e6f2140b401a190d45d31e052af8f
 ;;; Used for pretty printing output
 (defconstant +CELL-FORMATS+ '(:left   "~vA"
@@ -82,7 +85,11 @@
 ;;; Used by "print-month" arg to validate
 ;;; the user provided a valid key
 (defun check-month (month-key)
-  (if (stringp month-key) month-key))
+  (if (stringp month-key) month-key
+      (return-from check-month NIL))
+  (if (ppcre:scan *old-month-line-regex* month-key) month-key
+      (if (ppcre:scan *new-month-line-regex* month-key) month-key
+	  (return-from check-month NIL))))
 
 (opts:define-opts
   (:name :help
@@ -90,8 +97,8 @@
    :short #\h
    :long "help")
   (:name :print-month
-   :description "Print records for given month"
-   :shora #\p
+   :description "Print records for given month. Must conform to either MonthYear or YYYYMM semantics."
+   :short #\p
    :long "print-month"
    :arg-parser #'check-month)
   (:name :interactive-mode
@@ -110,7 +117,7 @@
 
 (defun parse-api-config (path)
   (let ((api-config-hash (yason:parse (uiop:read-file-string path)))
-	(ret-tuple '()))
+	(ret-tuple '())) ; I think this probably can be done in the let binding
     (push (gethash "token" api-config-hash) ret-tuple)
     (push (gethash "url" api-config-hash) ret-tuple)
     ret-tuple))
@@ -168,8 +175,9 @@
 
 ;; Called like: (add-month '202107)
 (defun add-month (month-key)
-  (setf (gethash month-key *records*) (make-hash-table :test 'equalp))
-  month-key)
+  (if (check-month month-key)
+      (setf (gethash month-key *records*) (make-hash-table :test 'equalp))
+      (return-from add-month NIL)))
 
 ;;; Taken from practical common lisp
 (defun prompt-read (prompt)
@@ -188,7 +196,6 @@
       (let ((innerhash (gethash month *records*))
 	    (exp-l (prompt-for-expense)))
 	(setf (gethash (first exp-l) innerhash) (second exp-l)))
-      ;;NIL))
       (add-expense-to-month (add-month month))))
 
 ;;; Given key for *records* hash,
@@ -276,10 +283,15 @@
     (when-option (matches :help)
       (display-help))
     (when-option (matches :print-month)
+      (let ((key (prompt-read "Enter decryption key: "))
+	    (month-key (destructuring-bind (&key print-month) matches
+			 print-month)))
+	(get-records key)
+	(dump-month-table month-key)))
     (when-option (matches :interactive-mode)
       (progn
 	(interactive-mode)
-	(quit))))))
+	(quit)))))
 
 ;;; Can only be called from the REPL,
 ;;; used for importing according to the old schema
@@ -289,16 +301,14 @@
 	    (loop for line = (read-line stream nil)
 		  while line
 		  collect line)))
-	(mre (ppcre:create-scanner "^(.*)[0-9]{4}$"))
-	(ere (ppcre:create-scanner "^([A-Z].*)\ -\ \\\$([0-9]{1,4}) - PAID"))
 	(cur-mon)
 	(cur-exp))
     (loop for line in old-file-lines
 	  do (progn
-	       (if (ppcre:scan mre line) (setf cur-mon line))
-	       (if (ppcre:scan ere line)
+	       (if (ppcre:scan *old-month-line-regex* line) (setf cur-mon line))
+	       (if (ppcre:scan *old-exp-line-regex* line)
 		   (progn
-		     (setf cur-exp (ppcre:register-groups-bind (first second) (ere line) :sharedp t (list first second)))
+		     (setf cur-exp (ppcre:register-groups-bind (first second) (*old-exp-line-regex* line) :sharedp t (list first second)))
 		     (print cur-exp)
 		     (if (gethash cur-mon *records*)
 			 (let ((innerhash (gethash cur-mon *records*)))