#!/bin/python3 import sys import csv import re from pathlib import Path whitelist_cards = ["7756"] def usage(): print('Usage: ynab.py ') def is_reserved(row): return '(Reservert)' in row[1] def convert_memo(original): original = re.match(r'="[ ]?(.+)"', original).groups()[0] original = original.replace(" Kurs: 1.0000", "") words = original.split(" ") for i in range(20): if words[0] == "": # It's empty del words[0] elif m := re.match(r'\*(\d{4})', words[0]): # It's the last four digits of a card if m.groups()[0] in whitelist_cards: # It's an expected card, ignore it del words[0] else: # It's an unexpected card, move it to the end words.append(words.pop(0)) elif m := re.match(r'\d{2}\.\d{2}', words[0]): # It's the date. Move it to the end words.append(words.pop(0)) elif (m1 := re.match(r'^[A-Z]{3}$', words[0])) and (m2 := re.match(r'[\d]+\.[\d]+', words[1])): # It's the original currency if words[0] == "NOK": # It's Norwegian kroner, ignoring del words[0] del words[0] else: # It's some other currency, move it to the end words.append(words.pop(0)) words.append(words.pop(0)) else: break else: raise Exception(f"Infinite loop while parsing \"{original}\"") return " ".join(words) def convert(reader, writer): header = ['Date', 'Payee', 'Memo', 'Outflow', 'Inflow'] writer.writerow(header) # Ignore header reader.__next__() for row in reader: if is_reserved(row): continue money_out = 0 money_in = 0 if (isinstance(row[3], str)): moneystr = row[3].replace(',', '.') try: money = float(moneystr) if moneystr else 0 except ValueError as e: print(f'Error in row {row}') raise e else: money = float(row[3]) if money >= 0: money_in = money else: money_out = -money memo = convert_memo(row[2]) new_row = [*row[:2], memo, money_out, money_in] writer.writerow(new_row) def main(): if len(sys.argv) != 2: usage() exit(1) filepath = Path(sys.argv[1]) new_basename = f'ynab-{filepath.name}' new_filepath = filepath.parent / new_basename with filepath.open(mode='r') as old_file: reader = csv.reader(old_file, delimiter=';') with new_filepath.open(mode='w') as new_file: writer = csv.writer(new_file) convert(reader, writer) if __name__ == '__main__': main()