Mercurial > louis > ofxstatement-us-hsbc
changeset 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 | |
files | .hgignore README.rst setup.py src/ofxstatement/plugins/us_hsbc/plugin.py |
diffstat | 4 files changed, 32 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Thu Dec 01 17:14:11 2016 -0800 +++ b/.hgignore Thu Mar 09 22:55:02 2017 -0800 @@ -2,3 +2,4 @@ .*\.py[co]$ .*\.egg-info$ .*\.ofx$ +Session.vim$
--- a/README.rst Thu Dec 01 17:14:11 2016 -0800 +++ b/README.rst Thu Mar 09 22:55:02 2017 -0800 @@ -3,7 +3,8 @@ This only supports the ``ExportData.csv`` file you can download from the "money management" tool found within their online banking interface (`accessible -here`_). +here`_). Note that access to this tool requires an advanced or premier account +with HSBC. ofxstatement can only process one account at a time, so make sure you export each account separately into different files.
--- a/setup.py Thu Dec 01 17:14:11 2016 -0800 +++ b/setup.py Thu Mar 09 22:55:02 2017 -0800 @@ -27,7 +27,7 @@ version=version, author="Louis Opter", author_email="louis@opter.org", - url="https://github.com/lopter/ofxstatement", + url="https://github.com/lopter/ofxstatement-us-hsbc", description=("HSBC (USA) plugin for ofxstatement"), long_description=long_description, license="GPLv3", @@ -57,6 +57,7 @@ "dev": [ "flake8", "mypy-lang", + "typed-ast", "ipython", "pdbpp", "pep8",
--- 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