diff --git a/ofx_processor/bpvf_processor/bpvf_cli.py b/ofx_processor/bpvf_processor/bpvf_cli.py new file mode 100644 index 0000000..ca1eb84 --- /dev/null +++ b/ofx_processor/bpvf_processor/bpvf_cli.py @@ -0,0 +1,9 @@ +import click + +from ofx_processor.bpvf_processor.bpvf_processor import BpvfProcessor + + +@click.command(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/bpvf_processor/bpvf_processor.py b/ofx_processor/bpvf_processor/bpvf_processor.py index 8670568..3c1f435 100644 --- a/ofx_processor/bpvf_processor/bpvf_processor.py +++ b/ofx_processor/bpvf_processor/bpvf_processor.py @@ -1,4 +1,8 @@ import re +import sys + +import click +from ofxtools import OFXTree from ofx_processor.utils.processor import Processor, Line @@ -38,3 +42,20 @@ class BpvfLine(Line): class BpvfProcessor(Processor): line_class = BpvfLine + account_name = "bpvf" + + def parse_file(self): + parser = OFXTree() + try: + parser.parse(self.filename) + except FileNotFoundError: + click.secho("Couldn't open ofx file", fg="red") + sys.exit(1) + + ofx = parser.convert() + + if ofx is None: + click.secho("Couldn't parse ofx file", fg="red") + sys.exit(1) + + return ofx.statements[0].transactions diff --git a/ofx_processor/bpvf_processor/main.py b/ofx_processor/bpvf_processor/main.py deleted file mode 100644 index c491b51..0000000 --- a/ofx_processor/bpvf_processor/main.py +++ /dev/null @@ -1,31 +0,0 @@ -import sys - -import click -from ofxtools.Parser import OFXTree - -from ofx_processor.bpvf_processor.bpvf_processor import BpvfProcessor -from ofx_processor.utils import ynab - - -@click.command(help="Process BPVF bank statement (OFX)") -@click.argument("ofx_filename") -def cli(ofx_filename): - parser = OFXTree() - try: - parser.parse(ofx_filename) - except FileNotFoundError: - click.secho("Couldn't open ofx file", fg="red") - sys.exit(1) - - ofx = parser.convert() - - if ofx is None: - click.secho("Couldn't parse ofx file", fg="red") - sys.exit(1) - - processor = BpvfProcessor(ofx.statements[0].transactions) - ynab_transactions = processor.get_transactions() - - click.secho(f"Processed {len(ynab_transactions)} transactions total.", fg="blue") - - ynab.push_transactions(ynab_transactions, "bpvf") diff --git a/ofx_processor/ce_processor/__init__.py b/ofx_processor/ce_processor/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ofx_processor/ce_processor/ce_cli.py b/ofx_processor/ce_processor/ce_cli.py new file mode 100644 index 0000000..0a024b2 --- /dev/null +++ b/ofx_processor/ce_processor/ce_cli.py @@ -0,0 +1,9 @@ +import click + +from ofx_processor.ce_processor.ce_processor import CeProcessor + + +@click.command(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 new file mode 100644 index 0000000..bf2fccf --- /dev/null +++ b/ofx_processor/ce_processor/ce_processor.py @@ -0,0 +1,5 @@ +from ofx_processor.bpvf_processor.bpvf_processor import BpvfProcessor + + +class CeProcessor(BpvfProcessor): + account_name = "ce" diff --git a/ofx_processor/main.py b/ofx_processor/main.py index 1b04a85..c949ddb 100644 --- a/ofx_processor/main.py +++ b/ofx_processor/main.py @@ -1,7 +1,8 @@ import click -import ofx_processor.bpvf_processor.main as bpvf -import ofx_processor.revolut_processor.main as revolut +from ofx_processor.bpvf_processor import bpvf_cli +from ofx_processor.ce_processor import ce_cli +from ofx_processor.revolut_processor import revolut_cli from ofx_processor.utils import ynab CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) @@ -13,8 +14,9 @@ def cli(): pass -cli.add_command(bpvf.cli, name="bpvf") -cli.add_command(revolut.cli, name="revolut") +cli.add_command(bpvf_cli.main, name="bpvf") +cli.add_command(revolut_cli.main, name="revolut") +cli.add_command(ce_cli.main, name="ce") cli.add_command(ynab.config, name="config") if __name__ == "__main__": diff --git a/ofx_processor/revolut_processor/main.py b/ofx_processor/revolut_processor/main.py deleted file mode 100644 index 4b72db8..0000000 --- a/ofx_processor/revolut_processor/main.py +++ /dev/null @@ -1,18 +0,0 @@ -import csv - -import click - -from ofx_processor.revolut_processor.revolut_processor import RevolutProcessor -from ofx_processor.utils import ynab - - -@click.command(help="Process Revolut bank statement (CSV)") -@click.argument("csv_filename") -def cli(csv_filename): - with open(csv_filename) as f: - reader = csv.DictReader(f, delimiter=";") - processor = RevolutProcessor(reader) - ynab_transactions = processor.get_transactions() - - click.secho(f"Processed {len(ynab_transactions)} transactions total.", fg="blue") - ynab.push_transactions(ynab_transactions, "revolut") diff --git a/ofx_processor/revolut_processor/revolut_cli.py b/ofx_processor/revolut_processor/revolut_cli.py new file mode 100644 index 0000000..335da48 --- /dev/null +++ b/ofx_processor/revolut_processor/revolut_cli.py @@ -0,0 +1,9 @@ +import click + +from ofx_processor.revolut_processor.revolut_processor import RevolutProcessor + + +@click.command(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/revolut_processor.py b/ofx_processor/revolut_processor/revolut_processor.py index 12be251..1349b42 100644 --- a/ofx_processor/revolut_processor/revolut_processor.py +++ b/ofx_processor/revolut_processor/revolut_processor.py @@ -1,3 +1,5 @@ +import csv + import dateparser from ofx_processor.utils.processor import Processor, Line @@ -46,3 +48,9 @@ class RevolutLine(Line): class RevolutProcessor(Processor): line_class = RevolutLine + account_name = "revolut" + + def parse_file(self): + with open(self.filename) as f: + reader = csv.DictReader(f, delimiter=";") + return reader diff --git a/ofx_processor/utils/processor.py b/ofx_processor/utils/processor.py index 1d1cd06..ea65969 100644 --- a/ofx_processor/utils/processor.py +++ b/ofx_processor/utils/processor.py @@ -1,5 +1,9 @@ from collections import defaultdict +import click + +from ofx_processor.utils import ynab + class Line: data = None @@ -41,9 +45,19 @@ class Line: class Processor: transaction_ids = defaultdict(int) line_class = Line + account_name = None - def __init__(self, iterable): - self.iterable = iterable + def __init__(self, filename): + self.filename = filename + self.iterable = self.parse_file() + + def parse_file(self): + return [] + + def push_to_ynab(self): + transactions = self.get_transactions() + click.secho(f"Processed {len(transactions)} transactions total.", fg="blue") + ynab.push_transactions(transactions, account=self.account_name) def get_transactions(self): return list(map(self._get_transaction, self.iterable)) diff --git a/ofx_processor/utils/ynab.py b/ofx_processor/utils/ynab.py index 76e30ad..6a53bdb 100644 --- a/ofx_processor/utils/ynab.py +++ b/ofx_processor/utils/ynab.py @@ -17,6 +17,7 @@ def get_default_config(): } default_config["bpvf"] = {"account": ""} default_config["revolut"] = {"account": ""} + default_config["ce"] = {"account": ""} return default_config diff --git a/pyproject.toml b/pyproject.toml index 85ee978..f1de176 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "ofx-processor" -version = "0.5.0" +version = "0.5.1" description = "Personal ofx processor" readme = "README.md" license = "GPL-3.0-or-later"