1
0
mirror of https://gitlab.os-k.eu/neox/CNIRevelator.git synced 2023-08-25 14:03:10 +02:00

Finished detection, obtain a working sum computation

This commit is contained in:
Adrien Bourmault 2019-07-31 17:08:15 +02:00 committed by GitHub
parent ea3bd9fb80
commit c1f5b92026
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 371 additions and 144 deletions

View File

@ -23,7 +23,6 @@
********************************************************************************
"""
import hashlib
import base64, hashlib
import os
from pypac import PACSession
@ -195,11 +194,11 @@ class newdownload:
fh.write(chunk)
self.count = os.path.getsize(self.destinationFile)
Percent = int(self.count / self.filesize * 100)
Percent = self.count / self.filesize * 100
launcherWindow.progressBar.stop()
launcherWindow.progressBar.configure(mode='determinate', value=(int(Percent)), maximum=100)
launcherWindow.printmsg('Downloading {}'.format(reducedFilename) + ' : ' + str((Percent)) + ' %')
launcherWindow.printmsg('Downloading {}'.format(reducedFilename) + ' : {:4.2f} %'.format(Percent))
launcherWindow.progressBar.configure(mode='indeterminate', value=0, maximum=20)
launcherWindow.progressBar.start()

View File

@ -32,7 +32,7 @@ import logger # logger.py
import globs # globs.py
controlKeys = ["Return", "Right", "Left", "Up", "Down", "Home", "End", "Delete", "BackSpace", "Inser", "Shift_L", "Shift_R", "Control_R", "Control_L"]
controlKeys = ["Right", "Left", "Up", "Down", "Home", "End", "Delete", "BackSpace", "Inser", "Shift_L", "Shift_R", "Control_R", "Control_L"]
class DocumentAsk(Toplevel):
@ -205,6 +205,117 @@ class OpenScanWin(Toplevel):
self.parent = parent
app = OpenScan(self, file, type, nframe)
class OpenScan(ttk.Frame):
def __init__(self, mainframe, fileorig, type, nframe=1, pagenum=0, file=None):
""" Initialize the main Frame """
if file == None:
file = fileorig
self.file = file
self.fileorig = fileorig
self.nframe = nframe
self.pagenum = pagenum
self.parent = mainframe.parent
ttk.Frame.__init__(self, master=mainframe)
self.master.title('Ouvrir un scan... (Utilisez la roulette pour zoomer, clic gauche pour déplacer et clic droit pour sélectionner la MRZ)')
self.master.resizable(width=False, height=False)
hs = self.winfo_screenheight()
w = int(self.winfo_screenheight() / 1.5)
h = int(self.winfo_screenheight() / 2)
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
x = ws / 2 - w / 2
y = hs / 2 - h / 2
self.master.geometry('%dx%d+%d+%d' % (w, h, x, y))
if getattr(sys, 'frozen', False):
self.master.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
self.master.iconbitmap('id-card.ico')
self.master.rowconfigure(0, weight=1)
self.master.columnconfigure(0, weight=1)
self.cadre = CanvasImage(self.master, self.file, type)
self.cadre.grid(row=0, column=0)
self.master.menubar = Menu(self.master)
if type == 1:
self.master.menubar.add_command(label='Page précédente', command=(self.pagep))
self.master.menubar.add_command(label='Pivoter -90°', command=(self.cadre.rotatemm))
self.master.menubar.add_command(label='Pivoter -1°', command=(self.cadre.rotatem))
self.master.menubar.add_command(label='Pivoter +1°', command=(self.cadre.rotatep))
self.master.menubar.add_command(label='Pivoter +90°', command=(self.cadre.rotatepp))
if type == 1:
self.master.menubar.add_command(label='Page suivante', command=(self.pages))
self.master.config(menu=(self.master.menubar))
self.cadre.canvas.bind('<ButtonPress-3>', self.motionprep)
self.cadre.canvas.bind('<B3-Motion>', self.motionize)
self.cadre.canvas.bind('<ButtonRelease-3>', self.motionend)
def pages(self):
if self.pagenum + 1 < self.nframe:
im = Image.open(self.fileorig)
im.seek(self.pagenum + 1)
newpath = globs.CNIREnv + '\\temp' + str(random.randint(11111, 99999)) + '.tif'
im.save(newpath)
im.close()
self.cadre.destroy()
self.__init__(self.master, self.fileorig, 1, self.nframe, self.pagenum + 1, newpath)
def pagep(self):
if self.pagenum - 1 >= 0:
im = Image.open(self.fileorig)
im.seek(self.pagenum - 1)
newpath = globs.CNIREnv + '\\temp' + str(random.randint(11111, 99999)) + '.tif'
im.save(newpath)
im.close()
self.cadre.destroy()
self.__init__(self.master, self.fileorig, 1, self.nframe, self.pagenum - 1, newpath)
def motionprep(self, event):
if hasattr(self, 'rect'):
self.begx = event.x
self.begy = event.y
self.ix = self.cadre.canvas.canvasx(event.x)
self.iy = self.cadre.canvas.canvasy(event.y)
self.cadre.canvas.coords(self.rect, self.cadre.canvas.canvasx(event.x), self.cadre.canvas.canvasy(event.y), self.ix, self.iy)
else:
self.begx = event.x
self.begy = event.y
self.ix = self.cadre.canvas.canvasx(event.x)
self.iy = self.cadre.canvas.canvasy(event.y)
self.rect = self.cadre.canvas.create_rectangle((self.cadre.canvas.canvasx(event.x)), (self.cadre.canvas.canvasy(event.y)), (self.ix), (self.iy), outline='red')
def motionize(self, event):
event.x
event.y
self.cadre.canvas.coords(self.rect, self.ix, self.iy, self.cadre.canvas.canvasx(event.x), self.cadre.canvas.canvasy(event.y))
def motionend(self, event):
self.endx = event.x
self.endy = event.y
self.imtotreat = self.cadre.resizedim.crop((min(self.begx, self.endx), min(self.begy, self.endy), max(self.endx, self.begx), max(self.endy, self.begy)))
im = self.imtotreat
import CNI_pytesseract as pytesseract
try:
os.environ['PATH'] = globs.CNIREnv + '\\Tesseract-OCR4\\'
os.environ['TESSDATA_PREFIX'] = globs.CNIREnv + '\\Tesseract-OCR4\\tessdata'
self.text = pytesseract.image_to_string(im, lang='ocrb', boxes=False, config='--psm 6 --oem 0 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890<')
except pytesseract.TesseractNotFoundError as e:
try:
os.remove(globs.CNIREnv + '\\Tesseract-OCR4\\*.*')
except Exception:
pass
showerror('Erreur de module OCR', ('Le module OCR localisé en ' + str(os.environ['PATH']) + 'est introuvable. Il sera réinstallé à la prochaine exécution'), parent=self)
except pytesseract.TesseractError as e:
pass
self.master.success = False
dialogconf = OpenScanDialog(self.master, self.text)
dialogconf.transient(self)
dialogconf.grab_set()
self.wait_window(dialogconf)
if self.master.success:
self.master.destroy()
## Global Handler
launcherWindowCur = LauncherWindow()

View File

@ -57,7 +57,7 @@ class mainWindow(Tk):
# Get the screen size
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
logfile.printdbg('mainWindow() : Launching main window with resolution' + str(ws) + 'x' + str(hs))
logfile.printdbg('Launching main window with resolution' + str(ws) + 'x' + str(hs))
self.grid()
# Configuring the size of each part of the window
@ -65,7 +65,8 @@ class mainWindow(Tk):
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))
self.grid_rowconfigure(1, weight=1, minsize=(hs / 2 * 0.10))
self.grid_rowconfigure(2, weight=1, minsize=(hs / 2 * 0.35))
# Prepare the data sections
self.lecteur_ci = ttk.Labelframe(self, text="Informations sur la pièce d'identité")
@ -133,15 +134,40 @@ class mainWindow(Tk):
self.STATUStxt['text'] = 'EN ATTENTE'
# The terminal to enter the MRZ
self.terminal = ttk.Labelframe(self, text='Terminal de saisie')
self.terminal = ttk.Labelframe(self, text='Terminal de saisie de MRZ complète')
self.terminal.grid_columnconfigure(0, weight=1)
self.terminal.grid_rowconfigure(0, weight=1)
self.termframe = Frame(self.terminal)
self.termframe.grid(column=0, row=0, sticky='EW')
self.termframe.grid_columnconfigure(0, weight=1)
self.termframe.grid_rowconfigure(0, weight=1)
self.termguide = Label((self.termframe), text='', font='Terminal 17', fg='#006699')
self.termguide.grid(column=0, row=0, padx=5, pady=0, sticky='NW')
self.termguide['text'] = '0 |5 |10 |15 |20 |25 |30 |35 |40 |45'
self.termtext = Text((self.termframe), state='normal', width=60, height=4, wrap='none', font='Terminal 17', fg='#121f38')
self.termtext.grid(column=0, row=0, sticky='NEW', padx=5)
self.termtext.grid(column=0, row=0, sticky='SW', padx=5, pady=25)
# Speed Entry Zone for 731
self.terminal2 = ttk.Labelframe(self, text='Terminal de saisie rapide (731)')
self.terminal2.grid_columnconfigure(0, weight=1)
self.terminal2.grid_rowconfigure(0, weight=1)
self.speed731 = Frame(self.terminal2)
self.speed731.grid(column=0, row=0, sticky='EW')
self.speed731.grid_columnconfigure(0, weight=1)
self.speed731.grid_columnconfigure(1, weight=1)
self.speed731.grid_columnconfigure(2, weight=1)
self.speed731.grid_columnconfigure(3, weight=1)
self.speed731.grid_columnconfigure(4, weight=1)
self.speed731.grid_columnconfigure(5, weight=1)
self.speed731.grid_columnconfigure(6, weight=1)
self.speed731.grid_columnconfigure(7, weight=1)
self.speed731.grid_columnconfigure(8, weight=1)
self.speed731.grid_columnconfigure(9, weight=1)
self.speed731.grid_rowconfigure(0, weight=1)
self.speed731text = Entry(self.speed731, font='Terminal 14')
self.speed731text.grid(column=0, row=0, sticky='NEW', padx=5)
self.speedResult = Text((self.speed731), state='disabled', width=1, height=1, wrap='none', font='Terminal 14')
self.speedResult.grid(column=2, row=0, sticky='NEW')
# The monitor that indicates some useful infos
self.monitor = ttk.Labelframe(self, text='Moniteur')
@ -156,8 +182,9 @@ class mainWindow(Tk):
# 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.terminal.grid(column=0, row=2, sticky='EWNS', columnspan=2, padx=5, pady=5)
self.terminal2.grid(column=0, row=1, sticky='EWNS', columnspan=2, padx=5, pady=5)
self.monitor.grid(column=2, row=1, sticky='EWNS', columnspan=1, rowspan=2, padx=5, pady=5)
self.update()
# What is a window without a menu bar ?
@ -169,7 +196,8 @@ class mainWindow(Tk):
menu1.add_command(label='Quitter', command=(self.destroy))
menubar.add_cascade(label='Fichier', menu=menu1)
menu3 = Menu(menubar, tearoff=0)
menu3.add_command(label='A propos', command=(self.infobox))
menu3.add_command(label='Commandes au clavier', command=(self.helpbox))
menu3.add_command(label='A propos de CNIRevelator', command=(self.infobox))
menubar.add_cascade(label='Aide', menu=menu3)
self.config(menu=menubar)
@ -196,12 +224,10 @@ class mainWindow(Tk):
# Some bindings
self.termtext.bind('<Key>', self.entryValidation)
self.termtext.bind('<<Paste>>', self.pasteValidation)
self.speed731text.bind('<Return>', self.speedValidation)
self.update()
logfile.printdbg('Initialization successful')
def onTabPressed(self, event):
return 'break'
def stringValidation(self):
# analysis
# If we must decide the type of the document
@ -225,16 +251,35 @@ class mainWindow(Tk):
self.logOnTerm("Document detecté : {}".format(candidates[0][2]))
self.mrzDecided = candidates[0]
else:
print("LEN mrzChar {} VS {}".format(len(self.mrzChar) - 2, len(self.mrzDecided[0][0])))
# break the line
if len(self.mrzChar) - 2 == len(self.mrzDecided[0][0]):
if (len(self.mrzChar) - 2 >= len(self.mrzDecided[0][0])) and ("\n" not in self.mrzChar[:-1]):
# In case of there is no second line
if len(self.mrzDecided[0][1]) == 0:
self.mrzChar = self.termtext.get("1.0", "end")[:-2]
self.termtext.delete("1.0","end")
self.termtext.insert("1.0", self.mrzChar)
self.nope = True
else:
# In case of there is a second line
self.mrzChar = self.termtext.get("1.0", "end")[:-1] + '\n'
self.termtext.delete("1.0","end")
self.termtext.insert("1.0", self.mrzChar)
self.nope = True
# stop when limit reached
elif (len(self.mrzChar) - 3 >= 2 * len(self.mrzDecided[0][0])):
self.mrzChar = self.termtext.get("1.0", "end")[:-2]
self.termtext.delete("1.0","end")
self.termtext.insert("1.0", self.mrzChar)
# compute the control sum if needed
self.computeSigma()
def entryValidation(self, event):
"""
On the fly validation with regex
"""
print("go")
controlled = False
# verifying that there is no Ctrl-C/Ctrl-V and others
@ -245,6 +290,29 @@ class mainWindow(Tk):
event.keysym == "y" ):
controlled = True
if event.keysym == "Tab":
if self.mrzDecided:
controlled = True
self.mrzChar = self.termtext.get("1.0", "end")[:-1]
# the regex
regex = re.compile("[^A-Z0-9<]")
code = re.sub(regex, '', self.mrzChar)
position = self.termtext.index(INSERT).split(".")
pos = (int(position[0]) - 1) * len(self.mrzDecided[0][0]) + (int(position[1]) - 1)
number = mrz.completeDocField(self.mrzDecided, code, pos) - 1
if number == 0:
return "break"
self.mrzChar = self.termtext.get("1.0", "end")[:-1] + "<"*number
self.termtext.delete("1.0","end")
self.termtext.insert("1.0", self.mrzChar)
self.termtext.mark_set("insert", "%d.%d" % (int(position[0]), int(position[1]) + number))
return "break"
# If not a control char
if not controlled and not event.keysym in ihm.controlKeys:
# the regex
@ -253,14 +321,11 @@ class mainWindow(Tk):
if not regex.fullmatch(event.char):
self.logOnTerm("Caractère non accepté !\n")
return "break"
# Adds the entry
self.mrzChar = self.termtext.get("1.0", "end")[:-1] + event.char + '\n'
self.stringValidation()
# validation of the mrz string
self.stringValidation()
def pasteValidation(self, event):
"""
@ -286,6 +351,13 @@ class mainWindow(Tk):
return "break"
def speedValidation(self, event):
"""
Computation of the speed entry
"""
char = self.speed731text.get()
self.speedResultPrint(str(mrz.computeControlSum(char)))
return "break"
def logOnTerm(self, text):
self.monlog['state'] = 'normal'
@ -293,6 +365,13 @@ class mainWindow(Tk):
self.monlog['state'] = 'disabled'
self.monlog.yview(END)
def speedResultPrint(self, text):
self.speedResult['state'] = 'normal'
self.speedResult.delete("1.0", 'end')
self.speedResult.insert('end', text)
self.speedResult['state'] = 'disabled'
def openingScan(self):
pass
# OPEN A SCAN
@ -304,142 +383,80 @@ class mainWindow(Tk):
def infobox(self):
Tk().withdraw()
showinfo('A propos du logiciel',
showinfo('A propos de CNIRevelator',
( '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. " +
"CNIRevelator est un logiciel libre : vous avez le droit de le modifier et/ou le distribuer " +
"dans les termes de la GNU General Public License telle que publiée par " +
"la Free Software Foundation, dans sa version 3 ou " +
"ultérieure. " + "\n\n" +
"CNIRevelator est distribué dans l'espoir d'être utile, sans toutefois " +
"impliquer une quelconque garantie de " +
"QUALITÉ MARCHANDE ou APTITUDE À UN USAGE PARTICULIER. Référez vous à la " +
"GNU General Public License pour plus de détails à ce sujet. " +
"\n\n" +
"You should have received a copy of the GNU General Public License " +
"along with CNIRevelator. If not, see <https://www.gnu.org/licenses/>. " +
"Vous devriez avoir reçu une copie de la GNU General Public License " +
"avec CNIRevelator. Si cela n'est pas le cas, jetez un oeil à '<https://www.gnu.org/licenses/>. " +
"\n\n" +
"Tesseract 4.0 est soumis à l'Apache License 2004" +
"Le module d'OCR Tesseract 4.0 est soumis à l'Apache License 2004" +
"\n\n" +
"Anaconda 3 est soumis à la licence BSD 2018-2019" +
"Les bibliothèques python et l'environnement Anaconda 3 sont soumis à la licence BSD 2018-2019" +
"\n\n" +
"En cas de problèmes, ouvrez une issue sur le github de CNIRevelator " +
"<https://github.com/neox95/CNIRevelator>, ou bien envoyez un mail à neox@os-k.eu!"
"Le code source de ce programme est disponible sur Github à l'adresse <https://github.com/neox95/CNIRevelator>.\n" +
" En cas de problèmes ou demande particulière, ouvrez-y une issue ou bien envoyez un mail à neox@os-k.eu !"
),
parent=self)
def calculSigma(self, MRZtxt, numtype):
pass
# CALCUL DE TOUTES LES SOMMES DE LA CARTE CONFORMEMENT A SON TYPE
def helpbox(self):
Tk().withdraw()
showinfo('Aide sur les contrôles au clavier',
( '' + '\n\n' +
"In construction"
),
parent=self)
# XXX
def computeSigma(self):
# the regex
regex = re.compile("[^A-Z0-9<]")
code = re.sub(regex, '', self.mrzChar)
allSums = mrz.computeAllControlSum(self.mrzDecided, code)
print("Code : {} | Sums : {}".format(code, allSums))
class OpenScan(ttk.Frame):
def __init__(self, mainframe, fileorig, type, nframe=1, pagenum=0, file=None):
""" Initialize the main Frame """
if file == None:
file = fileorig
self.file = file
self.fileorig = fileorig
self.nframe = nframe
self.pagenum = pagenum
self.parent = mainframe.parent
ttk.Frame.__init__(self, master=mainframe)
self.master.title('Ouvrir un scan... (Utilisez la roulette pour zoomer, clic gauche pour déplacer et clic droit pour sélectionner la MRZ)')
self.master.resizable(width=False, height=False)
hs = self.winfo_screenheight()
w = int(self.winfo_screenheight() / 1.5)
h = int(self.winfo_screenheight() / 2)
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
x = ws / 2 - w / 2
y = hs / 2 - h / 2
self.master.geometry('%dx%d+%d+%d' % (w, h, x, y))
if getattr(sys, 'frozen', False):
self.master.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
self.master.iconbitmap('id-card.ico')
self.master.rowconfigure(0, weight=1)
self.master.columnconfigure(0, weight=1)
self.cadre = CanvasImage(self.master, self.file, type)
self.cadre.grid(row=0, column=0)
self.master.menubar = Menu(self.master)
if type == 1:
self.master.menubar.add_command(label='Page précédente', command=(self.pagep))
self.master.menubar.add_command(label='Pivoter -90°', command=(self.cadre.rotatemm))
self.master.menubar.add_command(label='Pivoter -1°', command=(self.cadre.rotatem))
self.master.menubar.add_command(label='Pivoter +1°', command=(self.cadre.rotatep))
self.master.menubar.add_command(label='Pivoter +90°', command=(self.cadre.rotatepp))
if type == 1:
self.master.menubar.add_command(label='Page suivante', command=(self.pages))
self.master.config(menu=(self.master.menubar))
self.cadre.canvas.bind('<ButtonPress-3>', self.motionprep)
self.cadre.canvas.bind('<B3-Motion>', self.motionize)
self.cadre.canvas.bind('<ButtonRelease-3>', self.motionend)
def pages(self):
if self.pagenum + 1 < self.nframe:
im = Image.open(self.fileorig)
im.seek(self.pagenum + 1)
newpath = globs.CNIREnv + '\\temp' + str(random.randint(11111, 99999)) + '.tif'
im.save(newpath)
im.close()
self.cadre.destroy()
self.__init__(self.master, self.fileorig, 1, self.nframe, self.pagenum + 1, newpath)
def pagep(self):
if self.pagenum - 1 >= 0:
im = Image.open(self.fileorig)
im.seek(self.pagenum - 1)
newpath = globs.CNIREnv + '\\temp' + str(random.randint(11111, 99999)) + '.tif'
im.save(newpath)
im.close()
self.cadre.destroy()
self.__init__(self.master, self.fileorig, 1, self.nframe, self.pagenum - 1, newpath)
def motionprep(self, event):
if hasattr(self, 'rect'):
self.begx = event.x
self.begy = event.y
self.ix = self.cadre.canvas.canvasx(event.x)
self.iy = self.cadre.canvas.canvasy(event.y)
self.cadre.canvas.coords(self.rect, self.cadre.canvas.canvasx(event.x), self.cadre.canvas.canvasy(event.y), self.ix, self.iy)
else:
self.begx = event.x
self.begy = event.y
self.ix = self.cadre.canvas.canvasx(event.x)
self.iy = self.cadre.canvas.canvasy(event.y)
self.rect = self.cadre.canvas.create_rectangle((self.cadre.canvas.canvasx(event.x)), (self.cadre.canvas.canvasy(event.y)), (self.ix), (self.iy), outline='red')
def motionize(self, event):
event.x
event.y
self.cadre.canvas.coords(self.rect, self.ix, self.iy, self.cadre.canvas.canvasx(event.x), self.cadre.canvas.canvasy(event.y))
def motionend(self, event):
self.endx = event.x
self.endy = event.y
self.imtotreat = self.cadre.resizedim.crop((min(self.begx, self.endx), min(self.begy, self.endy), max(self.endx, self.begx), max(self.endy, self.begy)))
im = self.imtotreat
import CNI_pytesseract as pytesseract
try:
os.environ['PATH'] = globs.CNIREnv + '\\Tesseract-OCR4\\'
os.environ['TESSDATA_PREFIX'] = globs.CNIREnv + '\\Tesseract-OCR4\\tessdata'
self.text = pytesseract.image_to_string(im, lang='ocrb', boxes=False, config='--psm 6 --oem 0 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890<')
except pytesseract.TesseractNotFoundError as e:
try:
os.remove(globs.CNIREnv + '\\Tesseract-OCR4\\*.*')
except Exception:
pass
showerror('Erreur de module OCR', ('Le module OCR localisé en ' + str(os.environ['PATH']) + 'est introuvable. Il sera réinstallé à la prochaine exécution'), parent=self)
except pytesseract.TesseractError as e:
pass
self.master.success = False
dialogconf = OpenScanDialog(self.master, self.text)
dialogconf.transient(self)
dialogconf.grab_set()
self.wait_window(dialogconf)
if self.master.success:
self.master.destroy()

View File

@ -717,12 +717,13 @@ I__ = [
]
IDFR = [
["112223333333333333333333333333444444", "555566677777899999999999999AAAAAABCD"],
["11222333333333333333333333333344444E", "555566677777899999999999999AAAAAABCD"],
{
"1": ["2", "CODE", "ID"],
"2": ["3", "PAYS", "FRA"],
"3": ["25", "NOM", "([A-Z]|<)+"],
"4": ["6", "NOINT", ".+"],
"E": ["1", "CTRL", "[0-9]", "1234"],
"5": ["4", "DDATE", "[0-9]+"],
"6": ["3", "NOINT2", "[0-9]+"],
"7": ["5", "NOINT3", "[0-9]+"],
@ -731,7 +732,7 @@ IDFR = [
"A": ["6", "BDATE", "[0-9]+"],
"B": ["1", "CTRL", "[0-9]", "A"],
"C": ["1", "SEX", "[A-Z]"],
"D": ["1", "CTRL", "[0-9]", "123456789ABC"]
"D": ["1", "CTRL", "[0-9]", "123456789ABCE"]
},
"Pièce d'identité FR"
]
@ -758,13 +759,45 @@ longest = max([len(x[0][0]) for x in TYPES])
## THE ROOT OF THIS PROJECT !
def getDocString(doc):
return doc[0][0] + doc[0][1]
def getFieldLimits(doc, fieldtype):
"""
This function returns the limit of a given field string id for a given document structure
"""
L1 = limits(doc[0][0], fieldtype)
L2 = limits(doc[0][1], fieldtype)
if -1 in L1:
return 1, L2
else:
return 0, L1
return
def limits(line, fieldtype):
"""
Returns the limit of a given field structure
"""
a = line.find(fieldtype)
b = line.rfind(fieldtype)
return (a,b+1)
def completeDocField(doc, code, position):
"""
Completes with '<' the document the field that is located at given position
"""
field = getDocString(doc)[position]
limit = limits(getDocString(doc), field)
res = limit[1] - position
#print("field : {}, limit : {}, number of char to complete : {}".format(field, limit, res))
return res
def docMatch(doc, strs):
"""
This function calculates a regex match score for a given document and a string couple
"""
# Global handler
logfile = logger.logCur
@ -808,6 +841,9 @@ def docMatch(doc, strs):
return (level, nchar, bonus)
def allDocMatch(strs, final=False):
"""
This functions test all documents types on the lines provided and returns a score for each
"""
# Global handler
logfile = logger.logCur
@ -860,4 +896,68 @@ def computeControlSum(code):
break
resultat += valeur * facteur[(i % 3)]
return resultat % 10
return resultat % 10
def computeAllControlSum(doc, code):
"""
This function computes all the ctrl sums on a MRZ string and returns all the results
"""
ctrlSumList = []
# iteration on each char of the given MRZ
for charPos in range(len(code)):
field = getDocString(doc)[charPos]
if doc[1][field][1] == "CTRL":
#print("{} is CTRL field {}".format(code[charPos], field))
codeChain = ""
# iteration on the fields to control
for pos in range(len(code)):
target = getDocString(doc)[pos]
if target in doc[1][field][3]:
#print("__field : {} {} {} {}".format(target, pos, field, doc[1][field][3]))
codeChain += code[pos]
#print("chain to control : _{}_".format(codeChain))
ctrlSum = computeControlSum(codeChain)
#print("SUM : {} vs {}".format(code[charPos], ctrlSum))
ctrlSumList += [ (field, charPos, ctrlSum) ]
return ctrlSumList