from invoice import Invoice, Tax import db from argparse import ArgumentParser as ap import tempfile import subprocess import sqlite3 from configparser import ConfigParser import os from os import path CONFIG_FILE = "" def load_config(): basedir = os.environ.get("XDG_CONFIG_HOME", None) or \ path.join(os.environ["HOME"], ".config") basedir = path.join(basedir, "fracture") confile = path.join(basedir, "config") global CONFIG_FILE CONFIG_FILE = confile conf = ConfigParser() conf.read(confile) # SERIES for k in conf["series"]: Invoice.SERIES[int(k)] = conf["series"][k] if Invoice.SERIES == {}: raise "Invoice series not configured correctly: no series found" # ID FORMAT FORMAT = conf["invoice"].get("id_format", '"%s/%s/%s" % (series, date.year, id)') def f(series, date, id): return eval(FORMAT, None, {"series": series, "date": date, "id": id}) Invoice.ID_FORMAT = f # CURRENCY Invoice.CURRENCY = conf["invoice"].get("currency", "€") Invoice.CURRENCY_DECIMAL = conf["invoice"].getint("currency_decimal", 2) # TEMPLATE ? # TODO # Or dump a json or something? templatefile = conf["invoice"]["template"] if not path.isabs(templatefile): templatefile = path.join(confile, templatefile) # INVOICE LEVEL TAXES (like IRPF in Spain) tax = [] for k in conf["taxes"]: tax.append(Tax(k, conf.getfloat("taxes",k))) Invoice.DEFAULT_TAXES = tuple(tax) # DATABASE Invoice.DB_FILE = path.join(basedir, "invoice.db") if not path.exists(Invoice.DB_FILE): db.create(Invoice.DB_FILE) def call_editor(filename): """ Edit filename with $EDITOR (fallback to Vim) """ if not os.path.exists(filename): raise FileNotFoundError("File not found: " + filename) process = subprocess.Popen([os.environ.get("EDITOR", "vim"), filename],) process.wait() def edit(contents): """ Edit temporary file with initial `contents` and return it"s edited content """ with tempfile.NamedTemporaryFile(mode="w", delete=False) as t: t.write(contents) call_editor(t.name) with open(t.name) as t: edited_content = t.read() if os.path.exists(t.name): os.remove(t.name) return edited_content def edit_config(): # TODO: Generate config file if not created call_editor(CONFIG_FILE) def new_invoice(): num = Invoice.from_config( edit( Invoice().to_config() )).persist() # print(num) # edit(Invoice.load(num).to_config()) def summarize(): pass if __name__ == "__main__": load_config() # create the top-level parser parser = ap(prog="fracture") #parser.add_argument("--foo", action="store_true", help="foo help") parser.set_defaults(func=lambda: parser.print_help()) # make subparsers subparsers = parser.add_subparsers(title= "Subcommands", help="sub-command help") new_parser = subparsers.add_parser("new", aliases=["n"], help="a help") new_parser.set_defaults(func=new_invoice) configure_parser = subparsers.add_parser("configure", aliases=["c","conf"], help="b help") configure_parser.set_defaults(func=edit_config) summary_parser = subparsers.add_parser("summary", aliases=["s", "sum"], help="get summary") summary_parser.add_argument("--xlsx", action="store_true", help="aaa") summary_parser.add_argument("--quarter", action="store_true", help="aaa") summary_parser.add_argument("--year", action="store_true", help="aaa") summary_parser.set_defaults(func=summarize) # parse parser.parse_args().func()