Welcome To Our Shell

Mister Spy & Souheyl Bypass Shell

Current Path : /var/www/web-klick.de/dsh/21_finance/39/

Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
Upload File :
Current File : /var/www/web-klick.de/dsh/21_finance/39/konto.py~

#  coding:  utf
import os,sys,re,glob,time,base64,hashlib,random

#******************************************************************************

t0 = 0

#******************************************************************************

def mark (remark=""):
    
    global t0
    t = time.perf_counter()
    if t0 > 0:
        print ( ("%9.2f" % ((t-t0)*1000)) + " ms for:  " + remark )
    t0 = t

#******************************************************************************

def add (sortieren=0,file="result"):

#   Diese Funktion teilt die Buchungssaetze in einer Transaktionsdatei auf die
#   einzelnen Teildateien auf

    if not os.path.isfile(file+".orig"):
        print("No result file.")
        return()

    mark("A. Close transaction.")

    diff_salden = {}
    if os.path.isfile(file+".format") and os.path.isfile(file+".kto"):
        os.system("diff " + file + ".format " + file + ".kto > " + file + ".diff")
        mark("B. Difference computed.")
        apply_patch(file+".orig",file+".diff",1)
        
    (startdate,enddate) = sort_transaction(file+".orig")
    
    list_of_files = glob.glob("*.acc")
    for ktofile in list_of_files:

        salden_file = re.sub(r"\.acc$",".sum",ktofile)

        m = re.search(r"^(\d+)\.acc",ktofile)
        if not m:
            continue

        zeitraum = m.group(1)
        if os.path.isfile(salden_file):
            if zeitraum < startdate[0:len(zeitraum)]:
                continue
            if zeitraum > enddate[0:len(zeitraum)]:
                continue

        os.system("grep ^" + m.group(1) + " " + file + ".orig >> " + ktofile)
        if sortieren == 1:
            os.system("sort " + ktofile + " > " + "__" + ktofile)
            os.system("mv __" + ktofile + " " + ktofile)
            
        diff_salden = {}
        init_salden = ""
        if not os.path.isfile(salden_file):
            open(salden_file,"w").write("")
            init_salden = open(ktofile).read()

        for diff_buchung in ( init_salden + 
                   os.popen("grep '^> " + m.group(1) + "' " + file + ".orig >> " + ktofile).read() +
                   os.popen("grep '^< " + m.group(1) + "' " + file + ".orig >> " + ktofile).read() ).split("\n"):
            m = re.search("^([\<\>] +|)(\d\d\d\d\d\d\d\d) +(\-?\d+\.\d\d) +(\S+) +(\S+) +(\-?\d+\.\d\d)",diff_buchung)
#            print("DD",diff_buchung)
            if m:
                datum  = m.group(2)
                betrag = float(m.group(3))
                ktoa   = m.group(4)
                ktob   = m.group(5)
                if m.group(1).startswith(">"):
                    betrag = -betrag
                compute_salden(diff_salden,ktoa, betrag,datum) 
                compute_salden(diff_salden,ktob,-betrag,datum)

        salden_text = open(salden_file).read()   #  update der salden_files
#        print("-----")
        for kto in list(diff_salden.keys()):

#            print("DDZ",kto)
            m = re.search("^"+kto+" +(.*?) +(.*)",salden_text)
            if m:   #   wenn es schon eine Konto-Zeile im Salden-File gibt, diese integrieren
                monat    = int(m.group(1))
                betrag0  = 0.00
                for betrag in m.group(2).split(","):
                    print(betrag)
                    if not monat in diff_salden:
                        diff_salden[kto][monat] = 0.00
                    diff_salden[kto][monat] = diff_salden[kto][monat] + float(betrag) - betrag0
                    betrag0 = betrag
                    monat   = monat + 1
                    if str(monat)[4:6] == "12":
                        monat = int(str(int(str(monat)[0:4]) + 1) + "01")
                re.sub("^"+kto+" ","  ",salden_text)
                        
            monate   = list(diff_salden[kto].keys())
            monat    = min(monate)
            mmax     = max(monate)
            zeile    = kto + " " + str(monat) + " "
            betraege = []
            sum      = 0.00
            while (0 == 0):
                if monat in diff_salden[kto]:
                    sum = sum + diff_salden[kto][monat]
                betraege.append("%3.2f"%sum)
                monat   = monat + 1
                if str(monat)[4:6] == "12":
                    monat = int(str(int(str(monat)[0:4]) + 1) + "01")
                if monat > mmax:
                    break
            while (0 == 0):
                if len(betraege) < 2:
                    break
                if not betraege[-1] == betraege[-2]:
                    break
                betraege.pop()
            zeile = zeile + ",".join(betraege)
            salden_text = salden_text + zeile + "\n"
            
        mark("B. Update Salden " + ktofile + ".")
 
        open(salden_file,"w").write(salden_text)   #  update der salden_files
        os.system("grep -v '^ ' " + salden_file + " > " + "__" + salden_file)
        os.system("sort __" + salden_file + " > " + salden_file)
        os.system("rm __" + salden_file)

    os.system("mv " + file + ".orig " + file + ".old")
    mark("C. ... closed.")

#******************************************************************************

def compute_salden (salden,ukto,betrag,datum):

    monat = int(datum[0:6])
    while (0 == 0):
#        print(ukto)
        if not ukto in salden:
            salden[ukto] = {}
        if not monat in salden[ukto]:
            salden[ukto][monat] = 0.00
        salden[ukto][monat] = salden[ukto][monat] + betrag
        m = re.search(r"^(.*)\-(.+)$",ukto)
        if m:
            ukto = m.group(1)
        else:
            return()

#******************************************************************************

def sort_transaction (file):

    os.system("sort " + file + " > " + "__" + file)
    os.system("mv __" + file + " " + file)
    startdate = os.popen("head -n 1 " + file).read()[0:8]
    enddate   = os.popen("tail -n 1 " + file).read()[0:8]
    if not re.search(r"^\d\d\d\d\d\d\d\d$",startdate):
        startdate = "00000000"
    if not re.search(r"^\d\d\d\d\d\d\d\d$",enddate):
        enddate = "99999999"

    return(startdate,enddate)
    
#******************************************************************************

def split (pattern="",interval=None,file="result"):

    mark("")
    pattern1 = re.sub(r"\^"," ",pattern,9999)
    (pattern1,interval,egrep) = parse_pattern(pattern1)

    if os.path.isfile(file+".orig"):
        add()
        return()

    mark("A. Generate transaction file for " + pattern1 + " " + str(interval))
    if interval:
        if pattern1 == "":
            os.system(egrep + "grep -h -i ^" + interval + " *.acc > " + file + ".orig")
        else:
            os.system(egrep + "grep -h -i ^" + interval + " *.acc | grep -h -i '" + pattern1 + "' > " + file + ".orig")
    else:
        if pattern1 == "":
            os.system("less *.acc > " + file + ".orig")
        else:
            os.system(egrep + "grep -h -i '" + pattern1 + "' *.acc > " + file + ".orig")
            
    (startdate,enddate) = sort_transaction(file + ".orig")
    
    list_of_files = glob.glob("*.acc")
    for ktofile in list_of_files:

        m = re.search(r"^(\d+)\.acc",ktofile)
        if not m:
            continue
        zeitraum = m.group(1)
        if zeitraum < startdate[0:len(zeitraum)]:
            continue
        if zeitraum > enddate[0:len(zeitraum)]:
            continue

        if interval:
            if pattern1 == "":
                os.system(egrep + "grep -i -v ^" + interval + " " + ktofile + " > __" + ktofile)
            else:
                os.system(egrep + "grep -i -v ^" + interval + " " + ktofile + " > __" + ktofile)
                os.system(egrep + "grep -i ^" + interval + " " + ktofile + " | grep -i -v '" + pattern1 + "' >> __" + ktofile)
        else:
            if pattern1 == "":
                os.system(" > __" + ktofile)
            else:
                os.system(egrep + "grep -i -v '" + pattern1 + "' " + ktofile + " > __" + ktofile)
                
        os.system("mv __" + ktofile + " " + ktofile)

    mark("B. ... generated.")
    format_kto(pattern1)
    mark("C. ... formatted.")

            
#******************************************************************************

