schmeckels/autosort.py

70 lines
2.2 KiB
Python

#! /usr/bin/env python3
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from models import Category, Transaction
from helper import get_session, add_category, get_rules
import sys
import click
import colorful as cf
from prompt_toolkit.completion import FuzzyWordCompleter
from prompt_toolkit.shortcuts import prompt
def print_verbose(verbose, string):
if verbose:
print(string)
@click.command(name="autosort")
@click.option("--profile", "-p")
@click.option("--dry-run", default=False, is_flag=True)
@click.option("--verbose", "-v", default=False, is_flag=True)
def command(profile, dry_run, verbose):
session = get_session(profile)
rules = get_rules(profile)
unsorted = session.query(Transaction).filter(Transaction.category_id == None).all()
print("Found {} unsorted transcations".format(len(unsorted)))
new = []
for t in unsorted:
cat_name = apply_rules(t, rules)
if cat_name:
short_name = t.name[:25] if len(t.name) > 25 else t.name
short_desc = t.description[:45] if len(t.description) > 50 else t.description
print_verbose(verbose, "{:<25} | {:<50}| {:>10}".format(short_name, short_desc, t.amount / 100))
print_verbose(verbose, cf.green(f"Matched '{cat_name}'"))
cat_id = session.query(Category).filter(Category.name == cat_name).first()
if not cat_id:
cat_id = add_category(cat_name, profile, session)
t.category_id = cat_id
new.append(t)
print_verbose(verbose, "-" * 90)
print(f"Automatically matched {len(new)} transactions")
if not dry_run:
session.bulk_save_object(new)
session.commit()
def apply_rules(t, rules):
for r in rules:
iban = r.get("iban")
name_regex = r.get("name_regex")
desc_regex = r.get("desc_regex")
if iban:
if t.iban != iban:
continue
if name_regex:
if not name_regex.search(t.name):
continue
if desc_regex:
if not desc_regex.search(t.description):
continue
return r["category"]