From 4d9e8edec8f41dc329564f5469c6f8baaac45644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Murta?= Date: Thu, 3 Jun 2021 23:11:52 +0100 Subject: [PATCH] Changed run logic to adjust to SQLite db Removed init and restart functions and writes to state file. Moved create tables to init method of DBManager and launch from init command. Restart removed. Rearranged order in runnable.py according to sections. Only init command working since rest of runnable function not updated at the moment. --- logging.conf | 2 +- pfbudget/database.py | 42 +++++++++++------ pfbudget/runnable.py | 107 +++++++++++-------------------------------- 3 files changed, 56 insertions(+), 95 deletions(-) diff --git a/logging.conf b/logging.conf index a777f6d..b78ac54 100644 --- a/logging.conf +++ b/logging.conf @@ -27,7 +27,7 @@ args=(sys.stdout,) class=FileHandler level=NOTSET formatter=complex -args=('logs/pfbudget.log',) +args=('logs/pfbudget.log', 'a',) [formatter_simple] format=%(asctime)s %(message)s diff --git a/pfbudget/database.py b/pfbudget/database.py index 1cf53e2..51109cb 100644 --- a/pfbudget/database.py +++ b/pfbudget/database.py @@ -1,9 +1,9 @@ -import sqlite3 - +import csv +import datetime import logging import logging.config import pathlib - +import sqlite3 if not pathlib.Path("logs").is_dir(): pathlib.Path("logs").mkdir() @@ -87,17 +87,11 @@ FROM transactions class DBManager: """SQLite DB connection manager""" + __EXPORT_DIR = "export" + def __init__(self, db): self.db = db - self.__create_tables( - ( - ("transactions", CREATE_TRANSACTIONS_TABLE), - ("vacations", CREATE_VACATIONS_TABLE), - ("backups", CREATE_BACKUPS_TABLE), - ) - ) - def __execute(self, query, params=None): ret = None try: @@ -140,6 +134,19 @@ class DBManager: logger.info(f"Creating table if it doesn't exist {table_name}") self.__execute(query) + def query(self, query, params=None): + logger.info(f"Executing {query} with params={params}") + return self.__execute(query, params) + + def init(self): + self.__create_tables( + ( + ("transactions", CREATE_TRANSACTIONS_TABLE), + ("vacations", CREATE_VACATIONS_TABLE), + ("backups", CREATE_BACKUPS_TABLE), + ) + ) + def select_all(self): logger.info(f"Reading all transactions from {self.db}") return self.__execute("SELECT * FROM transactions") @@ -176,6 +183,13 @@ class DBManager: logger.info(f"Get transactions by {period}") return self.__execute(SELECT_TRANSACTION_BY_PERIOD, period) - def query(self, query, params=None): - logger.info(f"Executing {query} with params={params}") - return self.__execute(query, params) + def export(self): + filename = pathlib.Path( + "@".join([self.db, datetime.datetime.now().isoformat()]) + ).with_suffix(".csv") + logger.info(f"Exporting {self.db} into {filename}") + transactions = self.select_all() + if not (dir := pathlib.Path(self.__EXPORT_DIR)).is_dir(): + dir.mkdir() + with open(dir / filename, "w", newline="") as f: + csv.writer(f, delimiter="\t").writerows(transactions) diff --git a/pfbudget/runnable.py b/pfbudget/runnable.py index 8add129..31d1ceb 100644 --- a/pfbudget/runnable.py +++ b/pfbudget/runnable.py @@ -2,12 +2,14 @@ from pathlib import Path import argparse import datetime as dt +from .database import DBManager from .graph import discrete, monthly -from .state import pfstate from .transactions import load_transactions, save_transactions from . import report from . import tools +DEFAULT_DB = "data.db" + class PfBudgetInitialized(Exception): pass @@ -21,18 +23,31 @@ class DataFileMissing(Exception): pass -def get_argparser(): +def argparser(): parser = argparse.ArgumentParser(description="does cool finance stuff") + parser.add_argument("--db", help="select current database", default=DEFAULT_DB) parser.add_argument("-q", "--quiet", help="quiet") + parser.add_argument("--version") subparsers = parser.add_subparsers( - dest="task", required=True, help="sub-command help" + dest="command", required=True, help="sub-command help" ) + """ + Init + """ p_init = subparsers.add_parser("init", help="init help") - p_restart = subparsers.add_parser("restart", help="restart help") - p_backup = subparsers.add_parser("backup", help="backup help") + p_init.set_defaults(func=lambda args: DBManager(args.db)) + + """ + Exporting + """ + p_export = subparsers.add_parser("export", help="export help") + p_export.set_defaults(func=lambda args: DBManager(args.db).export()) + p_parse = subparsers.add_parser("parse", help="parse help") + + # p_restart = subparsers.add_parser("restart", help="restart help") p_vacation = subparsers.add_parser( "vacation", help="vacation help format: [YYYY/MM/DD]" ) @@ -40,20 +55,11 @@ def get_argparser(): p_report = subparsers.add_parser("report", help="report help") p_status = subparsers.add_parser("status", help="status help") - p_init.add_argument("raw", help="the raw data dir") - p_init.add_argument("data", help="the parsed data dir") + # p_restart.add_argument("--raw", help="new raw data dir") + # p_restart.add_argument("--data", help="new parsed data dir") - p_restart.add_argument("--raw", help="new raw data dir") - p_restart.add_argument("--data", help="new parsed data dir") - - p_backup.add_argument( - "option", - type=str, - choices=["single", "all", "restore"], - nargs="?", - default="single", - help="backup option help", - ) + # p_export.add_argument("option", type=str, choices=["single", "all", "restore"], nargs="?", default="single", + # help="backup option help") subparser_vacation = p_vacation.add_subparsers( dest="option", required=True, help="vacation suboption help" @@ -85,10 +91,8 @@ def get_argparser(): p_graph_interval.add_argument("--end", type=str, nargs=1, help="graph end date") p_graph_interval.add_argument("--year", type=str, nargs=1, help="graph year") - p_init.set_defaults(func=init) - p_restart.set_defaults(func=restart) - p_backup.set_defaults(func=backup) p_parse.set_defaults(func=parse) + # p_restart.set_defaults(func=restart) p_vacation.set_defaults(func=vacation) p_status.set_defaults(func=status) p_graph.set_defaults(func=graph) @@ -97,43 +101,6 @@ def get_argparser(): return parser -def init(state, args): - """Initialization - - Creates the state file which stores the internal state of the program - for later use. - Calls parse, that parses all raw files into the data directory. - - Args: - state (PFState): Internal state of the program - args (dict): argparse variables - Raises: - PfBudgetInitialized: Raised when there's already an initialized state - """ - if not state: - s = dict( - filename=tools.STATE_FILE, - raw_dir=args.raw, - data_dir=args.data, - raw_files=[], - data_files=[], - vacations=[], - last_backup="", - last_datadir_backup="", - ) - try: - state = pfstate(tools.STATE_FILE, s) - parse(state, args) - except Exception as e: - print(e) - if Path(tools.STATE_FILE).is_file(): - print(f"Deleting {tools.STATE_FILE}") - Path(tools.STATE_FILE).unlink() - - else: - raise PfBudgetInitialized(f"{Path(tools.STATE_FILE)} already exists") - - def restart(state, args): """Restart @@ -167,23 +134,6 @@ def restart(state, args): raise PfBudgetNotInitialized(f"{Path(tools.STATE_FILE)} doesn't exist") -def backup(state, args): - """Backup - - Saves all transactions on transactions_#.csv - - Args: - state (PFState): Internal state of the program - args (dict): argparse variables - """ - if args.option == "single": - tools.backup(state) - elif args.option == "all": - tools.full_backup(state) - elif args.option == "restore": - tools.restore(state) - - def parse(state, args): """Parser @@ -299,8 +249,5 @@ def f_report(state, args): def run(): - parser = get_argparser() - args = parser.parse_args() - - state = pfstate(tools.STATE_FILE) - args.func(state, args) + args = argparser().parse_args() + args.func(args)