def parse_pattern (pattern=""):    #   parse the pattern

    interval = None
    egrep    = ""
    m        = re.search(r"^(.*)([\.\:])(.*)$",pattern)
        
    if m:

        pattern       = m.group(1)
        mode          = m.group(2)
        interval      = "20" + m.group(3)[0:2]
        months        = m.group(3)[2:]
        
        if   months == "A":
            months = "10"
        elif months == "B":
            months = "11"
        elif months == "C":
            months = "12"
        elif months == "I":
            months = "0[123]"
        elif months == "J":
            months = "0[456]"
        elif months == "K":
            months = "0[789]"
        elif months == "L":
            months = "1[012]"
        elif months == "M":
            months = "0[123456]"
        elif months == "N":
            months = "[01][789012]"
        elif months == "P":
            months = ""
        elif not months == "":
            months = "0" + months
    
        if mode == ":":
            intervals = []
            jahr      = "2000"
            while (0 == 0):
                intervals.append(jahr)
                jahr = str(int(jahr)+1)
                if jahr == interval:
                    break
            month = "01"
            while (0 == 0):
                intervals.append(jahr+month)
                if month in (months,"12"):
                    break
                month = "%02u" % (int(month) + 1)
            interval = "\\(" + "\\|".join(intervals) + "\\)"
            egrep    = "e"
        else:
            interval = interval + months

    return(pattern,interval,egrep)            
            
#******************************************************************************

def format_kto (pattern,file="result"):

    try:
        text = open(file+".orig").read()
    except:
        return()

    result = parse_ktotext(text.split("\n"),pattern)
    if not result:
        return(None)
            
    (ktotext,format_maxa,format_maxb,maxsaldo,ukto) = result
            
    print("UKTO: " + ukto)
    if ukto == "":
        ktotext.sort(key=lambda x:x[0]+str(x[1])+x[3]+x[4])
    else:
        ktotext.sort(key=lambda x:str(x[5]+1)+x[0])

    text_match   = []
    result_match  = []
    gesamt       = 0.00

    for zeile in ktotext:
            
        betrag = float(zeile[1])
        if ukto == "" or zeile[5] == 0:
            saldo = "         ...."
        elif maxsaldo == 0 or zeile[5] == 1:
            gesamt = gesamt + betrag
            saldo  = "%13.2f" % gesamt
        elif zeile[5] == 2:
            saldo = "         0.00"
        ust = ""
        if "v.H." in zeile[4]:
            ust = "   "

        ktoa   = zeile[2]
        ktob   = zeile[3]
        zeile1 = ( zeile[0] + " " + ("%13.2f" % betrag) + "  " + (format_maxa % ktoa) + "  " +
                   (format_maxb % ktob) + " " + saldo + "  " + ust + re.sub(r" +"," ",zeile[4],9999) )
        text_match.append(zeile1)
        result_match.append(zeile[6])

    text_match  = "UKTO: " + ukto + "\n" + "\n".join(text_match) + "\n"
    result_match = "\n".join(result_match) + "\n"
    
    open(file+".format","w").write(text_match)
    open(file+".kto","w").write(text_match)

#******************************************************************************

def parse_ktotext (ktotext,pattern):

    buchungen      = []
    unique_strings = {}
    pattern        = pattern.strip().upper()
    if len(pattern) > 0 and pattern[-1] == "-":
        pattern = pattern[:-1]
    maxa           = 10
    maxb           = 10
    maxc           = 0
    maxd           = 0
    maxsaldo       = 0

    ukto  = ""
    ukto0 = ""
    if pattern == "":
        ukto = None
        
    zaehler = -1
    vvv = re.compile(r"^(\d\d\d\d)(..)(\d\d) +(\S+) +(\S+) +(\S+) +(\-?\d+\.\d\d|\-+|\.+) +(.*?) *$")
    for zeile in ktotext:

        mm = vvv.search(zeile)
        if not mm:   #   Einlesen der Kontobezeichnungen
#                buchungen.append(["00000000",zeile,"","","",-1])
            continue

        if mm.group(2) == "MM":
            monate = ["01","02","03","04","05","06","07","08","09","10","11","12"]
        else:
            monate = [mm.group(2)]

        for monat in monate:

            datum  = mm.group(1) + monat + mm.group(3)
            try:
                betrag = "%3.2f" % eval(mm.group(4))
            except:
                print(mm.group(4))
                exit()

            remark   = mm.group(8)
            uniqu    = []
            ktoa     = "^" + mm.group(5)
            ktob     = "^" + mm.group(6)

#                ktoa = self.parse_ktotext_compute_kto(m.group(5),self.ukto,uniqu)
#                ktob = self.parse_ktotext_compute_kto(m.group(6),self.ukto,uniqu)

            if ktoa > ktob:
                o      = ktoa    #  um Eindeutigkeit zu schaffen. Sonst kann es durch
                ktoa   = ktob    #  Hin- und Herschwingen zu Endlos-Loops kommen
                ktob   = o
                betrag = re.sub(r"^--","","-"+betrag)

            if not ktoa[1] == "-" and not pattern in ktoa.upper() and pattern in ktob.upper():
                o      = ktoa    #  um das gefundene Konto an den Anfang zu stellen
                ktoa   = ktob
                ktob   = o
                betrag = re.sub(r"^--","","-"+betrag)

            saldo = 0
            if not ukto == None:
                
                if ukto == "":
                    if pattern in ktoa.upper() and not ktoa[1] == "-":
                        ukto = ktoa
                for kto in (ktoa,ktob):
                    if pattern in kto.upper() and not kto[1] == "-":
                        while (0 == 0):
                            if kto.startswith(ukto):
                                break
                            m = re.search(r"^(.*)\-(.*)$",ukto)
                            if m:
                                ukto = m.group(1)
                            else:
                                ukto = ""
                            print("           fit ukto: " + ukto.replace("^",""))
                        if not pattern in ukto.upper():
                            ukto = None
                            print("No ukto found.")
                            salden = None
                        break

            if ukto:
                while (0 == 0):
                    m = re.search(r"^(.*)\-(.*)$",ukto)
                    if not m or not pattern in m.group(1).upper():
                        break
                    ukto  = m.group(1)
                    ukto0 = re.sub(r"\^","",ukto)
            

            if ukto or ktoa[1] == "-":
                saldo = ( int( ukto and ktoa.startswith(ukto) or ktoa[1] == "-") +
                          int( ukto and ktob.startswith(ukto) or ktob[1] == "-") )
                
            if uniqu == []:
                uniqu = [ktoa,ktob]

            maxsaldo = max(maxsaldo,saldo)
            uniqu1  = []
            for k in uniqu:
                uniqu1.append(re.sub(r"\-\d\d\d\d\d$","-BETRAG",k))
            uniqu   = uniqu1

            betrag1 = re.sub("\-","",betrag) + ","
            remark1 = "," + re.sub(r"[\+\- ]","",remark,9999)
            uniqu   = betrag1 + ",".join(uniqu) + remark1

            if datum in unique_strings:  #  to avoid double entries
                if uniqu in unique_strings[datum]:
                    continue  #  der Eintrag mit diesem unique-String existiert schon, daher nicht nochmal nehmen
                else:
                    unique_strings[datum].append(uniqu)
            else:
                unique_strings[datum] = [uniqu]

            ktoa = ktoa.replace("^","")
            ktob = ktob.replace("^","")

            if ktoa[0] == "-":
                maxc = max(maxc,len(ktoa))
            else:
                maxa = max(maxa,len(ktoa))

            if ktob[0] == "-":
                maxd = max(maxd,len(ktob))
            else:
                maxb = max(maxb,len(ktob))

            buchungen.append([datum,betrag,ktoa,ktob,remark,saldo,zeile])

    if ukto == None:
        ukto = ""
    ukto = ukto.replace("^","")

    if maxc > 0:
        maxa = max(maxa,len(ukto)+maxc)
    if maxd > 0:
        maxb = max(maxb,len(ukto)+maxd)

    format_maxa = "%-" + str(maxa) + "s"
    format_maxb = "%-" + str(maxb) + "s"

    return(buchungen,format_maxa,format_maxb,str(maxsaldo),ukto)


#*********************************************************************

