
| Current Path : /home/ift/52_procpy/fibu/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : //home/ift/52_procpy/fibu/sync.old |
# coding: utf8
import os,sys,re,glob,time,sqlite3,hashlib,time,base64,datetime
import procpy
import procpy.fibu
addpath = ".."
while len(addpath) < 30:
addpath
sys.path.append(addpath)
addpath = addpath + "/.."
import fibu
#******************************************************************************
class Sync (object):
def __init__ (self):
self.pythoncall = "python3"
try:
self.sortfkt = fibu.sortfkt
except:
self.sortfkt = None
try:
self.synchronized = fibu.synchronized
print("SYNCHRONIZED")
except:
self.synchronized = False
self.kontenrahmen = {}
try:
for kto in fibu.kontenrahmen.split("\n"):
m = re.search(r"^(.*?) +(.*?) *$",kto)
if m:
self.kontenrahmen[m.group(1)] = m.group(2)
except:
pass
def generate_db (self,database_file):
self.dbh = sqlite3.connect(database_file)
self.dbh.row_factory = sqlite3.Row
cursor = self.dbh.cursor()
self.pythoncall = "python3"
cursor.execute("create table if not exists buchungen " +
"(DATUM,BETRAG,KTOA,KTOB,REMARK,ID default '')")
try:
cursor.execute("create index DATUM_IDX on buchungen (DATUM)" )
cursor.execute("create index KTOA_IDX on buchungen (KTOA)" )
cursor.execute("create index KTOB_IDX on buchungen (KTOB)" )
self.database_empty = True
except Exception as e:
self.database_empty = False
def mark (self,remark=""):
t = time.clock()
if 't0' in vars(self):
print ( ("%9.2f" % ((t-self.t0)*1000)) + " ms for: " + remark )
self.t0 = t
def xxsync (self,ktodirs):
ktolist_new = []
ktolist_unchanged = [] # das wird die Liste mit allen Konto-Objekten
ktolist_changed = []
for dir in ktodirs: # Erste Runde: durch alle angegebenen Konto-Directories gehen
kto = procpy.fibu.kto.Kto() # jeweils ein Konto-Objekt daraus machen
kto.find_ukto_and_interval(dir) # aus dem Pfad die Konto-ID und das Gueltigkeitsintervall herauslesen
kto.rulenr = 0 # Anzahl der Runden, die das Konto durchlaeuft
kto.rule = glob.glob(dir+"/rule.py")
kto.dir = dir
ktofile = glob.glob(dir+"/*.kto") # jetzt den jeweiligen Kontotext einlesen
if len(ktofile) == 1: # es darf nur genau ein kto-File im Konto-Verzeichnis geben
ktotext = open(ktofile[0]).read()
# kto.read_template(ktotext)
kto.parse_ktotext(ktotext) # wenn das so ist, den Kontotext ins Konto-Objekt einlesen
elif len(ktofile) == 0:
continue
else: # im Fehlerfall mit einer Fehlermeldung Funktion beenden
return("ERROR: ktofile in " + dir + " is ambiguous")
kto.file0 = ktofile[0]
kto.file1 = self.sync_template( kto.file0,kto.kto_id(kto.dir))
if kto.file0 == kto.file1:
ktolist_unchanged.append(kto)
else:
if not re.search(r"\_\_([A-Za-z0-9]{8})\.kto$",kto.file0):
ktolist_new.append(kto)
else:
if len(kto.rule) == 1:
os.system(self.pythoncall + " " + kto.rule[0] + " " + str(kto.rulenr) )
kto.parse_ktotext( open(kto.file0).read() )
kto.file1 = self.sync_template( kto.file0, kto.kto_id(kto.dir))
kto.rulenr = 1
ktolist_changed.append(kto)
ktolist_unchanged.sort(key=lambda x: x.dir)
ktolist_unchanged.reverse()
# if len(ktolist_new) + len(ktolist_changed)== 0:
# return(0)
ktolist = ktolist_new + ktolist_unchanged + ktolist_changed # In dieser Liste sind jetzt alle Konton.
zaehler = " 1"
for kto in ktolist: # Zweite Runde: Erstmal alle Konten einlesen
print(zaehler + ". " + kto.ukto)
zaehler = "%2u" % (int(zaehler) + 1)
kto.delete_from_db(self.dbh) # Wenn schon was von dem Konto in der Datenbank gestanden war, die
# entsprechenden Buchungen loeschen
kto.import_to_db(self.dbh) # Dann den Konto-Objekt-Inhalt in die Datenbank schreiben
while (0 == 0): # diese Schleife so oft wiederholen, bis fuer alle Konten der Kontotext stabil bleibt
for kto in ktolist:
all_synced = True
kto.export_from_db(self.dbh) # Kontoinhalt aus der Datenbank auslesen
kto.write_ktotext(self.sortfkt) # kto.saldovortrag) # Kontotext erzeugen
open(kto.file0,"w").write(kto.ktotext)
kto.file1 = self.sync_template( kto.file0, kto.kto_id(kto.dir) )
if not kto.file1 == kto.file0:
o = " (" + kto.startdatum + "-" + kto.enddatum + ")"
if o == " (00000000-99999999)":
o = ""
print (" ....process " + kto.ukto + o)
os.rename(kto.file0,kto.file1)
kto.file0 = kto.file1
if len(kto.rule) == 1:
os.system("chdir " + kto.dir + "; cd " + kto.dir + "; " +
self.pythoncall + " " + kto.rule[0] + " " + str(kto.rulenr) )
kto.parse_ktotext( open(kto.file0).read() )
kto.delete_from_db(self.dbh)
kto.import_to_db(self.dbh)
kto.rulenr = kto.rulenr + 1
all_synced = False
if all_synced:
break
self.dbh.commit()
def xxsync_template (self,ktofile,ktohash):
newfile = ""
m = re.search(r"^(.*)\_\_([A-Za-z0-9]{8})\.kto$",ktofile)
if m:
newfile = m.group(1) + "__" + ktohash + ".kto"
else:
newfile = re.sub(r"\_*\.kto$","",ktofile) + "__" + ktohash + ".kto"
return(newfile)
def xxsync1 (self,ktodirs):
ktolist_new = []
ktolist_unchanged = [] # das wird die Liste mit allen Konto-Objekten
ktolist_changed = []
ktolist_stable = []
print("")
self.mark("")
self.mark("A. Start sync")
for dir in ktodirs: # Erste Runde: durch alle angegebenen Konto-Directories gehen
kto = procpy.fibu.kto.Kto() # jeweils ein Konto-Objekt daraus machen
kto.find_ukto_and_interval(dir) # aus dem Pfad die Konto-ID und das Gueltigkeitsintervall herauslesen
kto.rulenr = 0 # Anzahl der Runden, die das Konto durchlaeuft
kto.rule = glob.glob(dir+"/rule.py")
kto.dir = dir
kto.stable = False
if os.path.isfile(dir+"/STABLE"):
kto.stable = True
ktofile = glob.glob(dir+"/*.kto") # jetzt den jeweiligen Kontotext einlesen
print(ktofile)
if len(ktofile) == 1: # es darf hoechstens ein kto-File im Konto-Verzeichnis geben
kto.file = dir + "/" + kto.filename + ".kto"
ktotext = open(ktofile[0]).read()
if not ktofile[0] == kto.file:
os.rename(ktofile[0],kto.file)
elif len(ktofile) == 0:
kto.file = dir + "/" + kto.filename + ".kto"
open(kto.file,"w").write("\n")
ktotext = ""
else: # im Fehlerfall mit einer Fehlermeldung Funktion beenden
print( "ERROR: ktofile in " + dir + " is ambiguous")
return("ERROR: ktofile in " + dir + " is ambiguous")
kto.parse_ktotext(ktotext) # wenn das so ist, den Kontotext ins Konto-Objekt einlesen
kto.id0 = ""
kto.parent = ""
m = re.search(r"\n==== +(\d\d)-(\d\d)-(\d\d) +([A-Za-z0-9]{8}) +([A-Za-z0-9]{8})",
ktotext[max(0,len(ktotext)-500):],flags=re.DOTALL)
if m:
kto.maxa = int(m.group(1))
kto.maxb = int(m.group(2))
kto.maxc = int(m.group(3))
kto.id0 = m.group(4)
kto.parent = m.group(5)
kto.id1 = kto.kto_id(kto.dir)
if kto.stable:
ktolist_stable.append(kto)
elif kto.id1 == kto.id0:
ktolist_unchanged.append(kto)
else:
if kto.id0 == "":
ktolist_new.append(kto)
else:
if len(kto.rule) == 1:
os.system(self.pythoncall + " " + kto.rule[0] + " " + str(kto.rulenr) )
kto.parse_ktotext( open(kto.file).read() )
kto.id1 = kto.kto_id(kto.dir)
kto.rulenr = 1
ktolist_changed.append(kto)
ktolist_unchanged.sort(key=lambda x: x.dir)
ktolist_unchanged.reverse()
# if len(ktolist_new) + len(ktolist_changed)== 0:
# return(0)
ktolist = ["__NEW__"] + ktolist_new
ktolist = ktolist + ["__UNCHANGED__"] + ktolist_unchanged
ktolist = ktolist + ["__CHANGED__"] + ktolist_changed
ktolist = ktolist + ["__STABLE__"] + ktolist_stable # In dieser Liste sind jetzt alle Konton.
self.mark("B. Read Kto-Files")
zaehler = " 1"
for kto in ktolist: # Zweite Runde: Erstmal alle Konten einlesen
if type(kto) == type(""):
print(kto)
else:
print(zaehler + ". " + kto.ukto)
zaehler = "%2u" % (int(zaehler) + 1)
kto.delete_from_db(self.dbh) # Wenn schon was von dem Konto in der Datenbank gestanden war, die
# entsprechenden Buchungen loeschen
kto.import_to_db(self.dbh) # Dann den Konto-Objekt-Inhalt in die Datenbank schreiben
self.mark("C. Import into Database")
rounds = 0
while (0 == 0): # diese Schleife so oft wiederholen, bis fuer alle Konten der Kontotext stabil bleibt
rounds = rounds + 1
print("\n\n*****************************\nROUND: " + ("%2u" % rounds)+"\n---------\n\n")
all_synced = True
for kto in ktolist:
if type(kto) == type(""):
continue
kto.export_from_db(self.dbh) # Kontoinhalt aus der Datenbank auslesen
kto.write_ktotext(self.sortfkt) # kto.saldovortrag) # Kontotext erzeugen
open(kto.file,"w").write(kto.ktotext + "==== " + ("%02u" % int(kto.maxa)) + "-" +
("%02u" % int(kto.maxb)) + "-" + ("%02u" % int(kto.maxc))
+ " " + kto.id1 + " " + kto.id1 + "\n\n")
kto.id1 = kto.kto_id(kto.dir)
if not kto.id1 == kto.id0 or not kto.formatted:
print (kto.ukto)
o = " (" + kto.startdatum + "-" + kto.enddatum + ")"
if o == " (00000000-99999999)":
o = ""
# os.rename(kto.file0,kto.file1)
kto.id0 = kto.id1
if len(kto.rule) == 1:
m = re.search(r"^(.*)[\\\/](.*)$","/"+kto.rule[0])
if m:
rule1 = m.group(2)
os.system("chdir " + kto.dir + "; cd " + kto.dir + "; " +
self.pythoncall + " " + rule1 + " " + str(kto.rulenr) )
kto.parse_ktotext( open(kto.file).read() )
kto.delete_from_db(self.dbh)
kto.import_to_db(self.dbh)
kto.rulenr = kto.rulenr + 1
all_synced = False
self.mark("D. Round " + str(rounds))
if all_synced:
break
self.dbh.commit()
#**********************************************************************************************
def sync3 (self,ktodirs0):
bezeichner = {}
print("")
self.mark("")
self.mark("A. Start sync")
ktodirs = []
for ktodir in ktodirs0:
if "EXCLUDE" in ktodir:
continue
ktodirs.append(re.sub(r"([^\\\/])$","\\1/",ktodir))
main_dir = self.common_string(ktodirs) # das tiefste uebergeordnete Directory ermitteln
db_dir = re.sub(r"^(.*)[\\\/].*?$","\\1",main_dir) # das erste gemeinsam erreichbare Datenbankfile ermitteln
while (0 == 0):
db_file = glob.glob(db_dir+"/*.db")
print(db_dir,db_file,len(db_file))
if len(db_file) == 1:
break
if len(db_file) > 1:
fehler = "ERROR: dbfile in " + db_dir + " is ambiguous"
print(fehler)
return(fehler)
if os.path.isfile(db_dir + "/fibu.py"): # oberstes Directory erreicht
db_file = None # kein Datenbankfile
break
db_dir = os.path.abspath(db_dir+"/..")
self.generated_in = None
if not db_file:
print(" ... no database found, so create it here ...")
db_file = [main_dir+"/__cache__.db"]
self.generated_in = main_dir
if main_dir in ktodirs:
ktodirs.remove(main_dir)
ktodirs.insert(0,main_dir)
self.generate_db(db_file[0])
self.mark("B. DB-File " + db_file[0])
ktolist = []
for dir in ktodirs: # jetzt die Kontoobjekte erzeugen
if not os.path.isdir(dir):
continue
print(dir)
kto = procpy.fibu.kto.Kto() # jeweils ein Konto-Objekt daraus machen
kto.find_ukto_and_interval(dir) # aus dem Pfad die Konto-ID und das Gueltigkeitsintervall herauslesen
kto.rulenr = 0 # Anzahl der Runden, die das Konto durchlaeuft
kto.rule = glob.glob(dir+"/rule.py")
kto.dir = dir
ktolist.append(kto)
if self.generated_in == main_dir:
self.generated_in = kto
self.mark("C. Generate Kto objects")
for kto in ktolist:
ktofile = glob.glob(kto.dir+"/*.kto") # jetzt den jeweiligen Kontotext einlesen
if len(ktofile) == 1: # es darf hoechstens ein kto-File im Konto-Verzeichnis geben
kto.file = kto.dir + "/" + kto.filename + ".kto"
try:
ktotext = open(ktofile[0]).read()
except:
print(ktofile[0] + " could not being opened.")
if not ktofile[0] == kto.file:
os.rename(ktofile[0],kto.file)
elif len(ktofile) == 0:
kto.file = kto.dir + "/" + kto.filename + ".kto"
if not os.path.isdir(kto.dir):
os.mkdir(kto.dir)
open(kto.file,"w").write("NEWKTO\n")
ktotext = "NEWKTO\n"
else: # im Fehlerfall mit einer Fehlermeldung Funktion beenden
fehler = "ERROR: ktofile in " + kto.dir + " is ambiguous"
print(fehler)
return(fehler)
kto.parse_ktotext(ktotext,bezeichner) # wenn das so ist, den Kontotext ins Konto-Objekt einlesen
self.mark(" > " + os.path.relpath(kto.file,"."))
self.mark("D. Parse kto files")
if self.generated_in:
self.generated_in.import_to_db(self.dbh)
self.generated_in.db0 = "xxxxxx"
for kto in ktolist:
kto.id_new = kto.kto_id(kto.dir)
m = re.search(r"^[^\n]+\(([A-Za-z0-9\_\+\-]{6})([A-Za-z0-9\_\+\-]{6})\)",kto.ktotext)
if m:
kto.id = m.group(1) # der abgespeicherte Kto-Hash
kto.db = m.group(2) # der Kto-Hash des Parents
if kto == self.generated_in:
kto.db0 = kto.db
continue
if kto.ktotext[0:6] == "NEWKTO":
kto.id = kto.id_new
kto.db = "yyyyyy"
continue
kto.id = "xxxxxx"
buchungen = kto.export_from_db(self.dbh) # Kontoinhalt aus der Datenbank auslesen
kto.buchungen = buchungen
kto.db = kto.db_id(buchungen)
# print("A",m,kto.ukto,kto.id,kto.db,"---",kto.id_new)
self.mark("E. Evaluate kto hashes")
fehlerliste = []
rounds = 0
while (0 == 0):
rounds = rounds + 1
print("\n\n*****************************\nROUND: " + ("%2u" % rounds) + "\n---------\n\n")
all_synced = True
for kto in ktolist:
if kto in fehlerliste:
continue
# print(kto.ukto,kto.rule)
buchungen = kto.export_from_db(self.dbh)
# print(buchungen)
kto.db_new = kto.db_id(buchungen)
print(kto.ukto,"---",kto.id,kto.db,"---",kto.id_new,kto.db_new)
if kto.db_new == kto.db and kto.id_new == kto.id:
continue
elif not kto.db_new == kto.db and kto.id_new == kto.id: # or self.synchronized:
print(" ... write " + kto.ukto)
kto.buchungen = buchungen
saldo = kto.write_ktotext(bezeichner,self.sortfkt) # Kontotext erzeugen
# print(kto.ukto,"KTOTEXT:",kto.ktotext)
kto.db = kto.db_new
kto.id = kto.kto_id(kto.dir)
open(kto.file,"w").write(
("%-40s" % kto.filename) + "(" + kto.id + kto.db_new + ")" +
# " Saldo: " +
("%15.2f" % saldo) +
"\n\n" + kto.ktotext )
if os.path.isfile(kto.filename+".csv"):
open(kto.filename+".csv","w").write(kto.write_csv(kto.filename))
if len(kto.rule) == 1:
m = re.search(r"^(.*)[\\\/](.*)$","/"+kto.rule[0])
if m:
rule1 = m.group(2)
print(" ... run rule " + str(kto.rulenr) +" for " + kto.ukto)
os.system("chdir " + kto.dir + "; cd " + kto.dir + "; " +
self.pythoncall + " " + rule1 + " " + str(kto.rulenr) )
kto.rulenr = kto.rulenr + 1
kto.parse_ktotext( open(kto.file).read(), bezeichner )
kto.id_new = kto.kto_id(kto.dir)
all_synced = False
if not kto.id_new == kto.id: # gleich kto neu schreiben
kto.delete_from_db(self.dbh)
kto.import_to_db(self.dbh)
kto.db = "yyyyyy" #
kto.id = kto.id_new #
elif kto.db_new == kto.db and not kto.id_new == kto.id or self.synchronized:
print(" ... update " + kto.ukto)
kto.delete_from_db(self.dbh)
kto.parse_ktotext( open(kto.file).read(), bezeichner )
kto.import_to_db(self.dbh)
self.dbh.commit()
kto.db = "yyyyyy"
kto.id = kto.id_new
all_synced = False
elif not kto.db_new == kto.db and not kto.id_new == kto.id:
fehler = "ERROR: Conflict in " + kto.dir
print(fehler)
fehlerliste.append(kto)
self.dbh.commit()
self.mark("F"+str(rounds)+". Round " + str(rounds) + " finished.")
if all_synced:
print(" ... all accounts synced")
break
self.dbh.commit()
self.mark("G. All accounts synced. DB Commit")
print("")
if False and self.generated_in:
text = open(self.generated_in.file).read().split("\n")
m = re.search(r"^(.*\()([A-Za-z0-9\_\+\-]{6})([A-Za-z0-9\_\+\-]{6})(\).*)$",text[0])
if m:
# text[0] = m.group(1) + m.group(2) + self.generated_in.db0 + m.group(4)
text[0] = m.group(1) + "xxxxxx" + m.group(3) + m.group(4)
open(self.generated_in.file,"w").write("\n".join(text))
return(fehlerliste)
def common_string (self,elements):
main_el = elements[0]
for el in elements: # jetzt das tiefste uebergeordnete Directory ermitteln
main_el = main_el[0:len(el)]
el1 = el[0:len(main_el)]
while (0 == 0):
if el1 == main_el:
break
el1 = el1[:-1]
main_el = main_el[:-1]
return(main_el)
def sort (self,pattern,file):
if pattern == "..":
self.sort_numbers(file)
return()
text = open(file).read()
text_match = []
text_rest = []
for zeile in text.split("\n"):
if re.search(pattern,zeile,re.IGNORECASE):
text_match.append(zeile)
else:
text_rest.append(zeile)
text = "\n".join(text_rest) + "\n" + "\n".join(text_match) + "\n"
if os.path.isfile(file+"~"):
os.unlink(file+"~")
# os.rename(file,file+"~")
open(file,"w").write(text)
def sort_numbers (self,file):
text = open(file).read()
text_match = []
text_rest = []
for zeile in text.split("\n"):
m = re.search(r"\d\d\d\d\d\d\d\d +\-?(\d+\.\d\d) ",zeile)
if m:
text_match.append([zeile,float(m.group(1))])
else:
text_rest.append(zeile)
text_match.sort(key=lambda x:x[1])
text_match1 = []
for tt in text_match:
text_match1.append(tt[0])
text = "\n".join(text_rest) + "\n" + "\n".join(text_match1) + "\n"
if os.path.isfile(file+"~"):
os.unlink(file+"~")
# os.rename(file,file+"~")
open(file,"w").write(text)
#*************************************************************************************
def find_quittung (self,daydiff,file,pattern=""):
buchungen = []
text = []
text1 = []
ktotext = open(file).read()
for zeile in ktotext.split("\n"):
m = re.search(r"^(\d\d\d\d\d\d\d\d) +(\-?\d+\.\d\d) +(\S+) +(\S+) +(\-?\d+\.\d\d) +(.*)",zeile)
if not m:
text.append(zeile)
continue
else:
datum = m.group(1)
betrag = m.group(2)
ktoa = m.group(3)
ktob = m.group(4)
remark = m.group(6)
buchungen.append([0,datum,betrag,ktoa,ktob,remark,zeile])
day0 = datetime.datetime.strptime("19700101","%Y%m%d")
try:
day = datetime.datetime.strptime(datum,"%Y%m%d")
except:
day = datetime.datetime.strptime(datum[0:6]+"28","%Y%m%d")
buchungen[-1][0] = (day-day0).days
while (0 == 0):
if buchungen[-1][0] - buchungen[0][0] < int(daydiff):
break
text.append(buchungen.pop(0)[-1])
'''
if abs(float(buchung[2])) == abs(float(buchungen[-1][2])):
buchung1 = buchung
buchung2 = buchungen[-1]
common_kto1 = ""
common_kto2 = ""
m1 = re.search("("+pattern+")",buchung1[-1])
if m1:
common_kto1 = m1.group(1)
m2 = re.search("("+pattern+")",buchung2[-1])
if m2:
common_kto2 = m2.group(1)
print(common_kto1,common_kto2)
print(buchung1[-1])
print(buchung2[-1])
if not common_kto1 == common_kto2: # matching!
text1.append("")
if pattern in buchung2[-1]:
buchung0 = buchung1
buchung1 = buchung2
buchung2 = buchung0
betrag1 = buchung1[2]
ktoa1 = buchung1[3]
ktob1 = buchung1[4]
if not betrag1[0] == "-":
betrag1 = "-" + betrag1
ktox = ktoa1
ktoa1 = ktob1
ktob1 = ktox
betrag2 = buchung1[2]
ktoa2 = buchung1[3]
ktob2 = buchung1[4]
if not betrag2[0] == "-":
betrag2 = "-" + betrag2
ktox = ktoa2
ktoa2 = ktob2
ktob2 = ktox
if ktob1 == standard_kto:
ktob1 = ktob2
if ktob2 == standard_kto:
ktob2 = ktob1
ktob2 = ktoa1
zeile1 = buchung1[1] + " " + betrag1 + " " + ktoa1 + " " + ktob1 + " 0.00 " + buchung1[5]
zeile2 = buchung2[1] + " " + betrag2 + " " + ktoa2 + " " + ktob2 + " 0.00 " + buchung2[5]
text1.append(zeile1)
text1.append(zeile2)
'''
standard_kto = "-13-9999"
for buchung in buchungen[:-1]:
if abs(float(buchung[2])) == abs(float(buchungen[-1][2])):
buchung1 = buchung
buchung2 = buchungen[-1]
common_kto1 = ""
common_kto2 = ""
m1 = re.search("("+pattern+")",buchung1[-1])
if m1:
common_kto1 = m.group(1)
m2 = re.search("("+pattern+")",buchung2[-1])
if m2:
common_kto2 = m.group(1)
if not common_kto1 == common_kto2:
text1.append("")
if pattern in buchung2[-1]:
buchung0 = buchung1
buchung1 = buchung2
buchung2 = buchung0
betrag1 = buchung1[2]
ktoa1 = buchung1[3]
ktob1 = buchung1[4]
if not betrag1[0] == "-":
betrag1 = "-" + betrag1
ktox = ktoa1
ktoa1 = ktob1
ktob1 = ktox
betrag2 = buchung2[2]
ktoa2 = buchung2[3]
ktob2 = buchung2[4]
if not betrag2[0] == "-":
betrag2 = "-" + betrag2
ktox = ktoa2
ktoa2 = ktob2
ktob2 = ktox
if ktob1 == standard_kto:
ktob1 = ktob2
if ktob2 == standard_kto:
ktob2 = ktob1
ktob2 = re.sub("QUIT","ZAHL",ktoa1)
zeile1 = buchung1[1] + " " + betrag1 + " " + ktoa1 + " " + ktob1 + " 0.00 " + buchung1[5]
zeile2 = buchung2[1] + " " + betrag2 + " " + ktoa2 + " " + ktob2 + " 0.00 " + buchung2[5]
if ktoa1 == ktob1 or ktoa2 == ktob2:
text1.append(buchung1[-1])
text1.append(buchung2[-1])
else:
text1.append("# " + buchung1[-1])
text1.append("# " + buchung2[-1])
text1.append(zeile1)
text1.append(zeile2)
else:
text.append(buchung1[-1])
text.append(buchung2[-1])
buchungen.pop()
buchungen.remove(buchung)
break
for buchung in buchungen:
text.append(buchung[-1])
ktotext = "\n".join(text) + "\n" + "\n".join(text1) + "\n"
open(file,"w").write(ktotext)
#####################################################################################
def xxsync10 (self,ktodirs):
ktolist = [] # das wird die Liste mit allen Konto-Objekten
number_of_rounds = 0
for dir in ktodirs: # Erste Runde: durch alle angegebenen Konto-Directories gehen
kto = procpy.fibu.kto.Kto() # jeweils ein Konto-Objekt daraus machen
kto.find_ukto_and_interval(dir) # aus dem Pfad die Konto-ID und das Gueltigkeitsintervall herauslesen
ktorule = glob.glob(dir+"/rule.py")
print ("RULE",ktorule,dir)
if ktorule:
os.system(self.pythoncall + " " + ktorule[0] + " " + str(number_of_rounds) )
ktofile = glob.glob(dir+"/*.kto") # jetzt den jeweiligen Kontotext einlesen
if len(ktofile) == 1: # es darf nur genau ein kto-File im Konto-Verzeichnis geben
ktotext = open(ktofile[0]).read()
kto.parse_ktotext(ktotext) # wenn das so ist, den Kontotext ins Konto-Objekt einlesen
elif len(ktofile) == 0:
continue
else: # im Fehlerfall mit einer Fehlermeldung Funktion beenden
return("ERROR: ktofile in + " + dir + " is ambiguous")
kto.file = ktofile[0]
kto.dir = dir
open("_"+kto.file,"w").write(ktotext)
kto.delete_from_db(self.dbh) # Wenn schon was von dem Konto in der Datenbank gestanden war, die
# entsprechenden Buchungen loeschen
kto.import_to_db(self.dbh) # Dann den Konto-Objekt-Inhalt in die Datenbank schreiben
ktolist.append(kto) # Das Konto an die Liste mit den Konto-Objekten anfuegen
number_of_synced_ktos = 0 # Zaehler fuer die Anzahl der schon synchronisierten Konten
actual_konto = 0 # Nummer des aktuellen Kontos in der ktolist
while (0 == 0): # diese Schleife so oft wiederholen, bis fuer alle Konten der Kontotext stabil bleibt
if number_of_synced_ktos == len(ktolist): # alle Konten sind synchronisiert, Schleife beenden
break
if actual_konto == 0:
number_of_rounds = number_of_rounds + 1
print ("ROUND " + str(number_of_rounds))
kto = ktolist[actual_konto]
actual_konto = (actual_konto+1) % len(ktolist)
kto.ktotext0 = kto.ktotext
kto.export_from_db(self.dbh) # Kontoinhalt aus der Datenbank auslesen
kto.write_ktotext(self.sortfkt) # kto.saldovortrag) # Kontotext erzeugen
if kto.ktotext0 == kto.ktotext:
number_of_synced_ktos = number_of_synced_ktos + 1
continue
number_of_synced_ktos = 0
print (" ....process " + kto.ukto)
kto.delete_from_db(self.dbh)
kto.import_to_db(self.dbh)
open(kto.file,"w").write(kto.ktotext)
for kto in ktolist:
open(kto.file,"w").write(kto.ktotext)
def zzsync11 (self,depth=1):
search_string = "*.kto"
ktofiles = []
konten = []
while depth > -1:
ktofiles = ktofiles + glob.glob(search_string)
depth = depth - 1
ktodirs = {}
for ktofile in ktofiles:
m = re.search(r"(.*)[\\\/](.*)$",ktofile)
ktodir = m.group(1)
if m:
if ktodir in ktodirs:
print ("ERROR in " + m.group(1) + ": Double kto-files")
return()
else:
print ("ERROR, unidentified, in file " + ktofile)
return()
ktodirs[ktodir] = 1
kto = procpy.fibu.kto.Kto()
kto.dir = ktodir
kto.rulenr = 0
kto.rule = glob.glob(ktodir+"/rule.py")
kto.find_ukto_and_interval(ktodir)
for commit in self.repo.iter_commits(paths=ktodir):
kto.last_changed = commit.committed_date
break
return()
ktolist_unchanged = [] # das wird die Liste mit allen Konto-Objekten
ktolist_changed = []
for dir in ktodirs: # Erste Runde: durch alle angegebenen Konto-Directories gehen
kto = procpy.fibu.kto.Kto() # jeweils ein Konto-Objekt daraus machen
kto.find_ukto_and_interval(dir) # aus dem Pfad die Konto-ID und das Gueltigkeitsintervall herauslesen
kto.rulenr = 0 # Anzahl der Runden, die das Konto durchlaeuft
kto.rule = glob.glob(dir+"/rule.py")
ktofile = glob.glob(dir+"/*.kto") # jetzt den jeweiligen Kontotext einlesen
if len(ktofile) == 1: # es darf nur genau ein kto-File im Konto-Verzeichnis geben
ktotext = open(ktofile[0]).read()
kto.parse_ktotext(ktotext) # wenn das so ist, den Kontotext ins Konto-Objekt einlesen
elif len(ktofile) == 0:
continue
else: # im Fehlerfall mit einer Fehlermeldung Funktion beenden
return("ERROR: ktofile in + " + dir + " is ambiguous")
kto.dir = dir
kto.file = ktofile[0]
kto.last_changed = 0
for commit in self.repo.iter_commits(paths=kto.file):
kto.last_changed = int(self.git.committed_date)
if len(kto.rule) == 1:
os.system(self.pythoncall + " " + kto.rule[0] + " " + str(kto.rulenr) )
kto.parse_ktotext( open(kto.file0).read() )
kto.file1 = self.sync_template( kto.file0, kto.kto_id(kto.dir))
kto.rulenr = 1
ktolist_changed.append(kto)
if len(ktolist_changed) == 0:
return(0)
ktolist = ktolist_unchanged + ktolist_changed # In dieser Liste sind jetzt alle Konton.
# Als erstes die ungeaenderten, dann die geaenderten
for kto in ktolist: # Zweite Runde: Erstmal alle Konten einlesen
kto.delete_from_db(self.dbh) # Wenn schon was von dem Konto in der Datenbank gestanden war, die
# entsprechenden Buchungen loeschen
kto.import_to_db(self.dbh) # Dann den Konto-Objekt-Inhalt in die Datenbank schreiben
while (0 == 0): # diese Schleife so oft wiederholen, bis fuer alle Konten der Kontotext stabil bleibt
for kto in ktolist:
all_synced = True
kto.export_from_db(self.dbh) # Kontoinhalt aus der Datenbank auslesen
kto.write_ktotext(self.sortfkt) # kto.saldovortrag) # Kontotext erzeugen
kto.file1 = self.sync_template( kto.file0, kto.kto_id(kto.dir) )
if not kto.file1 == kto.file0:
print (" ....process " + kto.ukto)
kto.delete_from_db(self.dbh)
kto.import_to_db(self.dbh)
open(kto.file1,"w").write(kto.ktotext)
os.unlink(kto.file0)
kto.file0 = kto.file1
if len(kto.rule) == 1:
os.system(self.pythoncall + " " + kto.rule[0] + " " + str(kto.rulenr) )
kto.parse_ktotext( open(kto.file0).read() )
kto.file1 = self.sync_template( kto.file0, kto.kto_id(kto.dir) )
kto.rulenr = kto.rulenr + 1
all_synced = False
if all_synced:
break