#! /usr/bin/env python3 import os import sys import yaml import re from xdg import XDG_CONFIG_HOME, XDG_DATA_HOME from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker import models import locale try: from yaml import CLoader as Loader except ImportError: from yaml import Loader CONFIG_DIR = os.path.join(XDG_CONFIG_HOME, "schmeckels") DATA_DIR = os.path.join(XDG_DATA_HOME, "schmeckels") def format_amount(cents): amount = cents/100 return f"{amount:,.2f}" def get_list_of_bookable_categories(session): categories = session.query(models.Category).all() return [c for c in categories if c.is_child()] def create_dirs(): for directory in [CONFIG_DIR, DATA_DIR]: try: os.mkdir(directory) except FileExistsError: pass def build_database_filename(profile_name): return f"{DATA_DIR}/databases/{profile_name}.db" def build_rules_filename(profile_name): return f"{DATA_DIR}/rules/{profile_name}.yaml" def check_single_profile(): files = os.listdir(f"{DATA_DIR}/databases") if len(files) == 1: return files.split(".")[0] else: print("--profile is required when you have more than one database.") sys.exit(1) def list_profiles(): files = os.listdir(f"{DATA_DIR}/databases") return [x.split(".")[0] for x in files] def get_session(profile_name): if not profile_name: profile_name = check_single_profile() filename = build_database_filename(profile_name) if os.path.exists(filename) and os.path.isfile(filename): engine = create_engine(f"sqlite:///{filename}") Session = sessionmaker(bind=engine) return Session() else: print(f"No database for profile '{profile_name}'. Did you run 'init'?") sys.exit(1) def get_rules(profile_name): if not profile_name: profile_name = check_single_profile() filename = build_rules_filename(profile_name) if os.path.exists(filename) and os.path.isfile(filename): with open(filename) as fh: data = yaml.load(fh, Loader=Loader) for rule in data: if rule.get("name"): rule["name_regex"] = re.compile(rule["name"]) if rule.get("description"): rule["desc_regex"] = re.compile(rule["description"]) return data else: print(f"No rules for profile '{profile_name}'. Did you run 'init'?") sys.exit(1) def create_category(name, parent, profile, session): c = session.query(models.Category).filter(models.Category.name == name).first() if not c: c = models.Category(name=name, parent_id=parent) session.add(c) session.commit() return c.id def add_category(name, profile, session): parts = name.split(":") if len(parts) == 1: return create_category(name, None, profile, session) else: for i in range(len(parts) - 1): parent = parts[i] child = parts[i + 1] parent_id = create_category(parent, None, profile, session) id = create_category(child, parent_id, profile, session) return id