From d34123997822a956348f41fa8a920e0ac0526475 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Sun, 23 Feb 2020 09:23:42 +0100 Subject: [PATCH] Simplify code needed to add a new bank processor --- ofx_processor/bpvf_processor/bpvf_cli.py | 9 ----- ofx_processor/ce_processor/__init__.py | 0 ofx_processor/ce_processor/ce_cli.py | 9 ----- ofx_processor/ce_processor/ce_processor.py | 5 --- .../__init__.py | 0 .../bpvf_processor.py => processors/bpvf.py} | 6 +++ ofx_processor/processors/ce.py | 13 +++++++ .../revolut.py} | 7 ++++ ofx_processor/revolut_processor/__init__.py | 0 .../revolut_processor/revolut_cli.py | 9 ----- ofx_processor/utils/utils.py | 37 +++++++------------ tests/test_bpvf_processor.py | 2 +- tests/test_revolut_processor.py | 2 +- 13 files changed, 42 insertions(+), 57 deletions(-) delete mode 100644 ofx_processor/bpvf_processor/bpvf_cli.py delete mode 100644 ofx_processor/ce_processor/__init__.py delete mode 100644 ofx_processor/ce_processor/ce_cli.py delete mode 100644 ofx_processor/ce_processor/ce_processor.py rename ofx_processor/{bpvf_processor => processors}/__init__.py (100%) rename ofx_processor/{bpvf_processor/bpvf_processor.py => processors/bpvf.py} (88%) create mode 100644 ofx_processor/processors/ce.py rename ofx_processor/{revolut_processor/revolut_processor.py => processors/revolut.py} (86%) delete mode 100644 ofx_processor/revolut_processor/__init__.py delete mode 100644 ofx_processor/revolut_processor/revolut_cli.py diff --git a/ofx_processor/bpvf_processor/bpvf_cli.py b/ofx_processor/bpvf_processor/bpvf_cli.py deleted file mode 100644 index a59be14..0000000 --- a/ofx_processor/bpvf_processor/bpvf_cli.py +++ /dev/null @@ -1,9 +0,0 @@ -import click - -from ofx_processor.bpvf_processor.bpvf_processor import BpvfProcessor - - -@click.command("bpvf", help="Process BPVF bank statement (OFX)") -@click.argument("ofx_filename") -def main(ofx_filename): - BpvfProcessor(ofx_filename).push_to_ynab() diff --git a/ofx_processor/ce_processor/__init__.py b/ofx_processor/ce_processor/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/ofx_processor/ce_processor/ce_cli.py b/ofx_processor/ce_processor/ce_cli.py deleted file mode 100644 index aeae3a2..0000000 --- a/ofx_processor/ce_processor/ce_cli.py +++ /dev/null @@ -1,9 +0,0 @@ -import click - -from ofx_processor.ce_processor.ce_processor import CeProcessor - - -@click.command("ce", help="Process CE bank statement (OFX)") -@click.argument("ofx_filename") -def main(ofx_filename): - CeProcessor(ofx_filename).push_to_ynab() diff --git a/ofx_processor/ce_processor/ce_processor.py b/ofx_processor/ce_processor/ce_processor.py deleted file mode 100644 index bf2fccf..0000000 --- a/ofx_processor/ce_processor/ce_processor.py +++ /dev/null @@ -1,5 +0,0 @@ -from ofx_processor.bpvf_processor.bpvf_processor import BpvfProcessor - - -class CeProcessor(BpvfProcessor): - account_name = "ce" diff --git a/ofx_processor/bpvf_processor/__init__.py b/ofx_processor/processors/__init__.py similarity index 100% rename from ofx_processor/bpvf_processor/__init__.py rename to ofx_processor/processors/__init__.py diff --git a/ofx_processor/bpvf_processor/bpvf_processor.py b/ofx_processor/processors/bpvf.py similarity index 88% rename from ofx_processor/bpvf_processor/bpvf_processor.py rename to ofx_processor/processors/bpvf.py index 3c1f435..23809a9 100644 --- a/ofx_processor/bpvf_processor/bpvf_processor.py +++ b/ofx_processor/processors/bpvf.py @@ -59,3 +59,9 @@ class BpvfProcessor(Processor): sys.exit(1) return ofx.statements[0].transactions + + @staticmethod + @click.command("bpvf", help="Process BPVF bank statement (OFX)") + @click.argument("ofx_filename") + def main(ofx_filename): + BpvfProcessor(ofx_filename).push_to_ynab() diff --git a/ofx_processor/processors/ce.py b/ofx_processor/processors/ce.py new file mode 100644 index 0000000..5ccdc6f --- /dev/null +++ b/ofx_processor/processors/ce.py @@ -0,0 +1,13 @@ +import click + +from ofx_processor.processors.bpvf import BpvfProcessor + + +class CeProcessor(BpvfProcessor): + account_name = "ce" + + @staticmethod + @click.command("ce", help="Process CE bank statement (OFX)") + @click.argument("ofx_filename") + def main(ofx_filename): + CeProcessor(ofx_filename).push_to_ynab() diff --git a/ofx_processor/revolut_processor/revolut_processor.py b/ofx_processor/processors/revolut.py similarity index 86% rename from ofx_processor/revolut_processor/revolut_processor.py rename to ofx_processor/processors/revolut.py index 1349b42..076cea9 100644 --- a/ofx_processor/revolut_processor/revolut_processor.py +++ b/ofx_processor/processors/revolut.py @@ -1,5 +1,6 @@ import csv +import click import dateparser from ofx_processor.utils.processor import Processor, Line @@ -54,3 +55,9 @@ class RevolutProcessor(Processor): with open(self.filename) as f: reader = csv.DictReader(f, delimiter=";") return reader + + @staticmethod + @click.command("revolut", help="Process Revolut bank statement (CSV)") + @click.argument("csv_filename") + def main(csv_filename): + RevolutProcessor(csv_filename).push_to_ynab() diff --git a/ofx_processor/revolut_processor/__init__.py b/ofx_processor/revolut_processor/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/ofx_processor/revolut_processor/revolut_cli.py b/ofx_processor/revolut_processor/revolut_cli.py deleted file mode 100644 index 32e4753..0000000 --- a/ofx_processor/revolut_processor/revolut_cli.py +++ /dev/null @@ -1,9 +0,0 @@ -import click - -from ofx_processor.revolut_processor.revolut_processor import RevolutProcessor - - -@click.command("revolut", help="Process Revolut bank statement (CSV)") -@click.argument("csv_filename") -def main(csv_filename): - RevolutProcessor(csv_filename).push_to_ynab() diff --git a/ofx_processor/utils/utils.py b/ofx_processor/utils/utils.py index 5b23575..bb41782 100644 --- a/ofx_processor/utils/utils.py +++ b/ofx_processor/utils/utils.py @@ -3,34 +3,25 @@ import pkgutil import click -import ofx_processor +from ofx_processor import processors def discover_processors(cli: click.Group): """ - Discover processors. To be discovered, CLIs need to match the following structure: + Discover processors. - ofx_processor - ├── __init__.py - └── _processor -    ├── __init__.py -    ├── _cli.py -    └── _processor.py - - Preferably, package_name and module_name are the same, but there is no restriction. - Finally, a "main" function will be looked for inside the _cli module. - This function must be a Click command with a unique name and will be added to the - main command line interface. + To be discovered, processors must: + * Be in the `processors` package. + * Declare a Processor class + * Declare a static main function in this class, + which must be a click command :param cli: The main CLI to add discovered processors to. """ - prefix = ofx_processor.__name__ + "." - for package in pkgutil.iter_modules(ofx_processor.__path__, prefix): - if package.name.endswith("_processor"): - module_prefix = package.name + "." - package = importlib.import_module(package.name) - for module in pkgutil.iter_modules(package.__path__, module_prefix): - if module.name.endswith("_cli"): - module = importlib.import_module(module.name) - if "main" in dir(module): - cli.add_command(module.main) + prefix = processors.__name__ + "." + for module in pkgutil.iter_modules(processors.__path__, prefix): + module = importlib.import_module(module.name) + for item in dir(module): + if item.endswith("Processor") and item != "Processor": + cls = getattr(module, item) + cli.add_command(cls.main) diff --git a/tests/test_bpvf_processor.py b/tests/test_bpvf_processor.py index f7c3e21..f512910 100644 --- a/tests/test_bpvf_processor.py +++ b/tests/test_bpvf_processor.py @@ -1,6 +1,6 @@ import unittest -from ofx_processor.bpvf_processor.bpvf_processor import _process_name_and_memo +from ofx_processor.processors.bpvf import _process_name_and_memo class MyTestCase(unittest.TestCase): diff --git a/tests/test_revolut_processor.py b/tests/test_revolut_processor.py index 63750be..810c5c2 100644 --- a/tests/test_revolut_processor.py +++ b/tests/test_revolut_processor.py @@ -1,7 +1,7 @@ import datetime import unittest -from ofx_processor.revolut_processor.revolut_processor import ( +from ofx_processor.processors.revolut import ( _amount_str_to_float, RevolutLine, )