From 49777a9caafc4c60b9ce3f6733e8c4ff9edfa509 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Fri, 12 Jul 2019 16:12:44 +0200 Subject: [PATCH] Cleanup the bull**** --- src/CNIRevelator.py | 7 +- src/globs.py | 3 +- src/logger.py | 5 +- src/main.py | 452 +++++++------------------------------------- 4 files changed, 82 insertions(+), 385 deletions(-) diff --git a/src/CNIRevelator.py b/src/CNIRevelator.py index 3570502..0ca7543 100644 --- a/src/CNIRevelator.py +++ b/src/CNIRevelator.py @@ -45,7 +45,7 @@ logfile = logger.logCur def main(): logfile.printdbg('*** CNIRevelator LOGFILE. Hello World ! ***') - mainw = mainWindow(logfile.logger) + mainw = mainWindow() try: os.environ['PATH'] = globs.CNIRFolder + '\\Tesseract-OCR4\\' @@ -60,7 +60,7 @@ def main(): mainw.logOnTerm('\n\nEntrez la première ligne de MRZ svp \n') if globs.CNIRNewVersion: - showinfo('Changelog : résumé de mise à jour', ('Version du logiciel : CNIRevelator ' + globs.verstring_full + '\n\n' + globs.changelog), parent=mainWindow) + showinfo('Changelog : résumé de mise à jour', ('Version du logiciel : CNIRevelator ' + globs.verstring_full + '\n\n' + globs.changelog), parent=mainw) logfile.printdbg('main() : **** Launching App_main() ****') mainw.mainloop() logfile.printdbg('main() : **** Ending App_main() ****') @@ -95,4 +95,5 @@ try: main() except Exception as e: traceback.print_exc(file=sys.stdout) - updater.exitProcess(1) \ No newline at end of file + +updater.exitProcess(0) \ No newline at end of file diff --git a/src/globs.py b/src/globs.py index eecfb29..eebde99 100644 --- a/src/globs.py +++ b/src/globs.py @@ -28,6 +28,7 @@ import os version = [3, 0, 0] verstring_full = "{}.{}.{}".format(version[0], version[1], version[2]) verstring = "{}.{}".format(version[0], version[1]) +debug = True changelog = "Mise-à-jour majeure avec corrections suivantes :\n- Renouvellement de la signature numérique de l'exécutable\n- Amélioration de présentation du log en cas d'erreur\n- Refonte totale du code source et désobfuscation\n- Téléchargements en HTTPS fiables avec somme de contrôle" @@ -36,7 +37,7 @@ CNIRFolder = os.getcwd() CNIRLColor = "#006699" CNIRName = "CNIRevelator {}".format(verstring) CNIRCryptoKey = '82Xh!efX3#@P~2eG' -CNIRNewVersion = False +CNIRNewVersion = True CNIRConfig = CNIRFolder + '\\config\\conf.ig' CNIRErrLog = CNIRFolder + '\\logs\\error.log' diff --git a/src/logger.py b/src/logger.py index 91f2362..d4556f1 100644 --- a/src/logger.py +++ b/src/logger.py @@ -59,7 +59,10 @@ class NewLoggingSystem: self.logger = logger self.printerr = logger.error - self.printdbg = logger.info + + def printdbg(self, text): + if globs.debug: + self.logger.info(text) def close(self): logging.shutdown() diff --git a/src/main.py b/src/main.py index 78b1270..cf109be 100644 --- a/src/main.py +++ b/src/main.py @@ -29,19 +29,25 @@ from tkinter import * from tkinter.messagebox import * from tkinter import filedialog from tkinter import ttk +import threading +from datetime import datetime +import logger # logger.py import mrz # mrz.py -from image import CanvasImage # image.py import globs # globs.py +import pytesseract # pytesseract.py +from image import * # image.py + +# Global handler +logfile = logger.logCur class mainWindow(Tk): - def __init__(self, logger): + def __init__(self): Tk.__init__(self) - self.initialize(logger) + self.initialize() - def initialize(self, logger): - self.logger = logger + def initialize(self): self.PILE_ETAT = [] self.MRZCHAR = '' self.varnum = 10 @@ -49,15 +55,20 @@ class mainWindow(Tk): for type in mrz.TYPES: self.Score += [0] + # Get the screen size ws = self.winfo_screenwidth() hs = self.winfo_screenheight() - self.logger.info('mainWindow() : Launching main window with resolution' + str(ws) + 'x' + str(hs)) + logfile.printdbg('mainWindow() : Launching main window with resolution' + str(ws) + 'x' + str(hs)) self.grid() + + # Configuring the size of each part of the window self.grid_columnconfigure(0, weight=1, minsize=(ws / 2 * 0.3333333333333333)) self.grid_columnconfigure(1, weight=1, minsize=(ws / 2 * 0.3333333333333333)) self.grid_columnconfigure(2, weight=1, minsize=(ws / 2 * 0.3333333333333333)) self.grid_rowconfigure(0, weight=1, minsize=(hs / 2 * 0.5)) self.grid_rowconfigure(1, weight=1, minsize=(hs / 2 * 0.5)) + + # Prepare the data sections self.lecteur_ci = ttk.Labelframe(self, text="Informations sur la pièce d'identité") self.lecteur_ci.grid_columnconfigure(0, weight=1) self.lecteur_ci.grid_columnconfigure(1, weight=1) @@ -70,6 +81,8 @@ class mainWindow(Tk): self.lecteur_ci.grid_rowconfigure(3, weight=1) self.lecteur_ci.grid_rowconfigure(4, weight=1) self.lecteur_ci.grid_rowconfigure(5, weight=1) + + # Fill the data sections ttk.Label((self.lecteur_ci), text='Nom : ').grid(column=0, row=1, padx=5, pady=5) self.nom = ttk.Label((self.lecteur_ci), text=' ') self.nom.grid(column=1, row=1, padx=5, pady=5) @@ -100,6 +113,7 @@ class mainWindow(Tk): ttk.Label((self.lecteur_ci), text='Numéro de document : ').grid(column=4, row=5, padx=5, pady=5) self.no = ttk.Label((self.lecteur_ci), text=' ') self.no.grid(column=5, row=5, padx=5, pady=5) + self.nom['text'] = 'Inconnu(e)' self.prenom['text'] = 'Inconnu(e)' self.bdate['text'] = 'Inconnu(e)' @@ -110,12 +124,16 @@ class mainWindow(Tk): self.nat['text'] = 'Inconnu(e)' self.pays['text'] = 'Inconnu(e)' self.indic['text'] = 'Inconnu(e)' + + # The STATUS indicator self.STATUT = ttk.Labelframe(self, text='Statut') self.STATUT.grid_columnconfigure(0, weight=1) self.STATUT.grid_rowconfigure(0, weight=1) self.STATUStxt = Label((self.STATUT), text='', font='Times 24', fg='#FFBF00') self.STATUStxt.grid(column=0, row=0, padx=0, pady=0, sticky='EWNS') self.STATUStxt['text'] = 'EN ATTENTE' + + # The terminal to enter the MRZ self.terminal = ttk.Labelframe(self, text='Terminal de saisie') self.terminal.grid_columnconfigure(0, weight=1) self.terminal.grid_rowconfigure(0, weight=1) @@ -128,6 +146,8 @@ class mainWindow(Tk): vcmd = (self.register(self.entryValidation), '%S', '%P', '%d') self.termentry = Entry((self.termframe), font='Terminal 17', validate='all', validatecommand=vcmd, fg='#121f38', width=44) self.termentry.grid(column=0, row=0, sticky='SEW', padx=5) + + # The monitor that indicates some useful infos self.monitor = ttk.Labelframe(self, text='Moniteur') self.monlog = Text((self.monitor), state='disabled', width=60, height=10, wrap='word') self.monlog.grid(column=0, row=0, sticky='EWNS', padx=5, pady=5) @@ -136,10 +156,15 @@ class mainWindow(Tk): self.monlog['yscrollcommand'] = self.scrollb.set self.monitor.grid_columnconfigure(0, weight=1) self.monitor.grid_rowconfigure(0, weight=1) + + # All the items griding self.lecteur_ci.grid(column=0, row=0, sticky='EWNS', columnspan=2, padx=5, pady=5) self.STATUT.grid(column=2, row=0, sticky='EWNS', columnspan=1, padx=5, pady=5) self.terminal.grid(column=0, row=1, sticky='EWNS', columnspan=2, padx=5, pady=5) self.monitor.grid(column=2, row=1, sticky='EWNS', columnspan=1, padx=5, pady=5) + self.update() + + # What is a window without a menu bar ? menubar = Menu(self) menu1 = Menu(menubar, tearoff=0) menu1.add_command(label='Nouveau', command=(self.newEntry)) @@ -151,13 +176,18 @@ class mainWindow(Tk): menu3.add_command(label='A propos', command=(self.infobox)) menubar.add_cascade(label='Aide', menu=menu3) self.config(menu=menubar) + + # The title self.wm_title(globs.CNIRName) + + # The icon if getattr(sys, 'frozen', False): self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico') else: self.iconbitmap('id-card.ico') + + # Make this window resizable and set her size self.resizable(width=True, height=True) - self.update() self.minsize(self.winfo_width(), self.winfo_height()) w = int(self.winfo_width()) h = int(self.winfo_height()) @@ -166,178 +196,27 @@ class mainWindow(Tk): x = ws / 2 - w / 2 y = hs / 2 - h / 2 self.geometry('%dx%d+%d+%d' % (w, h, x, y)) + + # Some bindings self.termentry.bind('', self.preentryValidation) self.termtext.bind('', self.preentryValidation) self.termentry.bind('', self.onTabPressed) self.update() - self.logger.info('mainWindow() : Initialization successful') + logfile.printdbg('mainWindow() : Initialization successful') def preentryValidation(self, event): - self.logger.debug('preentryValidation() : Entering Validation') - if self.PILE_ETAT != [] and len(self.PILE_ETAT) == 1: - thetext = self.termentry.get() - self.logger.debug('preentryValidation() : PILE_ETAT Satisfy the requisites : ' + str(self.PILE_ETAT)) - n = len(thetext) - champ = mrz.TYPES[self.PILE_ETAT[0]][0] - if not n % champ.find('|') == 0: - self.logger.debug('preentryValidation() : Line not complete, operation aborted') - return 'break' - self.MRZCHAR += thetext - self.termtext['state'] = 'normal' - self.termtext.insert('end', thetext + '\n') - self.termtext['state'] = 'disabled' - self.termentry.delete(0, 'end') - if len(self.MRZCHAR) == champ.find('|'): - self.logOnTerm('Entrez la seconde ligne de la MRZ ou \nappuyez sur Entrée pour terminer.\n') - self.logger.debug('preentryValidation() : First line accepted') - self.MRZCHAR += '|' - else: - if len(self.MRZCHAR) == champ.find('|') * 2 + 1 or len(champ) == champ.find('|') + 1: - self.logOnTerm('\nCalcul des sommes ...\n') - self.logger.info('preentryValidation() : Launching calculSigma() thread') - threading.Thread(target=(self.calculSigma), args=[self.MRZCHAR, self.PILE_ETAT[0]]).start() - else: - if self.PILE_ETAT != []: - if len(self.PILE_ETAT) == 2: - self.MRZCHAR = self.termtext.get('1.0', 'end').replace('\n', '|') - temp = self.termtext.get('1.0', 'end') - self.termtext.delete('1.0', 'end') - self.termtext.insert('1.0', temp) - self.logger.debug('preentryValidation() : PILE_ETAT Satisfy the requisites : ' + str(self.PILE_ETAT)) - n = len(self.MRZCHAR) - champ = mrz.TYPES[self.PILE_ETAT[1]][0] - for char in self.MRZCHAR: - if char not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789<|': - self.logOnTerm('\nSyntaxe erronée, caractère incompatible') - return 'break' - if self.MRZCHAR[(-1)] == '|': - self.MRZCHAR = self.MRZCHAR[:-1] - - if len(self.MRZCHAR) == champ.find('|') * 2 + 1 or len(champ) == champ.find('|') + 1: - self.logger.debug('preentryValidation() : : ' + str(self.PILE_ETAT)) - self.logOnTerm('\nCalcul des sommes ...\n') - self.logger.info('preentryValidation() : Launching calculSigma() thread') - threading.Thread(target=(self.calculSigma), args=[self.MRZCHAR, self.PILE_ETAT[1]]).start() - return 'break' + """ + Function that detects the kind of identity document this is + """ def onTabPressed(self, event): - if self.PILE_ETAT != [] and len(self.PILE_ETAT) == 1: - thetext = self.termentry.get() - n = len(thetext) - champ = mrz.TYPES[self.PILE_ETAT[0]][0] - if len(self.MRZCHAR) <= champ.find('|'): - champ_type = mrz.TYPES[self.PILE_ETAT[0]][1][champ[(n - 1)]].split('|') - self.logger.debug('onTabPressed() : First line detected') - self.logger.debug('onTabPressed() : champ_type[0] : ' + str(champ_type[0])) - self.logger.debug('onTabPressed() : champ : ' + str(champ)) - self.logger.debug('onTabPressed() : champ[n-1] : ' + str(champ[(n - 1)])) - self.logger.debug('onTabPressed() : champ.find(champ[n-1]) : ' + str(champ.find(champ[(n - 1)]))) - nb = int(champ_type[0]) - (n - champ.find(champ[(n - 1)])) - else: - self.logger.debug('onTabPressed() : Second line detected') - champ = champ[champ.find('|') + 1:] - champ_type = mrz.TYPES[self.PILE_ETAT[0]][1][champ[(n - 1)]].split('|') - self.logger.debug('onTabPressed() : champ_type[0] : ' + str(champ_type[0])) - self.logger.debug('onTabPressed() : champ : ' + str(champ)) - self.logger.debug('onTabPressed() : champ[n-1] : ' + str(champ[(n - 1)])) - self.logger.debug('onTabPressed() : champ.find(champ[n-1]) : ' + str(champ.find(champ[(n - 1)]))) - self.logger.debug('onTabPressed() : n : ' + str(n)) - nb = int(champ_type[0]) - (n - champ.find(champ[(n - 1)])) - self.termentry.insert('end', '<' * nb) - self.logger.debug('onTabPressed() : Completing entry with ' + str(nb) + ' characters <') + return 'break' def entryValidation(self, char, entry_value, typemod): - set = False - isValid = True - if typemod == '1': - SUM = 0 - for ch in char: - if ch in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789<': - continue - self.bell() - isValid = False - else: - if typemod == '0': - for ch in char: - if ch in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789<': - continue - self.bell() - isValid = False + # XXX : we must recreate a proper on the fly validation with regex ! - n = len(entry_value) - if (n % self.varnum == 0 or len(char) > 3) and n < 45 and self.PILE_ETAT == []: - for i in range(len(self.Score)): - self.Score[i] = 0 - - for type, t in zip(mrz.TYPES, range(len(mrz.TYPES))): - for e in range(len(entry_value)): - try: - champchartest = type[0][:type[0].find('|')][e] - champchar = type[0][e] - except IndexError: - self.logger.debug('entryValidation() : type : ' + str(t)) - self.logger.debug('entryValidation() : Too short to be ok') - self.Score[t] += -5 - break - else: - self.logger.debug('entryValidation() : type : ' + str(t)) - if len(entry_value) <= type[0].find('|'): - champ_type = type[1][str(champchar)].split('|') - pos = e - type[0].find(champchar) - self.logger.debug('entryValidation() : champ_type[2][pos] : ' + str(champ_type[2][pos])) - self.logger.debug('entryValidation() : champ_type[1] : ' + str(champ_type[1])) - if champ_type[1] == 'CODE': - if champ_type[2][pos] == '*': - self.Score[t] += 0 - else: - if champ_type[2][pos] == entry_value[e]: - self.Score[t] += 1 - self.logger.debug('entryValidation() : +1') - else: - self.Score[t] += -50 - elif champ_type[2][pos] == '*': - self.Score[t] += 1 - self.logger.debug('entryValidation() : +1') - else: - if champ_type[2][pos] == 'A': - if entry_value[e].isalpha(): - self.Score[t] += 1 - self.logger.debug('entryValidation() : +1') - if champ_type[2][pos] == '0': - if entry_value[e].isnumeric(): - self.Score[t] += 1 - self.logger.debug('entryValidation() : +1') - if champ_type[1] == 'CTRL': - if entry_value[e].isnumeric(): - self.Score[t] += 1 - self.logger.debug('entryValidation() : +1') - if champ_type[2][pos] == '&': - if entry_value[e].isalpha() or entry_value[e] == '<': - self.Score[t] += 1 - self.logger.debug('entryValidation() : +1') - self.Score[t] += -1 - continue - - self.logger.debug('entryValidation() : self.Score : ' + str(self.Score)) - m = max(self.Score) - typem = [i for i, j in enumerate(self.Score) if j == m if m > 5] - for h in typem: - self.PILE_ETAT += [h] - - if len(self.PILE_ETAT) > 1: - self.varnum += 3 - self.PILE_ETAT = [] - else: - if len(self.PILE_ETAT) == 1: - TOPOS = mrz.TYPES[self.PILE_ETAT[0]][2] - self.logOnTerm(TOPOS + " détectée !\nAppuyez sur Echap pour compléter les champs avec des '<'\nAppuyez sur Entrée pour terminer.\n") - self.logger.debug('entryValidation() : Detection : ' + str(TOPOS)) - else: - if len(self.PILE_ETAT) == 1: - if len(entry_value) > len(mrz.TYPES[self.PILE_ETAT[0]][0].split('|')[0]): - isValid = False return isValid def logOnTerm(self, text): @@ -347,230 +226,43 @@ class mainWindow(Tk): self.monlog.yview(END) def openingScan(self): - self.initialize(self.logger) - self.update() - path = '' - path = filedialog.askopenfilename(parent=self, title='Ouvrir un scan de CNI...', filetypes=(('TIF files', '*.tif'), - ('TIF files', '*.tiff'), - ('JPEG files', '*.jpg'), - ('JPEG files', '*.jpeg'))) - self.openerrored = False - if path != '': - self.logger.info('openingScan() : Opening file with path ' + str(path)) - im = Image.open(path) - try: - nframe = im.n_frames - except AttributeError: - nframe = 1 - if nframe == 1: - self.mrzdetected = '' - self.mrzdict = {} - try: - opening = OpenScanWin(self, path, 0) - opening.transient(self) - opening.grab_set() - self.wait_window(opening) - except TclError: - pass - except Exception as e: - self.logger.critical('openingScan() : ' + str(e)) - - if self.openerrored == True: - self.logger.error('openingScan() : Incompatible file with path ' + str(path)) - return - self.logger.debug('openingScan() : ' + str(self.mrzdetected)) - else: - if nframe > 1: - self.mrzdetected = '' - self.mrzdict = {} - try: - opening = OpenScanWin(self, path, 1, nframe) - opening.transient(self) - opening.grab_set() - self.wait_window(opening) - except TclError: - pass - except Exception as e: - self.logger.critical('openingScan() : ' + str(e)) - - if self.openerrored == True: - self.logger.critical('openingScan() : Incompatible file with path ' + str(path)) - return - self.logger.debug('openingScan() : ' + str(self.mrzdetected)) - try: - os.remove(globs.CNIREnv + '\\temp.tif') - except IOError: - pass - - else: - raise Exception - mrzsoumisetab = self.mrzdetected.replace(' ', '').split('\n') - for chain in mrzsoumisetab: - self.termentry.insert('end', chain) - if len(chain) >= 5: - self.preentryValidation('') + # OPEN A SCAN def newEntry(self): - self.initialize(self.logger) + self.initialize() self.logOnTerm('\n\nEntrez la première ligne de MRZ svp \n') def infobox(self): Tk().withdraw() - showinfo('A propos du logiciel', ('Version du logiciel : \n' + globs.verstring_full + ' ' + "\nLicence GNU/GPL 2018\n\nAuteur : NeoX_ ; devadmin@neoxgroup.eu\n\nTesseract 4.0 est soumis à l'Apache License 2004\n\n N'hésitez pas à faire part de vos commentaires !"), parent=self) + + showinfo('A propos du logiciel', + ( 'Version du logiciel : CNIRevelator ' + globs.verstring_full + '\n\n' + + "CNIRevelator is free software: you can redistribute it and/or modify " + + "it under the terms of the GNU General Public License as published by " + + "the Free Software Foundation, either version 3 of the License, or " + + "any later version. " + "\n\n" + + "CNIRevelator is distributed in the hope that it will be useful, " + + "but without even the implied warranty of " + + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " + + "GNU General Public License for more details. " + + "\n\n" + + "You should have received a copy of the GNU General Public License " + + "along with CNIRevelator. If not, see . " + + "\n\n" + + "Tesseract 4.0 est soumis à l'Apache License 2004" + + "\n\n" + + "Anaconda 3 est soumis à la licence BSD 2018-2019" + + "\n\n" + + "En cas de problèmes, ouvrez une issue sur le github de CNIRevelator " + + ", ou bien envoyez un mail à neox@os-k.eu!" + ), + + parent=self) def calculSigma(self, MRZtxt, numtype): - CST_BACKGROUND = self['background'] - CTRList = [c for c, v in mrz.TYPES[numtype][1].items() if 'CTRL' in v] - self.logger.info('[calculSigma() thread] : Sigma calculation launched!') - self.logger.debug('[calculSigma() thread] : CTRList = ' + str(CTRList)) - self.Falsitude = 0 - self.logOnTerm('\n') - for i in CTRList: - sumtxt = mrz.TYPES[numtype][1][i] - length = mrz.TYPES[numtype][0].find('|') - index = mrz.TYPES[numtype][0].find(i) - sum_read = MRZtxt[index] - if len(sumtxt.split('|')[2]) == 1: - debut = mrz.TYPES[numtype][0].find(sumtxt.split('|')[2][0]) - sum_calc = mrz.MRZ(MRZtxt[int(debut):index]) - else: - transm_chain = '' - for y in sumtxt.split('|')[2]: - debut = mrz.TYPES[numtype][0].find(y) - fin = debut + int(mrz.TYPES[numtype][1][y].split('|')[0]) - transm_chain += MRZtxt[int(debut):int(fin)] - sum_calc = mrz.MRZ(transm_chain) - if str(sum_read)[0] != str(sum_calc)[0]: - if not (sumtxt.split('|')[1] == 'CTRLF' and str(sum_read)[0] == '<'): - self.Falsitude += 1 - self.logger.debug('[calculSigma() thread] : Falsitude +1, sum errored : ' + str(i)) - self.termtext.tag_add('highLOW', '1.0+' + str(index) + 'c', '1.0+' + str(index + 1) + 'c') - self.termtext.tag_configure('highLOW', background='#760808', relief='raised', foreground='white') - self.termtext.tag_add('highLOWB', '1.0+' + str(index) + 'c', '1.0+' + str(index + 1) + 'c') - self.termtext.tag_configure('highLOWB', background='#04B404', relief='raised', foreground='white') - self.logOnTerm('Somme : Lu ' + str(sum_read) + ' VS calculé ' + str(sum_calc) + '\n') - - NameList = [c for c, v in mrz.TYPES[numtype][1].items() if '|NOM' in v] - SurnameList = [c for c, v in mrz.TYPES[numtype][1].items() if 'PRENOM' in v] - DDateList = [c for c, v in mrz.TYPES[numtype][1].items() if 'DDATE' in v] - BDateList = [c for c, v in mrz.TYPES[numtype][1].items() if 'BDATE' in v] - EDateList = [c for c, v in mrz.TYPES[numtype][1].items() if 'EDATE' in v] - PAYSList = [c for c, v in mrz.TYPES[numtype][1].items() if 'PAYS' in v] - NATList = [c for c, v in mrz.TYPES[numtype][1].items() if 'NAT' in v] - SEXList = [c for c, v in mrz.TYPES[numtype][1].items() if 'SEX' in v] - NOINTList = [c for c, v in mrz.TYPES[numtype][1].items() if 'NOINT' in v] - NOList = [c for c, v in mrz.TYPES[numtype][1].items() if 'NO|' in v] - FACULTList = [c for c, v in mrz.TYPES[numtype][1].items() if 'FACULT' in v] - INDICList = [c for c, v in mrz.TYPES[numtype][1].items() if 'INDIC' in v] - BIGList = [ - NameList, SurnameList, DDateList, BDateList, EDateList, PAYSList, NATList, SEXList, NOList, INDICList, NOINTList] - BIGObj = [ - self.nom, self.prenom, self.ddate, self.bdate, self.edate, self.pays, self.nat, self.sex, self.no, self.indic, self.no] - for i in range(len(BIGList)): - for champ, champnum in zip(BIGList[i], range(len(BIGList[i]))): - debut = mrz.TYPES[numtype][0].find(champ) - fin = debut + int(mrz.TYPES[numtype][1][champ].split('|')[0]) - if BIGObj[i] == self.pays or BIGObj[i] == self.nat: - try: - BIGObj[i]['text'] = mrz.landcode[MRZtxt[int(debut):int(fin)].replace('<', '')] - except KeyError: - self.Falsitude += 1 - self.logOnTerm('Code pays : ' + str(MRZtxt[int(debut):int(fin)]) + ' est inconnu \n') - self.logger.debug('[calculSigma() thread] : Falsitude +1, unknown state') - self.termtext.tag_add('highLOW', '1.0+' + str(debut) + 'c', '1.0+' + str(fin) + 'c') - self.termtext.tag_configure('highLOW', background='#760808', relief='raised', foreground='white') - BIGObj[i]['background'] = '#760808' - BIGObj[i]['foreground'] = 'white' - else: - BIGObj[i]['background'] = CST_BACKGROUND - BIGObj[i]['foreground'] = 'black' - self.termtext.tag_add('highLOWN', '1.0+' + str(debut) + 'c', '1.0+' + str(fin) + 'c') - self.termtext.tag_configure('highLOWN', background='white', relief='raised', foreground='#121f38') - elif BIGObj[i] == self.sex: - try: - BIGObj[i]['text'] = mrz.sexcode[MRZtxt[int(debut):int(fin)]] - except KeyError: - self.Falsitude += 1 - self.logOnTerm('Sexe : ' + str(MRZtxt[int(debut):int(fin)]) + ' est inconnu \n') - self.logger.debug('[calculSigma() thread] : Falsitude +1, unknown state') - self.termtext.tag_add('highLOW', '1.0+' + str(debut) + 'c', '1.0+' + str(fin) + 'c') - self.termtext.tag_configure('highLOW', background='#760808', relief='raised', foreground='white') - BIGObj[i]['background'] = '#760808' - BIGObj[i]['foreground'] = 'white' - else: - BIGObj[i]['background'] = CST_BACKGROUND - BIGObj[i]['foreground'] = 'black' - self.termtext.tag_add('highLOWN', '1.0+' + str(debut) + 'c', '1.0+' + str(fin) + 'c') - self.termtext.tag_configure('highLOWN', background='white', relief='raised', foreground='#121f38') - else: - if BIGObj[i] == self.edate or BIGObj[i] == self.ddate or BIGObj[i] == self.bdate: - txtl = MRZtxt[int(debut):int(fin)].replace('<<<', '').replace('<', ' ') - if len(txtl) < 6: - txtl += '0' * (6 - len(txtl)) - BIGObj[i]['text'] = '{0}/{1}/{2}'.format(txtl[4:], txtl[2:4], txtl[:2]) - if BIGObj[i] == self.edate: - present = datetime.now() - try: - expiration = datetime(2000 + int(txtl[:2]), int(txtl[2:4]), int(txtl[4:])) - except ValueError: - BIGObj[i]['background'] = '#760808' - BIGObj[i]['foreground'] = 'white' - self.Falsitude += 1 - self.logOnTerm('Date : ' + str(BIGObj[i]['text']) + ' est invalide \n') - self.logger.debug('[calculSigma() thread] : Falsitude +1, invalid expiration date') - self.termtext.tag_add('highLOW', '1.0+' + str(debut) + 'c', '1.0+' + str(fin) + 'c') - self.termtext.tag_configure('highLOW', background='#760808', relief='raised', foreground='white') - else: - BIGObj[i]['background'] = CST_BACKGROUND - BIGObj[i]['foreground'] = 'black' - self.termtext.tag_add('highLOWN', '1.0+' + str(debut) + 'c', '1.0+' + str(fin) + 'c') - self.termtext.tag_configure('highLOWN', background='white', relief='raised', foreground='#121f38') - if expiration < present: - BIGObj[i]['background'] = '#e67300' - BIGObj[i]['foreground'] = 'white' - self.termtext.tag_add('highLOWN', '1.0+' + str(debut) + 'c', '1.0+' + str(fin) + 'c') - self.termtext.tag_configure('highLOWN', background='white', relief='raised', foreground='#121f38') - else: - BIGObj[i]['background'] = CST_BACKGROUND - BIGObj[i]['foreground'] = 'black' - else: - try: - if int(txtl[4:]) == 0: - verif = datetime(2000 + int(txtl[:2]), int(txtl[2:4]), 1) - else: - verif = datetime(2000 + int(txtl[:2]), int(txtl[2:4]), int(txtl[4:])) - except ValueError: - BIGObj[i]['background'] = '#760808' - BIGObj[i]['foreground'] = 'white' - self.Falsitude += 1 - self.logOnTerm('Date : ' + str(BIGObj[i]['text']) + ' est invalide \n') - self.logger.debug('[calculSigma() thread] : Falsitude +1, invalid datetime') - self.termtext.tag_add('highLOW', '1.0+' + str(debut) + 'c', '1.0+' + str(fin) + 'c') - self.termtext.tag_configure('highLOW', background='#760808', relief='raised', foreground='white') - else: - BIGObj[i]['background'] = CST_BACKGROUND - BIGObj[i]['foreground'] = 'black' - self.termtext.tag_add('highLOWN', '1.0+' + str(debut) + 'c', '1.0+' + str(fin) + 'c') - self.termtext.tag_configure('highLOWN', background=CST_BACKGROUND, relief='raised', foreground='#121f38') - else: - if champnum == 0: - BIGObj[i]['text'] = MRZtxt[int(debut):int(fin)].replace('<<<', '').replace('<', ' ') - else: - BIGObj[i]['text'] += MRZtxt[int(debut):int(fin)].replace('<<<', '').replace('<', ' ') - - if self.Falsitude == 0: - self.STATUStxt['text'] = 'CONFORME' - self.STATUStxt['fg'] = '#04B404' - self.logger.debug('[calculSigma() thread] : Conforme !') - else: - self.STATUStxt['text'] = 'NON CONFORME' - self.STATUStxt['fg'] = '#760808' - self.logger.debug('[calculSigma() thread] : Non conforme !') - self.logOnTerm('** Score de non conformité : ' + str(self.Falsitude) + '**\n') - self.termtext['state'] = 'normal' - self.PILE_ETAT = [self.Falsitude, numtype] + # CALCUL DE TOUTES LES SOMMES DE LA CARTE CONFORMEMENT A SON TYPE class OpenScan(ttk.Frame):