Compare commits

..

No commits in common. "5f2cb6fcf59d09b9bd52c6e54de600ad6780962d" and "e3756fa442aaa13b94fe1f0affe3461b45259ee3" have entirely different histories.

6 changed files with 26 additions and 69 deletions

View File

@ -194,19 +194,19 @@ def argparser(manager: Manager) -> argparse.ArgumentParser:
p_nordigen_access.set_defaults(func=lambda args: NordigenInput(manager).token()) p_nordigen_access.set_defaults(func=lambda args: NordigenInput(manager).token())
""" """
(Re)new bank requisition ID Access to Nordigen API
""" """
p_nordigen_access = subparsers.add_parser( p_nordigen_access = subparsers.add_parser(
"renew", "renew",
description="(Re)new the Bank requisition ID", description="Renew the requisition ID",
parents=[help], parents=[help],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_nordigen_access.add_argument("name", nargs=1, type=str) p_nordigen_access.add_argument("institution", nargs=1, type=str)
p_nordigen_access.add_argument("country", nargs=1, type=str) p_nordigen_access.add_argument("country", nargs=1, type=str)
p_nordigen_access.set_defaults( p_nordigen_access.set_defaults(
func=lambda args: NordigenInput(manager).requisition( func=lambda args: NordigenInput().requisition(
args.name[0], args.country[0] args.institution[0], args.country[0]
) )
) )

View File

@ -27,7 +27,7 @@ class Transaction:
self.description = " ".join(arg[1].split()) self.description = " ".join(arg[1].split())
self.bank = arg[2] self.bank = arg[2]
if type(arg[3]) is float: if type(arg[3]) is float:
self.value = Decimal(str(arg[3])) self.value = arg[3]
else: else:
self.value = Decimal(args[3]) self.value = Decimal(args[3])
self.category = arg[4] self.category = arg[4]
@ -118,7 +118,6 @@ class Bank:
bic: str bic: str
requisition_id: str requisition_id: str
invert: bool invert: bool
offset: int
key: PrimaryKey = PrimaryKey.ID key: PrimaryKey = PrimaryKey.ID

View File

@ -50,8 +50,7 @@ CREATE TABLE IF NOT EXISTS banks (
nordigen_id TEXT, nordigen_id TEXT,
nordigen_name TEXT, nordigen_name TEXT,
requisition_id TEXT, requisition_id TEXT,
invert INTEGER, invert INTEGER
offset INTEGER
) )
""" """
@ -63,8 +62,7 @@ class DbBank:
nordigen_id: str nordigen_id: str
nordigen_name: str nordigen_name: str
requisition_id: str requisition_id: str
invert: bool = False invert: bool
offset: int = 0
def tuple(self): def tuple(self):
return ( return (
@ -74,7 +72,6 @@ class DbBank:
self.nordigen_name, self.nordigen_name,
self.requisition_id, self.requisition_id,
int(self.invert), int(self.invert),
self.offset,
) )

View File

@ -1,10 +1,9 @@
from datetime import date from datetime import date
from time import sleep from time import sleep
from requests import HTTPError, ReadTimeout from requests import ReadTimeout
from dotenv import load_dotenv from dotenv import load_dotenv
from nordigen import NordigenClient from nordigen import NordigenClient
from uuid import uuid4 from uuid import uuid4
import json
import os import os
import webbrowser import webbrowser
@ -65,22 +64,16 @@ class NordigenInput(Input):
break break
except ReadTimeout: except ReadTimeout:
retries += 1 retries += 1
print(f"Request #{retries} timed-out, retrying in 1s") print(f"Request #{retries} timed-out, waiting 1s")
sleep(1)
except HTTPError as e:
retries += 1
print(f"Request #{retries} failed with {e}, retrying in 1s")
sleep(1) sleep(1)
if not downloaded: if not downloaded:
print(f"Couldn't download transactions for {account}") print(f"Couldn't download transactions for {account}")
continue continue
with open("json/" + bank.name + ".json", "w") as f:
json.dump(downloaded, f)
converted = [ converted = [
convert(t, bank) for t in downloaded["transactions"]["booked"] convert(t, bank.name, bank.invert)
for t in downloaded["transactions"]["booked"]
] ]
transactions.extend( transactions.extend(

View File

@ -4,7 +4,7 @@ from importlib import import_module
import datetime as dt import datetime as dt
import yaml import yaml
from pfbudget.common.types import NoBankSelected, Transaction, Transactions from pfbudget.common.types import Transaction
from pfbudget.utils import utils from pfbudget.utils import utils
Index = namedtuple( Index = namedtuple(
@ -43,7 +43,7 @@ Options = namedtuple(
) )
def parse_data(filename: str, args: dict) -> Transactions: def parse_data(filename: str, args: dict) -> None:
cfg: dict = yaml.safe_load(open("parsers.yaml")) cfg: dict = yaml.safe_load(open("parsers.yaml"))
assert ( assert (
"Banks" in cfg "Banks" in cfg
@ -57,25 +57,17 @@ def parse_data(filename: str, args: dict) -> Transactions:
bank = args["bank"][0] bank = args["bank"][0]
creditcard = None if not args["creditcard"] else args["creditcard"][0] creditcard = None if not args["creditcard"] else args["creditcard"][0]
try: if not creditcard:
options: dict = cfg[bank] options: dict = cfg[bank]
except KeyError as e: else:
banks = cfg["Banks"] options: dict = cfg[bank][creditcard]
raise NoBankSelected(f"{e} not a valid bank, try one of {banks}")
if creditcard:
try:
options = options[creditcard]
except KeyError as e:
creditcards = cfg["CreditCards"]
raise NoBankSelected(f"{e} not a valid bank, try one of {creditcards}")
bank += creditcard bank += creditcard
if args["category"]: if args["category"]:
options["category"] = args["category"][0] options["category"] = args["category"][0]
if options.get("additional_parser"): if options.get("additional_parser"):
parser = getattr(import_module("pfbudget.input.parsers"), bank) parser = getattr(import_module("pfbudget.parsers"), bank)
transactions = parser(filename, bank, options).parse() transactions = parser(filename, bank, options).parse()
else: else:
transactions = Parser(filename, bank, options).parse() transactions = Parser(filename, bank, options).parse()

View File

@ -1,4 +1,3 @@
from datetime import timedelta
from functools import singledispatch from functools import singledispatch
from pfbudget.common.types import Bank, Transaction, TransactionError from pfbudget.common.types import Bank, Transaction, TransactionError
@ -14,15 +13,7 @@ def convert(t):
@convert.register @convert.register
def _(t: Transaction) -> DbTransaction: def _(t: Transaction) -> DbTransaction:
return DbTransaction( return DbTransaction(t.date, t.description, t.bank, t.value, t.category, t.original, t.additional_comment)
t.date,
t.description,
t.bank,
t.value,
t.category,
t.original,
t.additional_comment,
)
@convert.register @convert.register
@ -35,38 +26,23 @@ def _(db: DbTransaction) -> Transaction:
@convert.register @convert.register
def _(db: DbBank, key: str = "") -> Bank: def _(db: DbBank, key: str = "") -> Bank:
bank = Bank(db.name, db.bic, db.requisition_id, db.invert, db.offset, key=key) return Bank(db.name, db.bic, db.requisition_id, db.invert, key=key)
if not bank.invert:
bank.invert = False
if not bank.offset:
bank.offset = 0
return bank
@convert.register @convert.register
def _(bank: Bank) -> DbBank: def _(bank: Bank, key: str = "") -> DbBank:
bank = DbBank( return DbBank(bank.name, bank.bic, "", "", bank.requisition_id, bank.invert)
bank.name, bank.bic, "", "", bank.requisition_id, bank.invert, bank.offset
)
if not bank.invert:
bank.invert = False
if not bank.offset:
bank.offset = 0
return bank
@convert.register @convert.register
def _(json: dict, bank: Bank) -> Transaction: def _(json: dict, bank: str, invert: bool) -> Transaction:
i = -1 if bank.invert else 1 i = -1 if invert else 1
try: try:
transaction = Transaction( return Transaction(
json["bookingDate"], json["bookingDate"],
json["remittanceInformationUnstructured"], json["remittanceInformationUnstructured"],
bank.name, bank,
i * parse_decimal(json["transactionAmount"]["amount"]), i * parse_decimal(json["transactionAmount"]["amount"]),
) )
transaction.date += timedelta(days=bank.offset)
return transaction
except TransactionError: except TransactionError:
print(f"{json} is in the wrong format") print(f"{json} is in the wrong format")