def apply_patch (file,patch,offset=0):  #  verbessern! Kann der patch Befehl auch dirket auf result.txt angewendet werden?

    text = open(file).read()
    text = re.sub("\n","--CR--\n",text,99999999)
    text = text.split("\n")
    
    nr = -1
    for zeile in open(patch).read().split("\n"):
        if len(zeile) == 0:
            continue
        if zeile[0] == ">":
            text[nr] = text[nr] + zeile[2:] + "--CR--"
        elif zeile[0] == "<":
            continue
        else:
            m = re.search(r"^(\d+)(,\d+|)([acd])",zeile)
            if m:
                act = m.group(3)
                nr1 = int(m.group(1)) - 1 - offset
                nr2 = nr1
                if len(m.group(2)) > 0:
                    nr2 = int(m.group(2)[1:]) - 1 - offset
                if act in "ac":
                    nr = nr1
                if act in "dc":
                    while (0 == 0):
                        print("DDD",text[nr1])
                        text[nr1] = ""
                        nr1 = nr1 + 1
                        if nr1 > nr2:
                            break

    text = "".join(text)
    text = re.sub(r"--CR--","\n",text,99999999)
    text = re.sub(r"\n$","",text,re.DOTALL)
    
    open(file,"w").write(text)


#******************************************************************************

class Kto9 ():

    def mark (self,remark=""):
    
        t = time.perf_counter()
        if 't0' in vars(self):
            print ( ("%9.2f" % ((t-self.t0)*1000)) + " ms for:  " + remark )
        self.t0 = t

#******************************************************************************

    def parse_pattern (self,pattern=""):    #   parse the pattern

        self.interval = None
        self.pattern  = pattern
        m = re.search(r"^(.*)([\.\:])(.*)$",pattern)
        
        if m:

            self.pattern  = m.group(1)
            mode          = m.group(2)
            interval      = "20" + m.group(3)[0:2]
            months        = m.group(3)[2:]
            
            if   months == "A":
                months = "10"
            elif months == "B":
                months = "11"
            elif months == "C":
                months = "12"
            elif months == "I":
                months = "0[123]"
            elif months == "J":
                months = "0[456]"
            elif months == "K":
                months = "0[789]"
            elif months == "L":
                months = "1[012]"
            elif months == "M":
                months = "0[123456]"
            elif months == "N":
                months = "[01][789012]"
            elif months == "P":
                months = ""
            elif not months == "":
                months = "0" + months
        
            if mode == ":":
                intervals = []
                jahr      = "2000"
                while (0 == 0):
                    intervals.append(jahr)
                    jahr = str(int(jahr)+1)
                    if jahr == interval:
                        break
                month = "01"
                while (0 == 0):
                    intervals.append(jahr+month)
                    if month in (months,"12"):
                        break
                    month = "%02u" % (int(month) + 1)
                self.interval = "\\(" + "\\|".join(intervals) + "\\)"
#                print(self.interval)
                self.egrep    = "e"
            else:
                self.interval = interval + months
                self.egrep    = ""
            
#******************************************************************************

    def kto_match (self,file):   #  deliver the matching part of database

        pattern1 = re.sub(r"\^"," ",self.pattern,9999)
#        print(pattern1,file)
        if self.interval:
            if self.pattern == "":
                self.text_match = os.popen(self.egrep+"grep -i ^"+self.interval + " " + file).read()
            else:
                self.text_match = os.popen(self.egrep+"grep -i ^"+self.interval + " " + file + " | grep -i '" + pattern1 + "'").read()
        else:
            if self.pattern == "":
                self.text_match = open(file).read()
            else:
                self.text_match = os.popen("grep -i '" + pattern1 + "' " + file).read()

#******************************************************************************

    def kto_rest (self,file):   #   deliver the rest of the database, not matched by the pattern

        pattern1 = re.sub(r"\^"," ",self.pattern,9999)

        if self.interval:
            if self.pattern == "":
                self.text_rest  = os.popen(self.egrep+"grep -i -v ^"+self.interval + " " + file).read()
            else:
                self.text_rest  = ( os.popen(self.egrep+"grep -i -v ^"+self.interval + " " + file).read() + 
                                    os.popen(self.egrep+"grep -i ^"   +self.interval + " " + file + 
                                        " | grep -i -v '" + pattern1 + "'").read() )
        else:
            if self.pattern == "":
                self.text_rest  = ""
            else:
                self.text_rest  = os.popen("grep -i -v '" + pattern1 + "' " + file).read()
        
#******************************************************************************

    def sync (self,file="",file0="",pattern_new="",add_string=""):

        if file == "m":
            paths = ['*/*/*/*/*/*/*/*/*/*/',
                     '*/*/*/*/*/*/*/*/*/',
                     '*/*/*/*/*/*/*/*/',
                     '*/*/*/*/*/*/*/',
                     '*/*/*/*/*/*/',
                     '*/*/*/*/*/',
                     '*/*/*/*/',
                     '*/*/*/',
                     '*/*/',
                     '*/'
#                     ,'.'
                     ]
            ktodir = []
                     
            for path in paths:
                for dir in glob.glob(path):
                    if not os.path.isdir(dir):
                        continue
                    if len(glob.glob(dir+"/*.kto")) == 0:
                        continue
                    ktodir.append(dir)
#                    print(dir)
            self.multisync(ktodir)
            return()
                        

        self.mark("O. Start sync")
        self.ukto = None
        id        = None

        zaehler = 0
        file1   = file0
        while (0 == 0):
            db_ktobase = glob.glob(file0+"/*.db.kto")
            if len(db_ktobase) == 1:
                file0 = db_ktobase[0]
            if os.path.isfile(file0):
                break
            file0 = file0 + "/.." 
            zaehler = zaehler + 1
            if zaehler == 20:
                file0 = file
            if zaehler > 40:
                if pattern_new == "":
                    id = self.sync(file,".",file1)
                else:
                    print("no parent file found: " + file0)
                return(id)

        if os.path.isdir(file):
            file1 = glob.glob(file+"/*.kto")
            if len(file1) > 1:
                print("More than one ktofile.")
                return()
            if len(file1) == 0:
                file = file + "/kto.kto"
            else:
                file = file1[0]

        if not re.search(r"\.kto$",file):
            id = self.sync(".",file0,file)
            return(id)


        if not os.path.isfile(file):
            self.parse_pattern(pattern_new)
            self.kto_match(file0)
            open(file,"w").write("     " + pattern_new + "\n" + self.text_match)
            return(None)

        text    = open(file)
        keyline = text.readline()
        text    = text.read()
        text2   = keyline + text
        pattern = ""

        m = re.search(r"\((\S\S\S\S\S\S)\) +(\S+)",keyline)
        if not m:
            m = re.search(r"\((\S\S\S\S\S\S)\)",keyline)
        elif pattern == "":
            pattern = m.group(2)
        if not m:
            if re.search(r"^ +(\S+) *$",keyline):
                pattern = keyline.strip()
            else: 
                text = keyline + text

        if pattern_new == "":
            pattern_new = pattern

        if pattern_new == "":
            print("No pattern in file: "+file)
            os.system("mv "+file+" "+file+".DELETE")
            return()
       
        self.parse_pattern(pattern_new)
        self.mark("A. Parse pattern")

        self.kto_match(file0)
        if not pattern_new == pattern:   # neues Pattern, daher Datei neu anlegen
#            self.kto_match(file0)
            open(file,"w").write("     " + pattern_new + "\n" + self.text_match)
            return()

        if not m:
#            self.kto_match(file0)
            if not text == self.text_match:
                self.kto_rest(file0)
                open(file0,"w").write(self.text_rest + text)
                open(file,"w").write("    (xxxxxx)\n\n"+text)
                return()
            key = "xxxxxx"
            id  = "yyyyyy"
        else:
            key  = m.group(1)
            id   = self.make_id(0,text.strip()+add_string)
        
#        print("KKK",key,id)
        rule_file_exists = False
        abs_file         = os.path.abspath(file)
        m = re.search(r"^(.*)[\\\/](.*)$",abs_file)
        if m:
            rule_dir         = m.group(1)
            file1            = m.group(2)
            try:
                self.rules_done
            except:
                self.rules_done = []
            rule_file_exists = os.path.isfile(rule_dir+"/rule.py") and not rule_dir in (self.rules_done)

        self.rule_executed = 0
        if not id  == key:
            if not key == "_rule_" and m:
                if rule_file_exists:
                    orig_dir = os.path.relpath(".",rule_dir)
                    os.chdir(rule_dir)
                    print( os.popen("python3 rule.py " + file1).read() )
                    self.mark("  ... apply rule.")
                    os.chdir(orig_dir)
                    text = open(file)
                    text.readline()
                    text = text.read()
                    if len(text) == 0:
                        text = " "
                    self.rule_executed = 1
                    self.rules_done.append(rule_dir)
            if self.rule_executed == 0:
                os.unlink(file)
                text = self.format_kto(text)

        else:
            self.kto_match(file0)
            os.unlink(file)
            text = self.format_kto(self.text_match,text.split("\n"))


        if not text == None: #  and len(text) > 0:

            self.kto_rest(file0)

            if self.rule_executed == 0:
                text0 = self.text_rest + text
                open(file0,"w").write(text0)

            id0 = id
            if self.rule_executed == 1:
                id = "_rule_"
            else:
                id = self.make_id(0,text.strip()+add_string)
