[Refactor] Decouple CLI arguments from Manager

The Manager doesn't need to know that it was called from the CLI, so it
now is initialized with the database and performs an action, based on
the operation it receives and its parameters.

The work isn't finished, some Manager actions are still based on the CLI
arguments.

The CLI logic and creation of parameters to pass to the manager have
been moved to the __main__.py file, which brings it to line to the
program being called as a package from the command line.
This commit is contained in:
Luís Murta 2022-12-09 19:43:09 +00:00
parent 471331ffc9
commit f721e6a910
Signed by: satprog
GPG Key ID: 169EF1BBD7049F94
4 changed files with 88 additions and 39 deletions

View File

@ -2,7 +2,10 @@ __all__ = ["argparser", "Manager", "parse_data", "categorize_data"]
__author__ = "Luís Murta" __author__ = "Luís Murta"
__version__ = "0.1" __version__ = "0.1"
from pfbudget.common.types import Operation
from pfbudget.core.categories import categorize_data from pfbudget.core.categories import categorize_data
from pfbudget.core.manager import Manager from pfbudget.core.manager import Manager
from pfbudget.cli.runnable import argparser from pfbudget.cli.runnable import argparser
from pfbudget.input.parsers import parse_data from pfbudget.input.parsers import parse_data
import pfbudget.db.model as types

View File

@ -4,5 +4,73 @@ import pfbudget
if __name__ == "__main__": if __name__ == "__main__":
argparser = pfbudget.argparser() argparser = pfbudget.argparser()
args = vars(argparser.parse_args()) args = vars(argparser.parse_args())
assert "op" in args, "No operation selected"
pfbudget.Manager(args["op"], args).start() assert "op" in args, "No pfbudget.Operation selected"
op: pfbudget.Operation = args["op"]
assert "database" in args, "No database selected"
db = args["database"]
params = None
match (op):
case pfbudget.Operation.CategoryAdd:
assert args.keys() >= {"category", "group"}, "argparser ill defined"
params = [
pfbudget.types.Category(cat, args["group"][0])
for cat in args["category"]
]
case pfbudget.Operation.CategoryUpdate:
assert args.keys() >= {"category", "group"}, "argparser ill defined"
params = [pfbudget.types.Category(cat) for cat in args["category"]]
params.append(args["group"][0])
case pfbudget.Operation.CategoryRemove:
assert "category" in args, "argparser ill defined"
params = [pfbudget.types.Category(cat) for cat in args["category"]]
case pfbudget.Operation.CategorySchedule:
assert args.keys() >= {
"category",
"period",
"frequency",
}, "argparser ill defined"
params = [
pfbudget.types.CategorySchedule(
cat, True, args["period"][0], args["frequency"][0]
)
for cat in args["category"]
]
case pfbudget.Operation.CategoryRule:
assert args.keys() >= {
"category",
"date",
"description",
"bank",
"min",
"max",
}, "argparser ill defined"
params = [
pfbudget.types.CategoryRule(
cat,
args["date"][0] if args["date"] else None,
args["description"][0] if args["description"] else None,
args["bank"][0] if args["bank"] else None,
args["min"][0] if args["min"] else None,
args["max"][0] if args["max"] else None,
)
for cat in args["category"]
]
case pfbudget.Operation.GroupAdd:
assert "group" in args, "argparser ill defined"
params = [pfbudget.types.CategoryGroup(group) for group in args["group"]]
case pfbudget.Operation.GroupRemove:
assert "group" in args, "argparser ill defined"
params = [pfbudget.types.CategoryGroup(group) for group in args["group"]]
pfbudget.Manager(db, args).action(op, params)

View File

@ -11,15 +11,14 @@ from pfbudget.cli.runnable import download, parse
class Manager: class Manager:
def __init__(self, op: Operation, args: dict): def __init__(self, db: str, args: dict):
self._operation = op
self._args = args self._args = args
print(args)
assert "database" in args, "ArgParser didn't include db" self._db = db
self._db = args["database"]
def start(self): def action(self, op: Operation, params: list):
match (self._operation): match (op):
case Operation.Init: case Operation.Init:
pass pass
case Operation.Parse: case Operation.Parse:
@ -49,28 +48,19 @@ class Manager:
case Operation.CategoryAdd: case Operation.CategoryAdd:
with self.db.session() as session: with self.db.session() as session:
for category in self.args["category"]: session.addcategories(params)
session.addcategory(
Category(name=category, group=self.args["group"])
)
case Operation.CategoryUpdate: case Operation.CategoryUpdate:
with self.db.session() as session: with self.db.session() as session:
session.updategroup( session.updategroup(*params)
[Category(name=category) for category in self.args["category"]],
self.args["group"][0],
)
case Operation.CategoryRemove: case Operation.CategoryRemove:
with self.db.session() as session: with self.db.session() as session:
session.removecategory( session.removecategories(params)
[Category(name=category) for category in self.args["category"]]
)
case Operation.CategorySchedule: case Operation.CategorySchedule:
assert ( with self.db.session() as session:
"period" in self.args and "frequency" in self.args session.updateschedules(params)
), "Schedule not well defined"
case Operation.CategoryRule: case Operation.CategoryRule:
with self.db.session() as session: with self.db.session() as session:

View File

@ -84,10 +84,10 @@ class DbClient:
def add(self, transactions: list[Transaction]): def add(self, transactions: list[Transaction]):
self.__session.add_all(transactions) self.__session.add_all(transactions)
def addcategory(self, category: Category): def addcategories(self, category: list[Category]):
self.__session.add(category) self.__session.add_all(category)
def removecategory(self, categories: list[Category]): def removecategories(self, categories: list[Category]):
stmt = delete(Category).where( stmt = delete(Category).where(
Category.name.in_([cat.name for cat in categories]) Category.name.in_([cat.name for cat in categories])
) )
@ -101,20 +101,8 @@ class DbClient:
) )
self.__session.execute(stmt) self.__session.execute(stmt)
def updateschedules( def updateschedules(self, schedules: list[CategorySchedule]):
self, categories: list[Category], schedule: CategorySchedule stmt = insert(CategorySchedule).values([asdict(s) for s in schedules])
):
stmt = insert(CategorySchedule).values(
[
dict(
name=cat.name,
recurring=schedule.recurring,
period=schedule.period,
period_multiplier=schedule.period_multiplier,
)
for cat in categories
]
)
stmt = stmt.on_conflict_do_update( stmt = stmt.on_conflict_do_update(
index_elements=[CategorySchedule.name], index_elements=[CategorySchedule.name],
set_=dict( set_=dict(