#!/usr/bin/env python #This script will do all the preprocessing on the cvs file so that it is ready to be read in, #and can immediatly be copied in the books #authors: Koenraad, Sandb import os, re, string, sys, datetime, getopt class Transfer(object): def __init__(self, date, description, incoming, outgoing, transfernumber): self.date = date self.description = description self.incoming = incoming self.outgoing = outgoing self.transfernumber = transfernumber def __repr__(self): return "%02d-%02d-%04d;%s;;%s;%s;" % (self.date.day, self.date.month, self.date.year, self.description, self.incoming, self.outgoing) def __cmp__(self, other): diff = cmp(type(self), type(other)) if diff != 0: return diff diff = cmp(self.date, other.date) if diff != 0: return diff diff = cmp(self.transfernumber, other.transfernumber) if diff != 0: return diff diff = cmp(self.description, other.description) if diff != 0: return diff diff = cmp(self.incoming, other.incoming) if diff != 0: return diff diff = cmp(self.outgoing, other.outgoing) if diff != 0: return diff return 0 class Automat0r(object): CURRENCY = re.compile(r'(?P\d\d)-(?P\d\d)-(?P\d\d\d\d)') def __init__(self, directory, anonimizingfile): self.directory = directory self.anonimize = [] if anonimizingfile: self.readanonimizingfile(anonimizingfile) def readanonimizingfile(self, filename): f = open(filename, 'r') try: for l in f.readlines(): search, replace = l.split(';')[:2] self.anonimize.append({ "search": search, "replace": replace }) finally: f.close() def readfiles(self): reg_cvs = re.compile(".*\.csv$", re.IGNORECASE) filecontents= {} for filename in os.listdir(self.directory): filename = os.path.join(self.directory, filename) if not os.path.isfile(filename): continue if not reg_cvs.match(filename): continue filecontents[filename] = self.readfile(filename) return filecontents def readfile(self, filename): f = open(filename, 'r') result = [] try: for line in f.readlines(): parsed = self.parse(line) if not parsed: continue result.append(parsed) result.reverse() return result finally: f.close() def parse(self,line): parts = line.split(';') if (len(parts) != 10): return None parts = [part.strip() for part in parts] currencydate, transfernumber, description, amount, coinage, transactiondate, targetaccount, targetname, message1, message2, = parts currencydate = self.CURRENCY.match(currencydate) #if currency data does not match, it is a bad line, skip if not currencydate: return None day, month, year = currencydate.groups() currencydate = datetime.date(int(year), int(month), int(day)) date = currencydate descriptionparts = [] if len(targetname) > 0: descriptionparts.append(targetname.strip()) if len(message1) > 0: descriptionparts.append(message1.strip()) if len(message2) > 0: descriptionparts.append(message2.strip()) description = '-'.join(descriptionparts) for a in self.anonimize: rgx = re.compile(a["search"], re.IGNORECASE) description = rgx.sub(a["replace"], description) total = float(amount.replace('.','').replace(',','.')) incoming = "0.00" outgoing = "0.00" if total >= 0: incoming = "%.2f" % total else: outgoing = "%.2f" % -total return Transfer(date, description, incoming, outgoing, transfernumber) def merge(self, csvs): purged = {} for csvitem in csvs.iteritems(): if len(csvitem[1]) < 1: continue purged[csvitem[0]]=csvitem[1] def csvkey(csvitem): return csvitem[1][0].date csvsorted = sorted(purged.iteritems(), key=csvkey) combined = [] for csv in csvsorted: combined.extend(csv[1]) unique = [] for transfer in combined: if transfer in unique: continue unique.append(transfer) return unique def run(self): csvs = self.readfiles() merged = self.merge(csvs) for transfer in merged: print(transfer) def usage(): print """ automator.pr0n -d directory [-a anonimize] [-?] Join and anonimizes argenta csv files into whitespace compatible csv structure. -d, --directory directory The directory containing the argenta csv files -a --anonimize A csv file containing search and replace options for anonimizing the message -?, --help Shows this help. """ def main(): try: opts, a = getopt.getopt(sys.argv[1:], "d:a:?", ["directory=", "anonimize=", "help"]) except getopt.GetoptError, err: print str(err) usage() sys.exit(2) directory = None anonimizingfile = None for opt, arg in opts: if opt in ("-d", "--directory"): directory = arg elif opt in ("-a", "--anonimize"): anonimizingfile = arg elif opt in ("-?", "--help"): usage() sys.exit() else: assert False, "unhandled option" if not directory: print "Missing directory option" usage() sys.exit(1) automat0r = Automat0r(directory, anonimizingfile) automat0r.run() if __name__ == "__main__": main()