X-Git-Url: https://piware.de/gitweb/?a=blobdiff_plain;f=consors-report.py;h=f76deb3ea6211cc68e5b117548f8ea5e028fb1a8;hb=refs%2Fheads%2Fmaster;hp=12397554da9431814f1154cc89c0df785371d1b1;hpb=7f495ed42f5540f1ff924505c2676718159285ae;p=bin.git diff --git a/consors-report.py b/consors-report.py index 1239755..81c7e39 100755 --- a/consors-report.py +++ b/consors-report.py @@ -2,6 +2,7 @@ import argparse import collections +import csv import itertools import re from collections import namedtuple @@ -14,17 +15,19 @@ CATEGORIES = { 'Gehalt/Steuern': re.compile('Gehalt/Rente|RED HAT|Finanzamt|FK Guenzburg', re.I), 'Wohnung': re.compile('Telekom|hands4home|Goetzfried|Green Planet Energy|Beitragsservice.*Rundfunk', re.I), 'Medizin': re.compile(r'Apotheke|MVZ|\bmed\b|ZAB Abrechnung|Caika|HNOeins|PVS|Dr\..*Sellier|' - r'BFS Health|Streifeneder|Labor|Physio|(Drescher.*Lung)|(Debeka.*Überweisung)|(DKV.*Überweisung)', re.I), - 'Versicherung': re.compile('(debeka|DKV|Hallesche|Versicherung|Alte Leipziger|ConceptIF|' - 'Baloise).*Lastschrift', re.I), - 'Transport': re.compile('DB Vertrieb|Deutsche Bahn|Nextbike', re.I), - 'Lebensmittel': re.compile('BIOS|Wolf|Ruta|Rewe', re.I), - 'Eigentumswohnungen': re.compile('Rechnung Darl.-Leistung|Semmelweis', re.I), - 'Hobby/Sport': re.compile('Holstein|Mrs. Sporty|Kieser|DJK', re.I), - 'Sparen': re.compile('Bausparkasse Mainz AG|FIL Fondsbank|MIG (Fonds|GmbH)|Netfonds AG', re.I), + r'BFS Health|Streifeneder|Labor|Physio|(Drescher.*Lung)|Osteopath|' + '(Dr.*Borchers)|(Debeka.*Überweisung)|(DKV.*Überweisung)|Beihilfe|Klinik|' + 'Niklas Hermann', re.I), + 'Versicherung': re.compile('((debeka|DKV|Hallesche|Versicherung|Alte Leipziger|ConceptIF|' + 'Baloise).*Lastschrift)|Hallesche.*Bonu', re.I), + 'Transport': re.compile('DB Vertrieb|DB Fernverkehr|Deutsche Bahn|Nextbike|Carsharing|Radstation', re.I), + 'Lebensmittel': re.compile('BIOS|Bäcker|Baecker|Ruta|Rewe', re.I), + 'Eigentumswohnungen': re.compile('Rechnung Darl.-Leistung|Semmelweis|BHP Buerkner', re.I), + 'Hobby/Sport': re.compile('Holstein|Mrs. Sporty|Kieser|DJK|Dimaso', re.I), + 'Sparen': re.compile('Bausparkasse Mainz AG|FIL Fondsbank|MIG (Fonds|GmbH)|Netfonds AG|Festgeld', re.I), 'Spenden': re.compile('Spende|Signal Foundation|nebenan.de|(paypal.*Sabine.Hossenf)|' 'Patreon|Umwelthilfe|Foerderer|Malteser|(Aktion Tier.*Mensch)|' - 'campact', re.I), + 'campact|Amnesty', re.I), } @@ -43,8 +46,10 @@ def get_category(item: str) -> str: return 'Sonstiges' -def parse_entry(line: str) -> Entry: - fields = [f.strip() for f in line.strip().split(';')] +def parse_entry(raw_fields: Iterable[str]) -> Entry: + fields = [f.strip() for f in raw_fields] + # format change in May 2024, adds a 9th field "Währung"; ignore + fields = fields[:8] # last field is the value, parse as float value = float(fields.pop().replace('.', '').replace(',', '.')) # match on who, IBAN, type, or desc @@ -62,9 +67,12 @@ def parse_csv(path: Path, date_filter: str) -> Iterable[Entry]: return filter_re.search(entry.date) with path.open() as f: + reader = csv.reader(f, delimiter=';') + next(reader) # skip header # first line is the column headers, chop it off - entries = map(parse_entry, f.readlines()[1:]) - return filter(filter_entry, entries) + entries = map(parse_entry, reader) + # do the actual iteration here, as the files get closed afterwards + return list(filter(filter_entry, entries)) def main():