#                print("XXX",key,id0,id)
                if not id0 == id and not key == "_rule_" and not id == key and rule_file_exists:
                    id = "_chng_"
                    self.mark("  ... prepare for rule.")

            if self.ukto:
                open(file,"w").write(("%-25s" % self.ukto) + "  " + "(" + id + ")   " +
                                      pattern + " " + self.last_sum + "\n\n"+text)
            else:
                open(file,"w").write("    (" + id + ")   " + pattern + "\n\n"+text)
            return(id)

        else:
            open(file,"w").write(text2)

        if self.ukto:
            return(id)
        else:
            return(None)
        
#****************************************************************************************

    def make_id (self,mode,text):
    
        profile = False
        if profile:
            self.mark("--1")
            
        if mode == 9:
            text = text.replace("  ","")  #  for performance reasons, this line doubles the speed!
            text = text.replace(" ","").split("\n")
            if profile:
                self.mark("--2")
            text.sort()
            text1 = []
            for line in text:
                line1 = list(line)
                line1.sort()
                text1.append("".join(line))
            if profile:
                self.mark("--3")
            text = "\n".join(text1)
            if profile:
                self.mark("--4")

        if mode == 1:
#            text = text.replace("  ","")  #  for performance reasons, this line doubles the speed!
#            text = text.replace(" ","").split("\n")
            text1 = []
            for line in text.split("\n"):
                m = re.search("^(\d\d\d\d\d\d\d\d) +\-?(\d+\.\d\d) +(\S+) +(\S+) +\S+ +(.*?) *$",line)
                if m:
                    line1 = [m.group(3),m.group(4)]
                    line1.sort()
                    line1 = [m.group(1) + m.group(2)] + line1 + [m.group(5)]
#                    line1.sort()
                    text1.append("".join(line1))
            text1.sort()
            text = "\n".join(text1)
                
        if mode == 2:
            text1 = []
            elements = []
            
            for line in text.split("\n")+["99999999"]:
                if len(line) == 8:
                    if re.search(r"^\d\d\d\d\d\d\d\d$",line):
                        if len(elements) > 0:
                            elements_a = elements[1:2]
                            elements_a.sort()
                            elements   = [ elements[0] ] + elements_a + elements[3:]
                            text1.append("".join(line))
                            elements = [line]
                else:
                    elements.append(line)
            text1.sort()
            text = "\n".join(text1)
                

        text = text.replace("  ","")  #  for performance reasons, this line doubles the speed!
        text = text.replace(" ","") 
        text = text.replace("\n","XX\n") 
        id = str( base64.urlsafe_b64encode(hashlib.md5( text.encode("utf-8")).digest()),"ascii" )[0:6]
        if profile:
            self.mark("--5")
        return(id)

#****************************************************************************************

    def make_db (self,text):
    
        self.mark("--1")
        text = re.sub(r"(\d\d\d\d\d\d\d\d) +(\d+\.\d\d) +(\S+?) +(\S+?) +(\-?\d+\.\d\d) +(.*?) *","---\\1.\\2.\\3.\\4.\\6",text,99999999)
        text = re.sub(r"(\d\d\d\d\d\d\d\d) +-(\d+\.\d\d) +(\S+?) +(\S+?) +(\-?\d+\.\d\d) +(.*?) *","---\\1.\\3.\\2.\\4.\\6",text,99999999)
        self.mark("--2")
        print(text)
        self.mark("--3")

#****************************************************************************************

    def format_kto (self,text,ktotext_old=[]):

        result = self.parse_ktotext(text.split("\n"),self.pattern,ktotext_old)
        self.mark("B. parse ktotext.")
        if not result:
            return(None)
            
        (ktotext,format_maxa,format_maxb,maxsaldo,ukto) = result
            
        print("UKTO: " + ukto)
        if ukto == "":
            ktotext.sort(key=lambda x:x[0]+str(x[1])+x[3]+x[4])
        else:
#            if ukto.startswith("10-B12-3695-qu"):
#                ktotext.sort(key=lambda x:str(abs(float(x[1])))+str(x[5]+1)+x[0])
#            else:
                ktotext.sort(key=lambda x:str(x[5]+1)+x[0])
        text_match = []
        gesamt     = 0.00
        datum0     = "00000000"
        self.ukto0 = ukto
        salden     = {}

        for zeile in ktotext:
                
            if zeile[5] == -1:
                text_match.append(zeile[1])
            else:
                betrag = float(zeile[1])
                if ukto == "" or zeile[5] == 0:
                    saldo = "         ...."
                elif maxsaldo == 0 or zeile[5] == 1:
                    gesamt = gesamt + betrag
                    saldo  = "%13.2f" % gesamt
                elif zeile[5] == 2:
                    saldo = "         0.00"
                ust = ""
                if "v.H." in zeile[4]:
                    ust = "   "

                ktoa = zeile[2]
                if ktoa[0] == "-":
                    self.rule_executed = 1
                    if ktoa == "-":
                        ktoa = ukto
                    else:
                        ktoa = ukto + ktoa
                self.compute_salden(salden,ktoa,betrag,zeile[0])
                ktob = zeile[3]
                if ktob[0] == "-":
                    self.rule_executed = 1
                    if ktob == "-":
                        ktob = ukto
                    else:
                        ktob = ukto + ktob
                self.compute_salden(salden,ktob,-betrag,zeile[0])

                zeile1 = ( zeile[0] + " " + ("%13.2f" % betrag) + "  " + (format_maxa % ktoa) + "  " +
                           (format_maxb % ktob) + " " + saldo + "  " + ust + re.sub(r" +"," ",zeile[4],9999) )
                text_match.append(zeile1)

        self.ukto = ukto
        if ukto == "":
            self.last_sum = ""
        else:
            self.last_sum = "%20.2f" % gesamt

        ktoliste = list(salden.keys())
        ktoliste.sort()
        text_match.append("")
        
        ktotyp =  ["^[^-]+","xxB12-3695","C13-3751","C13-3759","C13-3740","B12-1361",
                            "C11-3170","C12-3310","B12-1435","B12-1340","B12-3695","Do.-4600","Do.-4610",
                            "Do.-6011","Do.-6111","Do.-6816","Do.-6817","Do.-6818",
                            "Bo.-ver","Bo.-kto","Bo.-umlagen","Bo.-1700",
                            "D..-4100","D..-4105","D..-4106","D..-4400"]
        

        text_match.append("                  " + ("%13.2f" % gesamt))
        
        for kto in ktoliste:

            bed = 0
            if not "-" in kto:
                bed = 1
            else:
                for ktyp in ktotyp:
                    if re.search("^"+ktyp+r"-[^\-]+$",kto):
                        bed = 1
                        break
            if bed == 0:
                continue

            kto_ordnung = max(0,len(re.sub("[^\-]","",kto)))
            if kto_ordnung > 3:
                continue
            kto_ordnung = "%-" + ("%2u"%(20+kto_ordnung*4)) + "s"
            text_match.append( (kto_ordnung % kto) + "  " + ("%13.2f" % salden[kto]["XX"]) )

        self.mark("C. format kto")
        return("\n".join(text_match) + "\n")

#******************************************************************************

    def compute_salden (self,salden,ukto,betrag,datum):

        monat = datum[4:6]
        monat = "XX"

        ukto = re.sub(r"-qu-","-",ukto)

        if ukto.startswith(self.ukto0+"-"):
            ukto = re.sub("^"+self.ukto0+"-","",ukto)
        else:
            return()
