diff src/ofxstatement/plugins/us_hsbc/plugin.py @ 9:28548158a325 default tip

Some minor improvements/fixes This will eventually evolve to something more generic, since I have re-used the same design, and some of the parts here, to write a plugin for Charles Schwab.
author Louis Opter <louis@opter.org>
date Thu, 09 Mar 2017 22:55:02 -0800
parents 164da24a2997
children
line wrap: on
line diff
--- a/src/ofxstatement/plugins/us_hsbc/plugin.py	Thu Dec 01 17:14:11 2016 -0800
+++ b/src/ofxstatement/plugins/us_hsbc/plugin.py	Thu Mar 09 22:55:02 2017 -0800
@@ -18,7 +18,6 @@
 import contextlib
 import csv
 import datetime
-import enum
 import locale
 import logging
 import pdb
@@ -28,7 +27,7 @@
 from ofxstatement.parser import CsvStatementParser
 from ofxstatement.plugin import Plugin
 from ofxstatement.statement import StatementLine, generate_transaction_id
-from typing import Any, Dict, Iterable, List
+from typing import Dict, Generator, Iterable, List
 from typing.io import TextIO
 
 from .record import CsvIndexes, Record
@@ -39,13 +38,31 @@
 
 
 @contextlib.contextmanager
-def _override_locale(category, value):
+def _override_locale(category: int, value: str) -> Generator[None, None, None]:
     save = locale.getlocale(category)
     locale.setlocale(category, value)
     yield
     locale.setlocale(category, save)
 
 
+class _spawn_debugger_on_exception:
+
+    def __init__(self, errmsg: str) -> None:
+        self._errmsg = errmsg
+
+    def __enter__(self) -> None:
+        pass
+
+    def __exit__(self, exc_type, exc_value, exc_tb) -> bool:
+        if exc_value is not None:
+            logger.exception(self._errmsg)
+            logger.info("Press {} to exit the debugger".format(
+                "^Z" if sys.platform.startswith("win32") else "^D"
+            ))
+            pdb.post_mortem()
+            sys.exit(1)
+
+
 class Parser(CsvStatementParser):
 
     date_format = "%m/%d/%Y"
@@ -65,6 +82,7 @@
         "CASH CONCENTRATION VENMO": "XFER",
         "DEPOSIT FROM": "DIRECTDEP",
         "DEPOSIT": "DEP",
+        "HSBC SECURITIES": "XFER",
         "INTEREST EARNED AND PAID": "INT",
         "ONLINE PAYMENT TO": "PAYMENT",
         "PAY TO": "PAYMENT",
@@ -106,7 +124,7 @@
             logger.info("Skipping row: {}".format(row))
             return None  # skip (all) the csv headers
 
-        try:
+        with _spawn_debugger_on_exception("Parsing failed:"):
             sl = super(Parser, self).parse_record(row)
             record = Record(row)
 
@@ -123,13 +141,6 @@
 
             self.statement.start_date = min(sl.date, self.statement.start_date)
             self.statement.end_date = max(sl.date, self.statement.end_date)
-        except Exception:
-            logger.exception("Parsing failed:")
-            logger.info("Press {} to exit the debugger".format(
-                "^Z" if sys.platform.startswith("win32") else "^D"
-            ))
-            pdb.post_mortem()
-            sys.exit(1)
 
         return sl
 
@@ -148,9 +159,9 @@
         # XXX: how does this gets closed?
         fin = open(filename, "r", encoding=encoding)
 
-        parser = Parser(fin)
-        parser.statement.bank_id = self.settings.get("routing_number")
-        parser.statement.account_id = self.settings.get("account_number")
-        parser.statement.account_type = self.settings.get("account_type", "CHECKING")
+        p = Parser(fin)
+        p.statement.bank_id = self.settings.get("routing_number")
+        p.statement.account_id = self.settings.get("account_number")
+        p.statement.account_type = self.settings.get("account_type", "CHECKING")
 
-        return parser
+        return p