Operations refactor

Unify the manager operations under one enum.
Start cleaning up the argparser structure to easily add new operations.
This commit is contained in:
Luís Murta 2022-12-08 16:15:53 +00:00
parent d11bc6df1d
commit 72974c90aa
Signed by: satprog
GPG Key ID: 169EF1BBD7049F94
3 changed files with 109 additions and 153 deletions

View File

@ -2,7 +2,7 @@ from pathlib import Path
import argparse import argparse
import re import re
from pfbudget.common.types import Command, Operation from pfbudget.common.types import Operation
from pfbudget.core.categories import categorize_data from pfbudget.core.categories import categorize_data
from pfbudget.input.json import JsonParser from pfbudget.input.json import JsonParser
from pfbudget.input.nordigen import NordigenInput from pfbudget.input.nordigen import NordigenInput
@ -29,18 +29,18 @@ class DataFileMissing(Exception):
def argparser() -> argparse.ArgumentParser: def argparser() -> argparse.ArgumentParser:
help = argparse.ArgumentParser(add_help=False) universal = argparse.ArgumentParser(add_help=False)
help.add_argument( universal.add_argument(
"-db", "-db",
"--database", "--database",
nargs="?", nargs="?",
help="select current database", help="select current database",
default=DEFAULT_DB, default=DEFAULT_DB,
) )
help.add_argument( universal.add_argument(
"-q", "--quiet", action="store_true", help="reduces the amount of verbose" "-q", "--quiet", action="store_true", help="reduces the amount of verbose"
) )
help.add_argument( universal.add_argument(
"-v", "--verbose", action="store_true", help="increases the amount of verbose" "-v", "--verbose", action="store_true", help="increases the amount of verbose"
) )
@ -54,7 +54,7 @@ def argparser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="does cool finance stuff", description="does cool finance stuff",
parents=[help], parents=[universal],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
parser.add_argument( parser.add_argument(
@ -66,7 +66,7 @@ def argparser() -> argparse.ArgumentParser:
).group(1), ).group(1),
) )
subparsers = parser.add_subparsers(dest="command", required=True) subparsers = parser.add_subparsers(required=True)
""" """
Init Init
@ -74,10 +74,10 @@ def argparser() -> argparse.ArgumentParser:
p_init = subparsers.add_parser( p_init = subparsers.add_parser(
"init", "init",
description="Initializes the SQLite3 database", description="Initializes the SQLite3 database",
parents=[help], parents=[universal],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_init.set_defaults(command=Command.Init) p_init.set_defaults(command=Operation.Init)
""" """
Exporting Exporting
@ -85,7 +85,7 @@ def argparser() -> argparse.ArgumentParser:
p_export = subparsers.add_parser( p_export = subparsers.add_parser(
"export", "export",
description="Exports the selected database to a .csv file", description="Exports the selected database to a .csv file",
parents=[help], parents=[universal],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_export.set_defaults(func=lambda args: DatabaseClient(args.database).export()) p_export.set_defaults(func=lambda args: DatabaseClient(args.database).export())
@ -96,14 +96,14 @@ def argparser() -> argparse.ArgumentParser:
p_parse = subparsers.add_parser( p_parse = subparsers.add_parser(
"parse", "parse",
description="Parses and adds the requested transactions into the selected database", description="Parses and adds the requested transactions into the selected database",
parents=[help], parents=[universal],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_parse.add_argument("path", nargs="+", type=str) p_parse.add_argument("path", nargs="+", type=str)
p_parse.add_argument("--bank", nargs=1, type=str) p_parse.add_argument("--bank", nargs=1, type=str)
p_parse.add_argument("--creditcard", nargs=1, type=str) p_parse.add_argument("--creditcard", nargs=1, type=str)
p_parse.add_argument("--category", nargs=1, type=int) p_parse.add_argument("--category", nargs=1, type=int)
p_parse.set_defaults(command=Command.Parse) p_parse.set_defaults(command=Operation.Parse)
""" """
Categorizing Categorizing
@ -111,10 +111,10 @@ def argparser() -> argparse.ArgumentParser:
p_categorize = subparsers.add_parser( p_categorize = subparsers.add_parser(
"categorize", "categorize",
description="Categorizes the transactions in the selected database", description="Categorizes the transactions in the selected database",
parents=[help], parents=[universal],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_categorize.set_defaults(command=Command.Categorize) p_categorize.set_defaults(command=Operation.Categorize)
""" """
Graph Graph
@ -122,7 +122,7 @@ def argparser() -> argparse.ArgumentParser:
p_graph = subparsers.add_parser( p_graph = subparsers.add_parser(
"graph", "graph",
description="Graph of the transactions", description="Graph of the transactions",
parents=[help, period], parents=[universal, period],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_graph.add_argument( p_graph.add_argument(
@ -142,7 +142,7 @@ def argparser() -> argparse.ArgumentParser:
p_report = subparsers.add_parser( p_report = subparsers.add_parser(
"report", "report",
description="Prints report of transaction groups", description="Prints report of transaction groups",
parents=[help, period], parents=[universal, period],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_report.add_argument( p_report.add_argument(
@ -161,7 +161,7 @@ def argparser() -> argparse.ArgumentParser:
p_register = subparsers.add_parser( p_register = subparsers.add_parser(
"register", "register",
description="Register a bank", description="Register a bank",
parents=[help], parents=[universal],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_register.add_argument("bank", type=str, nargs=1, help="bank option help") p_register.add_argument("bank", type=str, nargs=1, help="bank option help")
@ -169,7 +169,7 @@ def argparser() -> argparse.ArgumentParser:
"--requisition", type=str, nargs=1, help="requisition option help" "--requisition", type=str, nargs=1, help="requisition option help"
) )
p_register.add_argument("--invert", action="store_true") p_register.add_argument("--invert", action="store_true")
p_register.set_defaults(command=Command.Register) p_register.set_defaults(command=Operation.Register)
""" """
Unregister bank Unregister bank
@ -177,11 +177,11 @@ def argparser() -> argparse.ArgumentParser:
p_register = subparsers.add_parser( p_register = subparsers.add_parser(
"unregister", "unregister",
description="Unregister a bank", description="Unregister a bank",
parents=[help], parents=[universal],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_register.add_argument("bank", type=str, nargs=1, help="bank option help") p_register.add_argument("bank", type=str, nargs=1, help="bank option help")
p_register.set_defaults(command=Command.Unregister) p_register.set_defaults(command=Operation.Unregister)
""" """
Nordigen API Nordigen API
@ -189,10 +189,10 @@ def argparser() -> argparse.ArgumentParser:
p_nordigen_access = subparsers.add_parser( p_nordigen_access = subparsers.add_parser(
"token", "token",
description="Get new access token", description="Get new access token",
parents=[help], parents=[universal],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_nordigen_access.set_defaults(command=Command.Token) p_nordigen_access.set_defaults(command=Operation.Token)
""" """
(Re)new bank requisition ID (Re)new bank requisition ID
@ -200,12 +200,12 @@ def argparser() -> argparse.ArgumentParser:
p_nordigen_access = subparsers.add_parser( p_nordigen_access = subparsers.add_parser(
"renew", "renew",
description="(Re)new the Bank requisition ID", description="(Re)new the Bank requisition ID",
parents=[help], parents=[universal],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_nordigen_access.add_argument("name", nargs=1, type=str) p_nordigen_access.add_argument("name", 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(command=Command.Renew) p_nordigen_access.set_defaults(command=Operation.Renew)
""" """
Downloading through Nordigen API Downloading through Nordigen API
@ -213,13 +213,13 @@ def argparser() -> argparse.ArgumentParser:
p_nordigen_download = subparsers.add_parser( p_nordigen_download = subparsers.add_parser(
"download", "download",
description="Downloads transactions using Nordigen API", description="Downloads transactions using Nordigen API",
parents=[help, period], parents=[universal, period],
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
p_nordigen_download.add_argument("--id", nargs="+", type=str) p_nordigen_download.add_argument("--id", nargs="+", type=str)
p_nordigen_download.add_argument("--name", nargs="+", type=str) p_nordigen_download.add_argument("--name", nargs="+", type=str)
p_nordigen_download.add_argument("--all", action="store_true") p_nordigen_download.add_argument("--all", action="store_true")
p_nordigen_download.set_defaults(command=Command.Download) p_nordigen_download.set_defaults(command=Operation.Download)
# """ # """
# List available banks on Nordigen API # List available banks on Nordigen API
@ -249,55 +249,9 @@ def argparser() -> argparse.ArgumentParser:
# func=lambda args: manager.parser(JsonParser(vars(args))) # func=lambda args: manager.parser(JsonParser(vars(args)))
# ) # )
# Add category # Categories
p_categories = subparsers.add_parser( category_parser = subparsers.add_parser("category", parents=[universal])
"category", category(category_parser, universal)
parents=[help],
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
p_categories_commands = p_categories.add_subparsers(dest="command", required=True)
p_categories_add = p_categories_commands.add_parser(
"add",
parents=[help],
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
p_categories_add.add_argument("category", nargs="+", type=str)
p_categories_add.add_argument("--group", nargs="?", type=str)
p_categories_add.set_defaults(command=Command.Category, op=Operation.Add)
p_categories_remove = p_categories_commands.add_parser(
"remove",
parents=[help],
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
p_categories_remove.add_argument("category", nargs="+", type=str)
p_categories_remove.add_argument("--group", nargs="?", type=str)
p_categories_remove.set_defaults(command=Command.Category, op=Operation.Remove)
p_categories_addgroup = p_categories_commands.add_parser(
"addgroup",
parents=[help],
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
p_categories_addgroup.add_argument("group", nargs="+", type=str)
p_categories_addgroup.set_defaults(command=Command.Category, op=Operation.AddGroup)
p_categories_removegroup = p_categories_commands.add_parser(
"removegroup",
parents=[help],
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
p_categories_removegroup.add_argument("group", nargs="+", type=str)
p_categories_removegroup.set_defaults(command=Command.Category, op=Operation.RemoveGroup)
p_categories_updategroup = p_categories_commands.add_parser(
"updategroup",
parents=[help],
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
p_categories_updategroup.add_argument("category", nargs="+", type=str)
p_categories_updategroup.add_argument("--group", nargs=1, type=str)
p_categories_updategroup.set_defaults(command=Command.Category, op=Operation.UpdateGroup)
return parser return parser
@ -362,7 +316,40 @@ def download(manager, args: dict):
manager.parser(NordigenInput(manager, args, start, end)) manager.parser(NordigenInput(manager, args, start, end))
def category(parser: argparse.ArgumentParser, universal: argparse.ArgumentParser):
commands = parser.add_subparsers(required=True)
add = commands.add_parser("add", parents=[universal])
add.set_defaults(op=Operation.CategoryAdd)
add.add_argument("category", nargs="+", type=str)
add.add_argument("--group", nargs="?", type=str)
remove = commands.add_parser("remove", parents=[universal])
remove.set_defaults(op=Operation.CategoryRemove)
remove.add_argument("category", nargs="+", type=str)
update = commands.add_parser("update", parents=[universal])
update.set_defaults(op=Operation.CategoryUpdate)
update.add_argument("category", nargs="+", type=str)
update.add_argument("--group", nargs="?", type=str)
group = commands.add_parser("group", parents=[universal])
category_group(group, universal)
def category_group(parser: argparse.ArgumentParser, universal: argparse.ArgumentParser):
commands = parser.add_subparsers(required=True)
add = commands.add_parser("add", parents=[universal])
add.set_defaults(op=Operation.GroupAdd)
add.add_argument("group", nargs="+", type=str)
remove = commands.add_parser("remove", parents=[universal])
remove.set_defaults(op=Operation.GroupRemove)
remove.add_argument("group", nargs="+", type=str)
def run(): def run():
args = vars(argparser().parse_args()) args = vars(argparser().parse_args())
assert "command" in args, "No command selected" assert "op" in args, "No operation selected"
return args["command"], args return args["op"], args

View File

@ -4,7 +4,7 @@ from decimal import Decimal, InvalidOperation
from enum import Enum, auto from enum import Enum, auto
class Command(Enum): class Operation(Enum):
Init = auto() Init = auto()
Parse = auto() Parse = auto()
Download = auto() Download = auto()
@ -13,15 +13,11 @@ class Command(Enum):
Unregister = auto() Unregister = auto()
Token = auto() Token = auto()
Renew = auto() Renew = auto()
Category = auto() CategoryAdd = auto()
CategoryUpdate = auto()
CategoryRemove = auto()
class Operation(Enum): GroupAdd = auto()
Add = auto() GroupRemove = auto()
Remove = auto()
AddGroup = auto()
RemoveGroup = auto()
UpdateGroup = auto()
class TransactionError(Exception): class TransactionError(Exception):

View File

@ -3,7 +3,7 @@ from pfbudget.input.nordigen import NordigenClient
from pfbudget.input.parsers import parse_data from pfbudget.input.parsers import parse_data
from pfbudget.db.client import DbClient from pfbudget.db.client import DbClient
from pfbudget.db.model import Category, CategoryGroup from pfbudget.db.model import Category, CategoryGroup
from pfbudget.common.types import Command, Operation from pfbudget.common.types import Operation
from pfbudget.core.categorizer import Categorizer from pfbudget.core.categorizer import Categorizer
from pfbudget.utils import convert from pfbudget.utils import convert
@ -11,98 +11,71 @@ from pfbudget.cli.runnable import download, parse
class Manager: class Manager:
def __init__(self, command: Command, args: dict): def __init__(self, op: Operation, args: dict):
self.__command = command self._operation = op
self._args = args self._args = args
match (command):
case Command.Init:
pass
case Command.Parse:
pass
case Command.Download:
pass
case Command.Categorize:
pass
case Command.Register:
pass
case Command.Unregister:
pass
case Command.Token:
pass
case Command.Renew:
pass
case Command.Category:
pass
assert "database" in args, "ArgParser didn't include db" assert "database" in args, "ArgParser didn't include db"
self._db = args["database"] self._db = args["database"]
def start(self): def start(self):
match (self.__command): match (self._operation):
case Command.Init: case Operation.Init:
pass pass
case Command.Parse: case Operation.Parse:
# TODO this is a monstrosity, remove when possible # TODO this is a monstrosity, remove when possible
parse(self, self.args) parse(self, self.args)
case Command.Download: case Operation.Download:
# TODO this is a monstrosity, remove when possible # TODO this is a monstrosity, remove when possible
download(self, self.args) download(self, self.args)
case Command.Categorize: case Operation.Categorize:
self.categorize(self.args) self.categorize()
case Command.Register:
case Operation.Register:
# self._db = DbClient(args["database"]) # self._db = DbClient(args["database"])
# self.register(args) # self.register(args)
pass pass
case Command.Unregister: case Operation.Unregister:
# self._db = DbClient(args["database"]) # self._db = DbClient(args["database"])
# self.unregister(args) # self.unregister(args)
pass pass
case Command.Token: case Operation.Token:
NordigenClient(self).token() NordigenClient(self).token()
case Command.Renew: case Operation.Renew:
NordigenClient(self).requisition( NordigenClient(self).requisition(
self.args["name"], self.args["country"] self.args["name"], self.args["country"]
) )
case Command.Category: case Operation.CategoryAdd:
assert "op" in self.args, "category operation not defined"
with self.db.session() as session: with self.db.session() as session:
match self.args["op"]:
case Operation.Add:
for category in self.args["category"]: for category in self.args["category"]:
session.addcategory( session.addcategory(
Category(name=category, group=self.args["group"]) Category(name=category, group=self.args["group"])
) )
case Operation.Remove: case Operation.CategoryUpdate:
session.removecategory( with self.db.session() as session:
[
Category(name=category)
for category in self.args["category"]
]
)
case Operation.UpdateGroup:
session.updategroup( session.updategroup(
[ [Category(name=category) for category in self.args["category"]],
Category(name=category)
for category in self.args["category"]
],
self.args["group"][0], self.args["group"][0],
) )
case Operation.AddGroup: case Operation.CategoryRemove:
with self.db.session() as session:
session.removecategory(
[Category(name=category) for category in self.args["category"]]
)
case Operation.GroupAdd:
with self.db.session() as session:
for group in self.args["group"]: for group in self.args["group"]:
session.addcategorygroup(CategoryGroup(name=group)) session.addcategorygroup(CategoryGroup(name=group))
case Operation.RemoveGroup: case Operation.GroupRemove:
with self.db.session() as session:
session.removecategorygroup( session.removecategorygroup(
[ [CategoryGroup(name=group) for group in self.args["group"]]
CategoryGroup(name=group)
for group in self.args["group"]
]
) )
# def init(self): # def init(self):