#        ukto = re.sub(r"^(.*?)\-(.*)$","\\1",ukto)


        while (0 == 0):
            if not ukto in salden:
                salden[ukto] = {}
            if not monat in salden[ukto]:
                salden[ukto][monat] = 0.00
            salden[ukto][monat] = salden[ukto][monat] + betrag

            m = re.search(r"^(.*)\-(.+)$",ukto)
#            if not m:
#                m = re.search(r"^(.*?)(.+)$",ukto)
            if m:
                ukto = m.group(1)
            else:
                return()

#            return()

#******************************************************************************

    def parse_ktotext (self,ktotext,pattern,ktotext_old=[]):

        buchungen      = []
        unique_strings = {}
        pattern        = pattern.strip().upper()
        if len(pattern) > 0 and pattern[-1] == "-":
            pattern = pattern[:-1]
        maxa           = 10
        maxb           = 10
        maxc           = 0
        maxd           = 0
        maxsaldo       = 0

        ukto = ""
        if pattern == "":
            ukto = None
            
#        ktotext_old.sort()
        
        self.kto_is_up_to_date_until_now = int(not ktotext_old == [])
        
        zaehler = -1
        vvv = re.compile(r"^(\d\d\d\d)(..)(\d\d) +(\S+) +(\S+) +(\S+) +(\-?\d+\.\d\d|\-+|\.+) +(.*?) *$")
#        ktotext.sort()
        for zeile in ktotext:

            mm = vvv.search(zeile)
            if not mm:   #   Einlesen der Kontobezeichnungen
#                buchungen.append(["00000000",zeile,"","","",-1])
                continue

            if mm.group(2) == "MM":
                monate = ["01","02","03","04","05","06","07","08","09","10","11","12"]
            else:
                monate = [mm.group(2)]

            for monat in monate:

                datum  = mm.group(1) + monat + mm.group(3)
                try:
                    betrag = "%3.2f" % eval(mm.group(4))
                except:
                    print(mm.group(4))
                    exit()

                remark   = mm.group(8)
                uniqu    = []
                ktoa     = "^" + mm.group(5)
                ktob     = "^" + mm.group(6)

#                ktoa = self.parse_ktotext_compute_kto(m.group(5),self.ukto,uniqu)
#                ktob = self.parse_ktotext_compute_kto(m.group(6),self.ukto,uniqu)

                if ktoa > ktob:
                    o      = ktoa    #  um Eindeutigkeit zu schaffen. Sonst kann es durch
                    ktoa   = ktob    #  Hin- und Herschwingen zu Endlos-Loops kommen
                    ktob   = o
                    betrag = re.sub(r"^--","","-"+betrag)

                if not ktoa[1] == "-" and not pattern in ktoa.upper() and pattern in ktob.upper():
                    o      = ktoa    #  um das gefundene Konto an den Anfang zu stellen
                    ktoa   = ktob
                    ktob   = o
                    betrag = re.sub(r"^--","","-"+betrag)

                saldo = 0
#                print(zeile)
                if not ukto == None:
                    
                    if ukto == "":
                        if pattern in ktoa.upper() and not ktoa[1] == "-":
                            ukto = ktoa
                    for kto in (ktoa,ktob):
                        if pattern in kto.upper() and not kto[1] == "-":
                            while (0 == 0):
                                if kto.startswith(ukto):
                                    break
                                m = re.search(r"^(.*)\-(.*)$",ukto)
                                if m:
                                    ukto = m.group(1)
                                else:
                                    ukto = ""
                                print("           fit ukto: " + ukto.replace("^",""))
                            if not pattern in ukto.upper():
                                ukto = None
                                print("No ukto found.")
                            break

#                print(123)
                if ukto:
                    while (0 == 0):
#                        print(pattern,ukto)
                        m = re.search(r"^(.*)\-(.*)$",ukto)
                        if not m or not pattern in m.group(1).upper():
                            break
                        ukto = m.group(1)
                

                if ukto or ktoa[1] == "-":
                    saldo = ( int( ukto and ktoa.startswith(ukto) or ktoa[1] == "-") +
                              int( ukto and ktob.startswith(ukto) or ktob[1] == "-") )
#                    print(ktoa,ktob,ukto,saldo,betrag)
                    
                if uniqu == []:
                    uniqu = [ktoa,ktob]

                maxsaldo = max(maxsaldo,saldo)
                uniqu1  = []
                for k in uniqu:
                    uniqu1.append(re.sub(r"\-\d\d\d\d\d$","-BETRAG",k))
                uniqu   = uniqu1

                betrag1 = re.sub("\-","",betrag) + ","
                remark1 = "," + re.sub(r"[\+\- ]","",remark,9999)
                uniqu   = betrag1 + ",".join(uniqu) + remark1

                if datum in unique_strings:  #  to avoid double entries
                    if uniqu in unique_strings[datum]:
                        continue  #  der Eintrag mit diesem unique-String existiert schon, daher nicht nochmal nehmen
                    else:
                        unique_strings[datum].append(uniqu)
                else:
                    unique_strings[datum] = [uniqu]

                ktoa = ktoa.replace("^","")
                ktob = ktob.replace("^","")

                if ktoa[0] == "-":
                    maxc = max(maxc,len(ktoa))
                else:
                    maxa = max(maxa,len(ktoa))
    
                if ktob[0] == "-":
                    maxd = max(maxd,len(ktob))
                else:
                    maxb = max(maxb,len(ktob))

                buchungen.append([datum,betrag,ktoa,ktob,remark,saldo])
#                print(buchungen[-1])
 
#   ---- additional check

                if self.kto_is_up_to_date_until_now:
                    while (0 == 0):
                        zaehler = zaehler + 1
                        if zaehler < len(ktotext_old):
                            line = ktotext_old[zaehler]
                        else:
                            m1   = None
                            break
                        m1 = re.search("^(\d\d\d\d\d\d\d\d) +(\-?\d+\.\d\d) +(\S+) +(\S+) +(\S+) +(.*?) *$",line)
                        if m1:
                            break
                
                    if m1:
                        datum1  = m1.group(1)
                        betrag1 = m1.group(2)
                        ktoa1   = m1.group(3)
                        ktob1   = m1.group(4)
                        remark1 = m1.group(6)
#                        print(line)
#                        print(zeile)
#                        print(datum,datum1)
#                        print(betrag,betrag1)
#                        print(ktoa,ktoa1)
#                        print(ktob,ktob1)
#                        print(remark,remark1)
                        if ( not datum1 == datum or not betrag1 == betrag or not remark1 == remark or
                             not ktoa in (ktoa1,ktob1) or not ktob in (ktoa1,ktob1) ):
                                 self.kto_is_up_to_date_until_now = False
#                                 print(line)
#                                 print(zeile)
                    else:
                        self.kto_is_up_to_date_until_now = False
#                    print(self.kto_is_up_to_date_until_now)
                        
        if self.kto_is_up_to_date_until_now:
            return(None)
        
        
        if ukto == None:
            ukto = ""
        ukto = ukto.replace("^","")

        if maxc > 0:
            maxa = max(maxa,len(ukto)+maxc)
        if maxd > 0:
            maxb = max(maxb,len(ukto)+maxd)

        format_maxa = "%-" + str(maxa) + "s"
        format_maxb = "%-" + str(maxb) + "s"
        return(buchungen,format_maxa,format_maxb,str(maxsaldo),ukto)

#******************************************************************************

    def xxyy (self,file=".",pattern=None):    #   file: Ziel
    
        self.mark("")

        if os.path.isdir(file):    #  file is a dir
            dir  = file
            file = dir + "/standard.kto"
        else:                      #  file is a file
            if pattern:
                dir = file
                try:
                    os.mkdir(file)
                except:
                    pass
                file = dir + "/standard.kto"
            else:            
                m = re.search(r"^(.*)[\\\/](.*)$",file)
                if m:
                    dir = m.group(1)
                else:
                    dir = "."

        files = glob.glob(dir+"/*.kto")
        if len(files) == 0:
            if pattern:
                try:
                    os.mkdir(dir)
                except:
                    pass
                try:
                    open(file,"w").write("")
                except:
                    print("File " + file + " not able to create.")
                    return()
            else:
                print("No ktofile found.")
                return()            
        
        elif len(files) > 1:
            print("More than one ktofile found: " + " ".join(files))
            return()

        else:
            file   = files[0]
            header = open(file).readline()
            header = re.sub(r"\-?\d+\.\d\d *$","",header)
            m = re.search(r"^(\S*) *(\(.*?\)) +(.*?) *$",header)
            if m:
                if pattern:
                    if not m.group(3) == pattern:
                        if os.path.isfile(file):
                            os.unlink(file)
                else:
                    pattern = m.group(3)
                self.mark("Kto " + m.group(1) + " found.")

            m = re.search(r"^(.*[\\\/])(.*?)[\\\/](|pattern_)([^\\\/]+)\.kto$",os.path.abspath(file))
            if m:
                os.system("touch " + m.group(1) + m.group(2) + "/" + "rule.py")
                if not pattern:
                    pattern = re.sub(r"\.\.",":",m.group(4),99)
                    pattern = re.sub(r"^\_","\^",pattern,99)
            
        dir0    = dir    #  find the source kto
        ruledir = None
        if os.path.isfile(dir+"/rule.py") or dir[0:4] == "rule":
            ruledir = dir

        absdir0 = ""
        while (0 == 0):   #   try to find a parent file, starting with the parent directory of dir
            dir0    = dir0 + "/.."
            absdir = os.path.abspath(dir0)
            print("    ... searching parent directory in " + absdir + " ...")  #   + re.sub(r"^(.*)([\\\/].*)$","\\2",file0) )
            if absdir == absdir0:
                print("No parent ktofile found.")
                return()
            absdir0 = absdir
            if not os.path.isdir(dir0):
                break
            files = glob.glob(dir0+"/*.kto")
            for file0 in files:
                if re.search(r"[\\\/]no\.kto$",file0):
                    print("No ktofile directories region from here.\n    ... give it up in " + absdir + ".")
                    return()
                if not pattern:
                    pattern0 = self.find_pattern_from_udir( os.path.relpath(dir0,dir))   #  not yet implemented
                else:
                    pattern0 = pattern
                erg = self.sync(pattern0,file0,file,"",ruledir)
                if not erg == 4:
                    return(erg)
#            print("Failing to find parent kto in " + absdir + ".\n    ... now try next uppermost parent ktofile directory.")
                

#******************************************************************************

    def multisync (self,ktolist):
    
        ktoids      = {}
        kto_in_work = []
        for kto in ktolist:
            if re.search(r"(^|[\\\/])_[^\\\/]+_([\\\/]|$)",kto):
                continue
            kto_in_work.append(re.sub(r"^(.*)[\\\/](.*.kto)$","\\1",kto))
            print(kto_in_work[-1])

        zaehler = 0
        while (0 == 0):
            if len(kto_in_work) == 0:
                break
            zaehler = (zaehler + 1) % len(ktolist)
#            round   = int((zaehler + 1) / len(kto_in_work)) + 1
            kto     = ktolist[zaehler]
            if not kto in kto_in_work:
                continue
            if len(glob.glob(kto+"/*.kto")) == 0:
                continue
#            bed = False
            while (0 == 0):
                id = self.sync(kto)
                if not id: # if not id in ["_rule_","_chng_"]:  #  technische id
                    break
#                if not id in ["_rule_","_chng_"]:

            if kto in kto_in_work:
                kto_in_work.remove(kto)
#            if not id:  
#                continue
            kto_in_work.append(kto)

            if not kto in ktoids:
                ktoids[kto] = []

            ktoids[kto].append(id)
            print(len(ktoids[kto]),"----",id,kto)
            if len(ktoids[kto]) > 1 and ktoids[kto][-2] == ktoids[kto][-1]:
                kto_in_work.remove(kto)
                
#                print(ktoids[kto])
#                if len(ktoids[kto]) == 0:
#                    ktoids[kto].append(id)
#                else:
#                    ktoids[kto] = [  ktoids[kto][-1],id ]
#                if not ktoids[kto][0] == ktoids[kto][1]:
#                    kto_in_work.append(kto)
                
#******************************************************************************

    def xxy (self,pattern=None,par=None):
    
        if par:
            dir     = pattern
            pattern = par
            try:
                os.system("mkdir "+dir)
            except:
                pass
            files = glob.glob(dir+"/*.kto")
            if len(files) > 1:
                print("More than one file in " + dir)
                return()
            if len(files) == 1:
                file = files[0]
                os.unlink(file)
            else:
                file = dir + "/" + pattern + ".orig"
            open(file,"w").write(" ")
            pattern = dir
    
        if pattern and (os.path.isdir(pattern) or os.path.isdir(pattern)):
            self.yy(pattern)   #   pattern is a file or a directory
            return()
            
        if not pattern:
            self.yy()
            return()

#        if not os.path.isdir("99_tmp"):
#            os.mkdir("99_tmp")

        tmp_dir = re.sub(r"\:","__",pattern)
        tmp_dir = "99_tmp/" + re.sub(r"[^0-9a-zA-Z\\\/]","_",tmp_dir)

#        last_dir = ""
#        for file in glob.glob("tmp_*/rule.py"):
#            last_dir = re.sub(r"[\\\/]rule.py","",file)
#            os.unlink(file)

        self.yy(tmp_dir,pattern)
        os.system("joe " + tmp_dir + "/standard.kto")

        for file in glob.glob("99_tmp/*/rule.py"):
            os.unlink(file)
        
        os.system("touch " + tmp_dir + "/rule.py")

        self.yy(tmp_dir,pattern)

#******************************************************************************

    def xxread_file (self,file=None):

        if not file:
            files = glob.glob("*.kto")
            if len(files) == 1:
                file = files[0]
        text = open(file).read()
        
        try:
            pos   = text.index("====")
            text0 = text[0:pos]
            text  = text[pos:]
        except:
            text0 = ""
            
        text1 = []
        for zeile in text.split("\n"):
        
            if zeile.startswith("====") or zeile.strip() == "":
                continue
        
            m = re.search(r"^(\d\d\d\d\d\d\d\d)( +\S+)( +)(\S+ +)(\S+ +)(\-?\d+\.\d\d| +\-+| +\.+)( +)(.*)$",zeile)
            if not m:
                text1.append(zeile)
                continue
                
            datum  = m.group(1)
            betrag = m.group(2)
            zwa    = m.group(3)
            ktoa   = m.group(4)
            ktob   = m.group(5)
            saldo  = m.group(6)
            zwb    = m.group(7)
            remark = m.group(8)
            
            text1.append([datum,betrag,zwa,ktoa,ktob,saldo,zwb,remark])
            
        return(file,text0,text1)
        
#******************************************************************************

    def xxusteuer (self,einnahmenkto,ausgabenkto,gegenkto,file=None):
    
        (file,text0,text1) = self.read_file(file)
        einnahmen = {}
        ausgaben  = {}
        
        text2 = []
        for zeile in text1:
            if type(zeile) == type(""):
                text2.append(zeile)

            remark = zeile[7] 
            if "v.H." in remark:
                continue
                
            text2.append("".join(zeile))
            
            if remark[0:2] == '++':
                steuersatz = 19
                steuerart  = "6"
            elif remark[0:2] == '+-':
                steuersatz = 7
                steuerart  = "7"
            else:
                steuersatz = 0
                steuerart  = ""

            datum  = zeile[0]
            betrag = zeile[1]
            zwa    = zeile[2]
            ktoa   = zeile[3]
            ktob   = zeile[4]
            saldo  = zeile[5]
            zwb    = zeile[6]
            remark = remark[2:]
            jahr   = datum[0:4]

            format_ktoa   = "%-" + str(len(ktoa))   + "s"
            format_ktob   = "%-" + str(len(ktob))   + "s"
            format_betrag = "%"  + str(len(betrag)) + ".2f"
            betrag        = float(betrag)
#            ktoa          = ktoa.strip()
#            ktob          = ktob.strip()

            if not datum[0:4] in einnahmen:
                einnahmen[jahr] = 0.00
            if not datum[0:4] in ausgaben:
                ausgaben[jahr] = 0.00

            netto = betrag - betrag * steuersatz * 0.01 / (1.0 + steuersatz * 0.01)

            if ktoa.strip().startswith(einnahmenkto):
                einnahmen[jahr] = einnahmen[jahr] + netto
                if betrag > 0.0:
                    ktob = format_ktob % (gegenkto + "-I" + steuerart)
                    add  = "Vorst."
                else:
                    ktob = format_ktob % (gegenkto + "-U" + steuerart)
                    add  = "USt."

            elif ktoa.strip().startswith(ausgabenkto):
                ausgaben[jahr] = ausgaben[jahr] + netto
                if betrag < 0.0:
                    ktob = format_ktob % (gegenkto + "-U" + steuerart)
                    add  = "USt."
                else:
                    ktob = format_ktob % (gegenkto + "-I" + steuerart)
                    add  = "Vorst."

            elif ktob.strip().startswith(einnahmenkto):
                einnahmen[jahr] = einnahmen[jahr] - netto 
                if betrag < 0.0:
                    ktoa = format_ktoa % (gegenkto + "-U" + steuerart)
                    add  = "USt."
                else:
                    ktoa = format_ktoa % (gegenkto + "-I" + steuerart)
                    add  = "Vorst."

            elif ktob.strip().startswith(ausgabenkto):
                ausgaben[jahr] = ausgaben[jahr] - netto
                if betrag > 0.0:
                    ktoa = format_ktoa % (gegenkto + "-I" + steuerart)
                    add  = "Vorst."
                else:
                    ktoa = format_ktoa % (gegenkto + "-U" + steuerart)
                    add  = "USt."
                    
            else:
                continue
                
            if steuersatz == 0:
                continue

            ubetrag = format_betrag % (-betrag * steuersatz * 0.01 / (1.0 + steuersatz * 0.01) )

            zeile1 = datum  + ubetrag + zwa + ktoa + ktob + (" "*(len(saldo)-4)) + "0.00" + zwb + "    "
            zeile1 = zeile1 + str(steuersatz) + " v.H. " + add + " von " + '%3.2f' % abs(float(betrag))
            zeile1 = zeile1 + ' (' + remark + ')'
            text2.append(zeile1)
                
        brutto = ""
        jahre = list( einnahmen.keys() )
        jahre.sort()
        for jahr in jahre:
            brutto = brutto + jahr + "  " + ("%20.2f" % einnahmen[jahr] ) + "\n"
        open("einnahmen.txt","w").write(brutto)
        
        brutto = ""
        jahre = list( ausgaben.keys() )
        jahre.sort()
        for jahr in jahre:
            brutto = brutto + jahr + "  " + ("%20.2f" % ausgaben[jahr] ) + "\n"
        open("ausgaben.txt","w").write(brutto)
        
        text2 = "\n".join(text2) 
        if not text0.strip() == "":
            text2 = text0 + '====\n' + text2 + '\n'
        open(file,"w").write(text2)


#**************************************************************************************


    def xxsync (self,file,file1,pattern):

        text  = open(file).read()
        try:
            text1 = open(file1)
        except:
            text1 = None
            
        if text1:
            keyline = text1.readline()
            text1   = text1.read()
            m = re.search(r"\((\S\S\S\S\S\S)(\S\S\S\S\S\S)\)",keyline)
            if m:
                key0 = m.group(1)
                key1 = m.group(2)
            else:
                key0 = ""
                key1 = ""
                text1 = keyline + text1
            id0 = str( base64.urlsafe_b64encode(hashlib.md5( text1.encode("utf-8")).digest()),"ascii" )[0:6]

        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_match.sort(key=lambda x: x[0:8])
        id1 = str( base64.urlsafe_b64encode(hashlib.md5( (pattern+"\n".join(text_match)).encode("utf-8")).digest()),"ascii" )[0:6]

#        print(id1,key1,id0,key0)
        if text1:
            if id1 == key1 or key1 == "":
                if id0 == key0:
                    return(0)
                else:
                    open(file,"w").write("\n".join(text_rest) + "\n" + text1)
                    print("update parent")
                    text1 = re.sub(r"^.*?\n(.*)$","\\1",text1) 
            elif id0 == key0:
                text1 = None
            else:
                print("CONFLICT")
                return(1)

        if not text1:
            text1 = "\n".join(text_match) + "\n"

        id0   = str( base64.urlsafe_b64encode(hashlib.md5( text1.encode("utf-8")).digest()),"ascii" )[0:6]
        text1 = "    ("+id0+id1+")\n" + text1
        open(file1,"w").write(text1)
        print("update ukto")
        return(0)

#******************************************************************************

    def xxsort (self,part,pattern="",file=None):

        if not file:
            files = glob.glob("*.kto")
            if len(files) == 1:
                file = files[0]

        interval      = None
        insertline    = "====  " + pattern + "\n"

        m = re.search(r"^(.*)([\.\:])(.*)$",pattern)
        if m:

            pattern  = m.group(1)
            mode     = m.group(2)
            interval = "20" + m.group(3)[0:2]
            months   = m.group(3)[2:]
            
            if   months == "A":
                months = "10"
            elif months == "B":
                months = "11"
            elif months == "C":
                months = "12"
            elif months == "I":
                months = "0[123]"
            elif months == "J":
                months = "0[456]"
            elif months == "K":
                months = "0[789]"
            elif months == "L":
                months = "1[012]"
            elif months == "M":
                months = "0[123456]"
            elif months == "N":
                months = "[01][789012]"
            elif months == "P":
                months = ""
            elif not months == "":
                months = "0" + months
        
            if mode == ":":
                intervals = []
                jahr      = "2000"
                while (0 == 0):
                    if jahr > interval:
                        break
                    intervals.append(jahr)
                    jahr = str(int(jahr)+1)
                interval = "\\(" + "\\|".join(intervals) + months + "\\)"
                e        = "e"
            else:
                interval = interval + months
                e        = ""
            
        pattern1 = re.sub(r"\^"," ",pattern,9999)

        if part in (1,2):
            if interval:
                if pattern == "":
                    text_match = os.popen(e+"grep ^"+interval + " " + file).read()
                else:
                    text_match = os.popen(e+"grep ^"+interval + " " + file + " | grep '" + pattern1 + "'").read()
            else:
                if pattern == "":
                    text_match = open(file).read()
                else:
                    text_match = os.popen("grep '" + pattern1 + "' " + file).read()

        if part in (1,2):
            if interval:
                if pattern == "":
                    if part in (1,2):
                        text_match = os.popen(e+"grep ^"+interval + " " + file).read()
                    if part in (0,2):
                        text_rest  = os.popen(e+"grep -v ^"+interval + " " + file).read()
                else:
                    if part in (1,2):
                        text_match = os.popen(e+"grep ^"+interval + " " + file + " | grep '" + pattern1 + "'").read()
                    if part in (0,2):
                        text_rest  = ( os.popen(e+"grep -v ^"+interval + " " + file).read() + 
                                       os.popen(e+"grep ^"+interval + " " + file + " | grep -v '" + pattern1 + "'").read() )
            else:
                if pattern == "":
                    text_match = open(file).read()
                    text_rest  = ""
                else:
                    text_match = os.popen("grep '" + pattern1 + "' " + file).read()
                    text_rest  = os.popen("grep -v '" + pattern1 + "' " + file).read()
            self.mark("B1.    grep")
        
            self.text_rest  = re.sub(r"\n====.*","",text_rest,9999)

            if not self.text_rest == "":
                self.text_rest = self.text_rest + insertline
#        self.text_match = re.sub(r"====.*\n","",text_match[0:100],9999) + text_match[100:]
            self.text_match = re.sub(r"====.*\n","",text_match,9999)
            self.mark("B2.    Combine")
            self.pattern = pattern

            self.mark("B1.    grep")
        
            self.text_rest  = re.sub(r"\n====.*","",text_rest,9999)

            if not self.text_rest == "":
                self.text_rest = self.text_rest + insertline
#        self.text_match = re.sub(r"====.*\n","",text_match[0:100],9999) + text_match[100:]
            self.text_match = re.sub(r"====.*\n","",text_match,9999)
            self.mark("B2.    Combine")
            self.pattern = pattern

        if part in (1,2):
            if interval:
                if pattern == "":
                    if part in (1,2):
                        text_match = os.popen(e+"grep ^"+interval + " " + file).read()
                    if part in (0,2):
                        text_rest  = os.popen(e+"grep -v ^"+interval + " " + file).read()
                else:
                    if part in (1,2):
                        text_match = os.popen(e+"grep ^"+interval + " " + file + " | grep '" + pattern1 + "'").read()
                    if part in (0,2):
                        text_rest  = ( os.popen(e+"grep -v ^"+interval + " " + file).read() + 
                                       os.popen(e+"grep ^"+interval + " " + file + " | grep -v '" + pattern1 + "'").read() )
            else:
                if pattern == "":
                    text_match = open(file).read()
                    text_rest  = ""
                else:
                    text_match = os.popen("grep '" + pattern1 + "' " + file).read()
                    text_rest  = os.popen("grep -v '" + pattern1 + "' " + file).read()
            self.mark("B1.    grep")
        
            self.text_rest  = re.sub(r"\n====.*","",text_rest,9999)

            if not self.text_rest == "":
                self.text_rest = self.text_rest + insertline
#        self.text_match = re.sub(r"====.*\n","",text_match[0:100],9999) + text_match[100:]
            self.text_match = re.sub(r"====.*\n","",text_match,9999)
            self.mark("B2.    Combine")
            self.pattern = pattern
        
#******************************************************************************

    def xxsync (self,pattern,file0,file,add_string="",ruledir=None):

        self.mark("A. Sync Start")
        self.sort(pattern,file0)
        self.mark("B. Sorting")
        
        id0 = self.make_id(self.text_match)
        
        self.text_match.replace(" ","")
        id0 = str( base64.urlsafe_b64encode(hashlib.md5( id0.encode("utf-8")).digest()),"ascii" )[0:6]
        self.mark("D. Compute db id")

#        expr = '"^20[0123456789][0123456789][0123456789][0123456789][0123456789][0123456789] " '
        if os.path.isfile(file):

            text    = open(file)
            keyline = text.readline()
            text    = text.read()

            if not re.search(r"\S",text):
            
                key0 = ""
                key  = ""
                id   = ""

            else:

                m = re.search(r"\((\S\S\S\S\S\S)(\S\S\S\S\S\S)\)",keyline)
                if m:
                    key0  = m.group(1)
                    key   = m.group(2)
                else:
                    key0  = id0
                    key   = ""
                    text  = keyline + "\n" + text

                id = text + add_string
                id = str( base64.urlsafe_b64encode(hashlib.md5(  id.encode("utf-8")).digest()),"ascii" )[0:6]

        else:

            key0 = ""
            key  = ""
            id   = ""

        self.mark("E. " + " ".join([id0,key0,id,key]))
        self.ukto     = ""
        self.last_sum = ""
        
        if id0 == key0:
            if id == key:
                open(file0,"w").write(self.text_rest + self.text_match)
                erg = 1   
            else:
                self.mark("F. Update database")
                if ruledir and os.path.isdir(ruledir):

                    dir9  = os.path.relpath(".",ruledir)
                    file1 = re.sub(r"^(.*)[\\\/](.*)$","\\2",file)
                    os.chdir(ruledir)
                    os.popen("python3 rule.py " + file1).read()
                    os.chdir(dir9)
                    self.mark("F1. ... apply rule.py")

                    text    = open(file).read()
                    text    = "\n" + self.format_kto(text.split("\n")[1:]).strip() + "\n"

#                    open(file,"w").write(text)
                    self.mark("F2. ... format kto")
                    id = text + add_string
                    id = str( base64.urlsafe_b64encode(hashlib.md5(  id.encode("utf-8")).digest()),"ascii" )[0:6]
                    self.mark("G. Compute kto id")
                text0 = os.popen("grep ^20 " + file).read()
#                id = text + add_string
#                id = str( base64.urlsafe_b64encode(hashlib.md5(  id.encode("utf-8")).digest()),"ascii" )[0:6]
                id0 = text0.replace(" ","")
                id0 = str( base64.urlsafe_b64encode(hashlib.md5( id0.encode("utf-8")).digest()),"ascii" )[0:6]
                self.mark("H. Compute db id")
                open(file,"w").write(("%-25s" % self.ukto) + "  " + "(" + id0 + id + ")   " +
                                  pattern + " " + self.last_sum + "\n" + text)
                open(file0,"w").write(self.text_rest + text0)
                erg = 2   
        else:
            if id == key:
                self.mark("E. Update ktofile")
                if ruledir and os.path.isdir(ruledir):
                    self.text_match = self.format_kto(self.text_match.split("\n")[:]).strip() + "\n"
                    self.mark("F. Format kto")
                    id0 = self.text_match.replace(" ","")
                    id0 = str( base64.urlsafe_b64encode(hashlib.md5( id0.encode("utf-8")).digest()),"ascii" )[0:6]
                id = "\n" + self.text_match + add_string
                id = str( base64.urlsafe_b64encode(hashlib.md5(  id.encode("utf-8")).digest()),"ascii" )[0:6]
                self.mark("G. Compute kto id")
                open(file,"w").write(("%-25s" % self.ukto) + "  " + "(" + id0 + id + ")   " +
                                  pattern + " " + self.last_sum + "\n\n"+self.text_match)
                open(file0,"w").write(self.text_rest + self.text_match)
                erg = 3   
            else:
                open(file0,"w").write(self.text_rest + self.text_match)
                print("CONFLICT")
                erg = 4
                
        return(erg)   


#******************************************************************************

    def xxsync (self,pattern,file0,file,add_string="",ruledir=None):

        self.parse_pattern(pattern)
        self.mark("A. Sync Start")
        self.kto_match(file0)
        self.mark("B. Find matching lines")
        
        id0 = self.make_id(1,self.text_match)
        self.mark("C. Compute db id")

        if os.path.isfile(file):

            text    = open(file)
            keyline = text.readline()
            text    = text.read()

            if not re.search(r"\S",text):
            
                key0 = ""
                key  = ""
                id   = ""

            else:

                m = re.search(r"\((\S\S\S\S\S\S)(\S\S\S\S\S\S)\)",keyline)
                if m:
                    key0  = m.group(1)
                    key   = m.group(2)
                else:
                    key0  = id0
                    key   = ""
                    text  = keyline + "\n" + text

                id = self.make_id(0,text+add_string)

        else:

            key0 = ""
            key  = ""
            id   = ""

        self.mark("D. " + " ".join([id0,key0,id,key]))
        self.ukto     = ""
        self.last_sum = ""
        
        if id0 == key0:
            if id == key:
#                open(file0,"w").write(self.text_rest + self.text_match)
                erg = 1   
            else:
                self.mark("E. Update database")
                if ruledir and os.path.isdir(ruledir):

                    dir9  = os.path.relpath(".",ruledir)
                    file1 = re.sub(r"^(.*)[\\\/](.*)$","\\2",file)
                    os.chdir(ruledir)
                    os.popen("python3 rule.py " + file1).read()
                    os.chdir(dir9)
                    self.mark("F. ... apply rule.py")

                    text    = open(file).read()
                    text    = "\n" + self.format_kto(text.split("\n")[1:]).strip() + "\n"

#                    open(file,"w").write(text)
                    self.mark("G. ... format kto")
                    id = self.make_id(0,text+add_string)
                    self.mark("H. Compute kto id")
#                text0 = os.popen("grep ^20 " + file + " | grep -o -P '\S+'").read()
                text0 = os.popen("grep -P '^\d\d\d\d\d\d\d\d ' " + file).read()
                id0   = self.make_id(1,text0)
                self.mark("I. Compute db id")
                open(file,"w").write(("%-25s" % self.ukto) + "  " + "(" + id0 + id + ")   " +
                                  pattern + " " + self.last_sum + "\n" + text)
                self.kto_rest(file0)
                open(file0,"w").write(self.text_rest + text0)
                erg = 2   
        else:
            if id == key:
                self.mark("E. Update ktofile")
                if ruledir and os.path.isdir(ruledir):
                    self.text_match = self.format_kto(self.text_match.split("\n")[:]).strip() + "\n"
                    self.mark("F. Format kto")
                    id0 = self.make_id(1,self.text_match)
                id = self.make_id(0,"\n"+self.text_match+add_string)
                self.mark("G. Compute kto id")
                open(file,"w").write(("%-25s" % self.ukto) + "  " + "(" + id0 + id + ")   " +
                                  pattern + " " + self.last_sum + "\n\n"+self.text_match)
#                open(file0,"w").write(self.text_rest + self.text_match)
                erg = 3   
            else:
#                open(file0,"w").write(self.text_rest + self.text_match)
                print("CONFLICT")
                erg = 4
                
        return(erg)   

#******************************************************************************

if __name__ == "__main__":
    
    vars()[sys.argv[1]](*sys.argv[2:])

bypass 1.0, Devloped By El Moujahidin (the source has been moved and devloped)
Email: contact@elmoujehidin.net bypass 1.0, Devloped By El Moujahidin (the source has been moved and devloped) Email: contact@elmoujehidin.net