Preparing update 3.1.0

This commit is contained in:
Adrien Bourmault 2019-08-19 17:56:23 +02:00 committed by GitHub
parent b9a24fca1e
commit 6b6589b772
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1648 additions and 714 deletions

View File

@ -24,19 +24,15 @@
******************************************************************************** ********************************************************************************
""" """
# Import critical files # Import critical files
import sys
import os import os
import subprocess
import threading import threading
import psutil
import traceback
import lang # lang.py import lang # lang.py
import logger # logger.py import logger # logger.py
import globs # globs.py import globs # globs.py
import critical # critical.py import critical # critical.py
# Import all other files # Import all other files and crash if necessary
try: try:
import launcher # launcher.py" import launcher # launcher.py"
@ -48,9 +44,6 @@ try:
except: except:
critical.LASTCHANCECRASH() critical.LASTCHANCECRASH()
from main import * # main.py
# Global handler # Global handler
logfile = logger.logCur logfile = logger.logCur
@ -72,8 +65,10 @@ def main():
mainw.logOnTerm('\n\n{} \n'.format(lang.all[globs.CNIRlang]["Please type a MRZ or open a scan"])) mainw.logOnTerm('\n\n{} \n'.format(lang.all[globs.CNIRlang]["Please type a MRZ or open a scan"]))
# changelog
if globs.CNIRNewVersion: if globs.CNIRNewVersion:
showinfo("Changelog : update summary", ('{} : CNIRevelator {}\n\n{}'.format(lang.all[globs.CNIRlang]["Program version"], globs.verstring_full, globs.changelog)), parent=mainw) mainw.after_idle(mainw.showChangeLog)
logfile.printdbg('main() : **** Launching App_main() ****') logfile.printdbg('main() : **** Launching App_main() ****')
try: try:
mainw.mainloop() mainw.mainloop()
@ -87,59 +82,44 @@ def main():
## BOOTSTRAP OF CNIREVELATOR ## BOOTSTRAP OF CNIREVELATOR
try: try:
# LANGUAGE
if os.path.isfile(globs.CNIRLangFile):
with open(globs.CNIRLangFile, 'r') as (configFile):
try:
# Reading it
globs.CNIRlang = configFile.read()
except Exception as e:
ihm.crashCNIR()
raise IOError(str(e))
else:
# Recreating the url file
try:
os.mkdir(globs.CNIRFolder + '\\config')
except:
pass
with open(globs.CNIRLangFile, 'w') as (configFile): try:
# LANGUAGE
lang.readLang()
except:
ihm.crashCNIR()
updater.exitProcess(1)
from main import * # main.py
# GO
try:
launcherThread = threading.Thread(target=updater.umain, daemon=False)
launcher.lmain(launcherThread)
except Exception:
ihm.crashCNIR()
updater.exitProcess(1)
if updater.UPDATE_IS_MADE:
# Launch app !
args = updater.UPATH + '\\CNIRevelator.exe' + " DELETE " + globs.CNIRFolder
cd = updater.UPATH
for i in range(0,3):
try: try:
# Writing it updater.spawnProcess(args, cd)
configFile.write(globs.CNIRlang) except:
except Exception as e: time.sleep(3)
ihm.crashCNIR() continue
raise IOError(str(e)) break
updater.exitProcess(0)
# Here we go !
try:
main()
except Exception as e:
ihm.crashCNIR()
updater.exitProcess(1)
except: except:
ihm.crashCNIR() critical.LASTCHANCECRASH()
updater.exitProcess(1)
# GO
try:
launcherThread = threading.Thread(target=updater.umain, daemon=False)
launcher.lmain(launcherThread)
except Exception:
ihm.crashCNIR()
updater.exitProcess(1)
if updater.UPDATE_IS_MADE:
# Launch app !
args = updater.UPATH + '\\CNIRevelator.exe' + " DELETE " + globs.CNIRFolder
cd = updater.UPATH
for i in range(0,3):
try:
updater.spawnProcess(args, cd)
except:
time.sleep(3)
continue
break
updater.exitProcess(0)
# Here we go !
try:
main()
except Exception as e:
ihm.crashCNIR()
updater.exitProcess(1)
updater.exitProcess(0) updater.exitProcess(0)

View File

@ -24,16 +24,27 @@
""" """
from tkinter.messagebox import * from tkinter.messagebox import *
from tkinter import * from tkinter import *
import webbrowser
import traceback
import psutil
import os
import lang # lang.py import lang # lang.py
import logger # logger.py import logger # logger.py
import globs # globs.py
def LASTCHANCECRASH(): def LASTCHANCECRASH():
"""
very last solution
"""
root = Tk() root = Tk()
root.withdraw() root.withdraw()
logfile = logger.logCur logfile = logger.logCur
logfile.printerr("FATAL ERROR : see traceback below.\n{}".format(traceback.format_exc())) logfile.printerr("FATAL ERROR : see traceback below.\n{}".format(traceback.format_exc()))
showerror(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["CNIRevelator crashed because a fatal error occured. View log for more infos and please open an issue on Github"]) showerror(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["CNIRevelator crashed because a fatal error occured. View log for more infos and please open an issue on Github"])
res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to open the log file ?"])
if res == "yes":
webbrowser.open_new(globs.CNIRErrLog)
res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to open an issue on Github to report this bug ?"]) res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to open an issue on Github to report this bug ?"])
if res == "yes": if res == "yes":
webbrowser.open_new("https://github.com/neox95/CNIRevelator/issues") webbrowser.open_new("https://github.com/neox95/CNIRevelator/issues")

View File

@ -29,16 +29,29 @@ verType = "final release"
version = [3, 1, 0] version = [3, 1, 0]
verstring_full = "{}.{}.{} {}".format(version[0], version[1], version[2], verType) verstring_full = "{}.{}.{} {}".format(version[0], version[1], version[2], verType)
verstring = "{}.{}".format(version[0], version[1]) verstring = "{}.{}".format(version[0], version[1])
debug = True
changelog = "Version 3.1.0 \nMise-à-jour majeure avec les progressions suivantes :\n- Modifications cosmétiques de l'interface utilisateur\n- Stabilisation des changements effectués sur la version mineure 3.0 : interface utilisateur, OCR, VISA A et B, logging\n- Rationalisation du système de langues" CNIRTesserHash = '5b58db27f7bc08c58a2cb33d01533b034b067cf8'
CNIRFolder = os.getcwd()
CNIRLColor = "#006699"
CNIRName = "CNIRevelator {}".format(verstring)
CNIRCryptoKey = '82Xh!efX3#@P~2eG'
CNIRNewVersion = False
CNIRConfig = CNIRFolder + '\\config\\conf.ig'
CNIRTesser = CNIRFolder + '\\Tesseract-OCR4\\'
CNIRErrLog = CNIRFolder + '\\logs\\error.log'
CNIRMainLog = CNIRFolder + '\\logs\\main.log'
CNIRUrlConfig = CNIRFolder + '\\config\\urlconf.ig'
CNIRVerStock = CNIRFolder + '\\downloads\\versions.lst'
CNIREnv = CNIRFolder + '\\Data\\'
CNIRTesserHash = '5b58db27f7bc08c58a2cb33d01533b034b067cf8' CNIRTesserHash = '5b58db27f7bc08c58a2cb33d01533b034b067cf8'
CNIRFolder = os.path.dirname(os.path.realpath(__file__)) CNIRFolder = os.path.dirname(os.path.realpath(__file__))
CNIRLColor = "#006699" CNIRLColor = "#006699"
CNIRName = "CNIRevelator {}".format(verstring) CNIRName = "CNIRevelator {}".format(verstring)
CNIRCryptoKey = '82Xh!efX3#@P~2eG' CNIRCryptoKey = '82Xh!efX3#@P~2eG'
CNIRNewVersion = False
CNIRLangFile = CNIRFolder + '\\config\\lang.ig' CNIRLangFile = CNIRFolder + '\\config\\lang.ig'
CNIRlang = "fr" CNIRlang = "fr"
@ -50,4 +63,9 @@ CNIRUrlConfig = CNIRFolder + '\\config\\urlconf.ig'
CNIRVerStock = CNIRFolder + '\\downloads\\versions.lst' CNIRVerStock = CNIRFolder + '\\downloads\\versions.lst'
CNIREnv = CNIRFolder + '\\Data\\' CNIREnv = CNIRFolder + '\\Data\\'
CNIROpenFile = False CNIRBetaURL = "https://raw.githubusercontent.com/neox95/CNIRevelator/v3.1/VERSIONS.LST"
CNIRDefaultURL = "https://raw.githubusercontent.com/neox95/CNIRevelator/master/VERSIONS.LST"
CNIRNewVersion = False
CNIROpenFile = False
debug = True

View File

@ -1,4 +1,4 @@
""" """
******************************************************************************** ********************************************************************************
* CNIRevelator * * CNIRevelator *
* * * *
@ -35,7 +35,7 @@ import traceback
import logger # logger.py import logger # logger.py
import globs # globs.py import globs # globs.py
import lang # lang.py import lang # lang.py
import updater # updater.py
controlKeys = ["Escape", "Right", "Left", "Up", "Down", "Home", "End", "BackSpace", "Delete", "Inser", "Shift_L", "Shift_R", "Control_R", "Control_L"] controlKeys = ["Escape", "Right", "Left", "Up", "Down", "Home", "End", "BackSpace", "Delete", "Inser", "Shift_L", "Shift_R", "Control_R", "Control_L"]
@ -117,21 +117,22 @@ class LoginDialog(Toplevel):
self.login = '' self.login = ''
super().__init__(parent) super().__init__(parent)
self.title(lang.all[globs.CNIRlang]["Connection"]) self.title(lang.all[globs.CNIRlang]["Connection"])
Label(self, text='IPN : ').pack() self["background"] = "white"
self.entry_login = Entry(self) Label(self, text='IPN : ', bg="white").pack(fill=Y)
self.entry_login = ttk.Entry(self)
self.entry_login.insert(0, '') self.entry_login.insert(0, '')
self.entry_login.pack() self.entry_login.pack()
Label(self, text='{} : '.format(lang.all[globs.CNIRlang]["Password"])).pack() Label(self, text='{} : '.format(lang.all[globs.CNIRlang]["Password"]), bg="white").pack(fill=Y)
self.entry_pass = Entry(self, show='*') self.entry_pass = ttk.Entry(self, show='*')
self.entry_pass.insert(0, '') self.entry_pass.insert(0, '')
self.entry_pass.pack() self.entry_pass.pack(fill=Y)
Button(self, text=lang.all[globs.CNIRlang]["Connection"], command=(self.connecti)).pack() ttk.Button(self, text=lang.all[globs.CNIRlang]["Connection"], command=(self.connecti)).pack(fill=Y, pady=10)
self.update()
self.resizable(width=False, height=False) self.resizable(width=False, height=False)
ws = self.winfo_screenwidth() ws = self.winfo_screenwidth()
hs = self.winfo_screenheight() hs = self.winfo_screenheight()
w = hs / 10 w = self.winfo_reqwidth() + 5
h = ws / 18 h = self.winfo_reqheight()
self.update()
if getattr(sys, 'frozen', False): if getattr(sys, 'frozen', False):
self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico') self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else: else:
@ -146,6 +147,124 @@ class LoginDialog(Toplevel):
self.key = self.entry_pass.get().strip() self.key = self.entry_pass.get().strip()
self.destroy() self.destroy()
class ChangelogDialog(Toplevel):
def __init__(self, parent, text):
super().__init__(parent)
self.title(lang.all[globs.CNIRlang]["Show Changelog"])
self["background"] = "white"
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.text = Text(self, wrap='word', width=55, height=15, borderwidth=0, font="TkDefaultFont", bg="white")
self.text.grid(column=0, row=0, sticky='EWNS', padx=5, pady=5)
ttk.Button(self, text="OK", command=(self.oki)).grid(column=0, row=1, pady=5)
self.scrollb = ttk.Scrollbar(self, command=(self.text.yview))
self.scrollb.grid(column=1, row=0, sticky='EWNS', padx=5, pady=5)
self.text['yscrollcommand'] = self.scrollb.set
self.text.insert('end', text)
self.text['state'] = 'disabled'
self.update()
self.resizable(width=False, height=False)
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
w = self.winfo_reqwidth() + 5
h = self.winfo_reqheight()
if getattr(sys, 'frozen', False):
self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
self.iconbitmap('id-card.ico')
x = ws / 2 - w / 2
y = hs / 2 - h / 2
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
self.bind("<Return>", self.oki)
def oki(self, event=None):
self.destroy()
class langDialog(Toplevel):
def __init__(self, parent):
super().__init__(parent)
self.title(lang.all[globs.CNIRlang]["Language"])
Label(self, text=lang.all[globs.CNIRlang]["Please choose your language : "]).pack(fill=Y)
vals = [i for i in lang.all]
for i in range(len(lang.all)):
ttk.Radiobutton(self, text=vals[i], command=self.createRegister(i), value=vals[i]).pack(fill=Y)
ttk.Button(self, text="OK", command=(self.oki)).pack(fill=Y, pady=5)
self.update()
self.resizable(width=False, height=False)
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
w = self.winfo_reqwidth() + 5
h = self.winfo_reqheight()
if getattr(sys, 'frozen', False):
self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
self.iconbitmap('id-card.ico')
x = ws / 2 - w / 2
y = hs / 2 - h / 2
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
self.bind("<Return>", self.oki)
def oki(self, event=None):
self.destroy()
def createRegister(self, i):
def register():
lang.updateLang([j for j in lang.all][i])
return register
class updateSetDialog(Toplevel):
def __init__(self, parent):
super().__init__(parent)
self.title(lang.all[globs.CNIRlang]["Update options"])
Label(self, text=lang.all[globs.CNIRlang]["Please choose your update channel : "]).pack(fill=Y)
self.vals = ["Stable", "Beta"]
vals = self.vals
for i in range(len(vals)):
ttk.Radiobutton(self, text=vals[i], command=self.createRegister(i), value=vals[i]).pack(fill=Y)
ttk.Button(self, text="OK", command=(self.oki)).pack(fill=Y, pady=5)
self.update()
self.resizable(width=False, height=False)
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
w = self.winfo_reqwidth() + 5
h = self.winfo_reqheight()
if getattr(sys, 'frozen', False):
self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
self.iconbitmap('id-card.ico')
x = ws / 2 - w / 2
y = hs / 2 - h / 2
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
self.bind("<Return>", self.oki)
def oki(self, event=None):
self.destroy()
def createRegister(self, i):
def register():
updater.updateChannel(self.vals[i])
return register
class LauncherWindow(Tk): class LauncherWindow(Tk):
def __init__(self): def __init__(self):
@ -233,6 +352,23 @@ class ResizeableCanvas(Canvas):
# rescale all the objects tagged with the "all" tag # rescale all the objects tagged with the "all" tag
self.scale("all",0,0,wscale,hscale) self.scale("all",0,0,wscale,hscale)
class StatusBar(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.label = Label(self, bd=1, relief=SUNKEN, anchor=W)
self.label.pack(fill=X)
def set(self, text):
self.label.config(text="Document : " + text.lower())
self.label.update_idletasks()
def clear(self):
self.label.config(text="")
self.label.update_idletasks()
## Crash
def crashCNIR(): def crashCNIR():
""" """
last solution last solution
@ -244,6 +380,9 @@ def crashCNIR():
root.withdraw() root.withdraw()
logfile.printerr("FATAL ERROR : see traceback below.\n{}".format(traceback.format_exc())) logfile.printerr("FATAL ERROR : see traceback below.\n{}".format(traceback.format_exc()))
showerror(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["CNIRevelator crashed because a fatal error occured. View log for more infos and please open an issue on Github"]) showerror(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["CNIRevelator crashed because a fatal error occured. View log for more infos and please open an issue on Github"])
res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to open the log file ?"])
if res == "yes":
webbrowser.open_new(globs.CNIRErrLog)
res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to open an issue on Github to report this bug ?"]) res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to open an issue on Github to report this bug ?"])
if res == "yes": if res == "yes":
webbrowser.open_new("https://github.com/neox95/CNIRevelator/issues") webbrowser.open_new("https://github.com/neox95/CNIRevelator/issues")

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@ from tkinter import filedialog
from tkinter import ttk from tkinter import ttk
import threading import threading
from datetime import datetime from datetime import datetime
from importlib import reload
import re import re
import cv2 import cv2
import PIL.Image, PIL.ImageTk import PIL.Image, PIL.ImageTk
@ -50,11 +51,16 @@ logfile = logger.logCur
class mainWindow(Tk): class mainWindow(Tk):
## App Pattern
def __init__(self): def __init__(self):
Tk.__init__(self) Tk.__init__(self)
self.initialize() self.initialize()
def initialize(self): def initialize(self):
"""
Initializes the main window
"""
self.mrzChar = "" self.mrzChar = ""
self.mrzDecided = False self.mrzDecided = False
self.Tags = [] self.Tags = []
@ -71,12 +77,13 @@ class mainWindow(Tk):
logfile.printdbg('Launching main window with resolution' + str(ws) + 'x' + str(hs)) logfile.printdbg('Launching main window with resolution' + str(ws) + 'x' + str(hs))
# Configuring the size of each part of the window # Configuring the size of each part of the window
self.grid_columnconfigure(0, weight=1, minsize=(ws / 2 * 0.3333333333333333)) self.grid_columnconfigure(0, minsize=(ws / 2 * 0.3333333333333333))
self.grid_columnconfigure(1, weight=1, minsize=(ws / 2 * 0.3333333333333333)) self.grid_columnconfigure(1, minsize=(ws / 2 * 0.3333333333333333))
self.grid_columnconfigure(2, 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(0, minsize=(hs / 2 * 0.5))
self.grid_rowconfigure(1, weight=1, minsize=(hs / 2 * 0.10)) self.grid_rowconfigure(1, minsize=(hs / 2 * 0.10))
self.grid_rowconfigure(2, weight=1, minsize=(hs / 2 * 0.35)) self.grid_rowconfigure(2, minsize=(hs / 2 * 0.35))
self.grid_rowconfigure(3, minsize=10)
# Prepare the data sections # Prepare the data sections
self.lecteur_ci = ttk.Labelframe(self, text=lang.all[globs.CNIRlang]["Informations about the current document"]) self.lecteur_ci = ttk.Labelframe(self, text=lang.all[globs.CNIRlang]["Informations about the current document"])
@ -91,9 +98,14 @@ class mainWindow(Tk):
self.lecteur_ci.grid_rowconfigure(3, weight=1) self.lecteur_ci.grid_rowconfigure(3, weight=1)
self.lecteur_ci.grid_rowconfigure(4, weight=1) self.lecteur_ci.grid_rowconfigure(4, weight=1)
self.lecteur_ci.grid_rowconfigure(5, weight=1) self.lecteur_ci.grid_rowconfigure(5, weight=1)
# And what about the status bar ?
self.statusbar = ihm.StatusBar(self)
self.statusbar.grid(row=3, columnspan=3, sticky="NSEW")
# Fill the data sections # Fill the data sections
ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Status"])).grid(column=0, row=0, padx=5, pady=5) ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Status"])).grid(column=0, row=0, padx=5, pady=5)
self.statusbar.set(lang.all[globs.CNIRlang]["IDLE"])
self.STATUStxt = ttk.Label((self.lecteur_ci), text=lang.all[globs.CNIRlang]["IDLE"], font=("TkDefaultFont", 13, "bold"), foreground="orange", anchor=CENTER) self.STATUStxt = ttk.Label((self.lecteur_ci), text=lang.all[globs.CNIRlang]["IDLE"], font=("TkDefaultFont", 13, "bold"), foreground="orange", anchor=CENTER)
self.STATUStxt.grid(column=1, row=0, padx=5, pady=5) self.STATUStxt.grid(column=1, row=0, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Name"])).grid(column=0, row=1, padx=5, pady=5) ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Name"])).grid(column=0, row=1, padx=5, pady=5)
@ -319,14 +331,21 @@ class mainWindow(Tk):
menu1.add_separator() menu1.add_separator()
menu1.add_command(label=lang.all[globs.CNIRlang]["Quit"], command=(self.destroy)) menu1.add_command(label=lang.all[globs.CNIRlang]["Quit"], command=(self.destroy))
menubar.add_cascade(label=lang.all[globs.CNIRlang]["File"], menu=menu1) menubar.add_cascade(label=lang.all[globs.CNIRlang]["File"], menu=menu1)
menu2 = Menu(menubar, tearoff=0)
menu2.add_command(label=lang.all[globs.CNIRlang]["Update options"], command=(self.updateSet))
menu2.add_command(label=lang.all[globs.CNIRlang]["Show Changelog"], command=(self.showChangeLog))
menu2.add_separator()
menu2.add_command(label=lang.all[globs.CNIRlang]["Language"], command=(self.languageSet))
menubar.add_cascade(label=lang.all[globs.CNIRlang]["Settings"], menu=menu2)
menu3 = Menu(menubar, tearoff=0) menu3 = Menu(menubar, tearoff=0)
menu3.add_command(label=lang.all[globs.CNIRlang]["Keyboard commands"], command=(self.helpbox)) menu3.add_command(label=lang.all[globs.CNIRlang]["Keyboard commands"], command=(self.helpbox))
menu3.add_command(label=lang.all[globs.CNIRlang]["Report a bug"], command=(self.openIssuePage)) menu3.add_command(label=lang.all[globs.CNIRlang]["Report a bug"], command=(self.openIssuePage))
menu3.add_separator() menu3.add_separator()
menu3.add_command(label=lang.all[globs.CNIRlang]["About CNIRevelator"], command=(self.infobox)) menu3.add_command(label=lang.all[globs.CNIRlang]["About CNIRevelator"], command=(self.infobox))
menubar.add_cascade(label=lang.all[globs.CNIRlang]["Help"], menu=menu3) menubar.add_cascade(label=lang.all[globs.CNIRlang]["Help"], menu=menu3)
menubar.add_command(label="<|>", command=(self.panelResize))
self.config(menu=menubar) self.config(menu=menubar)
# The title # The title
self.wm_title(globs.CNIRName) self.wm_title(globs.CNIRName)
@ -337,19 +356,21 @@ class mainWindow(Tk):
self.iconbitmap('id-card.ico') self.iconbitmap('id-card.ico')
# Make this window resizable and set her size # Make this window resizable and set her size
self.resizable(width=True, height=True) self.resizable(0, 0)
self.update() self.update()
w = int(self.winfo_reqwidth()) self.w = int(self.winfo_reqwidth())
h = int(self.winfo_reqheight()) self.h = int(self.winfo_reqheight())
ws = self.winfo_screenwidth() self.ws = self.winfo_screenwidth()
hs = self.winfo_screenheight() self.hs = self.winfo_screenheight()
x = (ws - w)/2 self.x = (self.ws - self.w)/2
y = (hs - h)/2 self.y = (self.hs - self.h)/2
self.geometry('%dx%d+%d+%d' % (w, h, x, y)) self.geometry('%dx%d+%d+%d' % (self.w, self.h, self.x, self.y))
self.update() self.update()
self.deiconify() self.deiconify()
self.attributes("-topmost", 1) self.attributes("-topmost", 1)
self.minsize(self.winfo_width(), self.winfo_height()) self.maxsize(self.w, self.h)
self.minsize(int(2.15 * (self.ws / 2 * 0.3333333333333333)), self.h)
self.currentw = self.w
# Set image # Set image
self.imageViewer.image = None self.imageViewer.image = None
@ -370,13 +391,13 @@ class mainWindow(Tk):
if globs.CNIROpenFile: if globs.CNIROpenFile:
self.after_idle(lambda : self.openScanFile(sys.argv[1])) self.after_idle(lambda : self.openScanFile(sys.argv[1]))
def statusUpdate(self, image=None, setplace=False):
if image: ## OCR related functions
self.imageViewer.image = image
self.imageViewer.ZONE.itemconfigure(self.STATUSimg, image=(self.imageViewer.image))
self.imageViewer.ZONE.configure(scrollregion=self.imageViewer.ZONE.bbox("all"))
def rectangleSelectScan(self, event): def rectangleSelectScan(self, event):
"""
Realises the selection of the MRZ to make OCR possible
"""
if self.imageViewer.image: if self.imageViewer.image:
canvas = event.widget canvas = event.widget
#print("Get coordinates : [{}, {}], for [{}, {}]".format(canvas.canvasx(event.x), canvas.canvasy(event.y), event.x, event.y)) #print("Get coordinates : [{}, {}], for [{}, {}]".format(canvas.canvasx(event.x), canvas.canvasy(event.y), event.x, event.y))
@ -390,6 +411,9 @@ class mainWindow(Tk):
self.imageViewer.ZONE.delete(self.select) self.imageViewer.ZONE.delete(self.select)
def goOCRDetection(self): def goOCRDetection(self):
"""
Realises the OCR detection and get the text in self.mrzChar (and prints it)
"""
if self.imageViewer.image: if self.imageViewer.image:
cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber] cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber]
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
@ -466,8 +490,12 @@ class mainWindow(Tk):
logfile.printerr("Tesseract error : {}".format(e)) logfile.printerr("Tesseract error : {}".format(e))
showerror(lang.all[globs.CNIRlang]["OCR module error"], (lang.all[globs.CNIRlang]["The Tesseract module encountered a problem: {}"].format(e)), parent=self) showerror(lang.all[globs.CNIRlang]["OCR module error"], (lang.all[globs.CNIRlang]["The Tesseract module encountered a problem: {}"].format(e)), parent=self)
## Regex and document detection + control related functions
def stringValidation(self, keysym): def stringValidation(self, keysym):
"""
Analysis of the already typed document
"""
# analysis # analysis
# If we must decide the type of the document # If we must decide the type of the document
if not self.mrzDecided: if not self.mrzDecided:
@ -484,10 +512,12 @@ class mainWindow(Tk):
self.wait_window(invite) self.wait_window(invite)
self.logOnTerm(lang.all[globs.CNIRlang]["Document detected: {}\n"].format(candidates[invite.choice][2])) self.logOnTerm(lang.all[globs.CNIRlang]["Document detected: {}\n"].format(candidates[invite.choice][2]))
self.statusbar.set(candidates[invite.choice][2])
self.mrzDecided = candidates[invite.choice] self.mrzDecided = candidates[invite.choice]
elif len(candidates) == 1: elif len(candidates) == 1:
self.logOnTerm(lang.all[globs.CNIRlang]["Document detected: {}\n"].format(candidates[0][2])) self.logOnTerm(lang.all[globs.CNIRlang]["Document detected: {}\n"].format(candidates[0][2]))
self.statusbar.set(candidates[0][2])
self.mrzDecided = candidates[0] self.mrzDecided = candidates[0]
else: else:
# corrects some problems # corrects some problems
@ -574,11 +604,13 @@ class mainWindow(Tk):
self.wait_window(invite) self.wait_window(invite)
self.logOnTerm(lang.all[globs.CNIRlang]["Document detected again: {} \ n"].format(candidates[invite.choice][2])) self.logOnTerm(lang.all[globs.CNIRlang]["Document detected again: {}\n"].format(candidates[invite.choice][2]))
self.statusbar.set(candidates[invite.choice][2])
self.mrzDecided = candidates[invite.choice] self.mrzDecided = candidates[invite.choice]
elif len(candidates) == 1: elif len(candidates) == 1:
self.logOnTerm(lang.all[globs.CNIRlang]["Document detected again: {} \ n"].format(candidates[0][2])) self.logOnTerm(lang.all[globs.CNIRlang]["Document detected again: {}\n"].format(candidates[0][2]))
self.statusbar.set(candidates[0][2])
self.mrzDecided = candidates[0] self.mrzDecided = candidates[0]
return "break" return "break"
@ -630,30 +662,128 @@ class mainWindow(Tk):
char = self.speed731text.get() char = self.speed731text.get()
self.speedResultPrint(str(mrz.computeControlSum(char))) self.speedResultPrint(str(mrz.computeControlSum(char)))
return "break" return "break"
def computeSigma(self):
"""
Launch the checksum computation, infos validation and print/display the results
"""
# the regex
regex = re.compile("[^A-Z0-9<]")
code = re.sub(regex, '', self.mrzChar)
self.compliance = True
allSums = mrz.computeAllControlSum(self.mrzDecided, code)["ctrlSumList"]
#print("Code : _{}_ | Sums : {}".format(code, allSums))
self.termtext.tag_remove("conforme", "1.0", "end")
self.termtext.tag_remove("nonconforme", "1.0", "end")
self.clearTerm()
self.logOnTerm(lang.all[globs.CNIRlang]["Document Review: {}\n\n"].format(self.mrzDecided[2]))
for sum in allSums:
x = sum[1] // len(self.mrzDecided[0][0]) +1
y = sum[1] % len(self.mrzDecided[0][0])
#print("index : {}.{}".format(x,y))
#print("{} == {}".format(code[sum[1]], sum[2]))
if sum[3]:
self.logOnTerm(lang.all[globs.CNIRlang]["Checksum position {}: Lu {} VS Calculated {} [facultative]\n"].format(sum[1], code[sum[1]], sum[2]))
else:
self.logOnTerm(lang.all[globs.CNIRlang]["Checksum position {}: Lu {} VS Calculated {}\n"].format(sum[1], code[sum[1]], sum[2]))
# if sum is facultative or if sum is ok
try:
if sum[3] or int(code[sum[1]]) == int(sum[2]):
self.termtext.tag_add("conforme", "{}.{}".format(x,y), "{}.{}".format(x,y+1))
self.termtext.tag_configure("conforme", background="green", foreground="white")
else:
self.termtext.tag_add("nonconforme", "{}.{}".format(x,y), "{}.{}".format(x,y+1))
self.termtext.tag_configure("nonconforme", background="red", relief='raised', foreground="white")
self.compliance = False
except ValueError:
self.termtext.tag_add("nonconforme", "{}.{}".format(x,y), "{}.{}".format(x,y+1))
self.termtext.tag_configure("nonconforme", background="red", relief='raised', foreground="white")
self.compliance = False
# get the infos
docInfos = mrz.getDocInfos(self.mrzDecided, code)
#print(docInfos)
# display the infos
for key in [ e for e in docInfos ]:
#print(docInfos[key])
if key in ["CODE", "CTRL", "CTRLF"]:
continue
if not docInfos[key] == False:
self.infoList[key]['text'] = docInfos[key]
self.infoList[key]['background'] = self['background']
self.infoList[key]['foreground'] = "black"
else:
self.infoList[key]['background'] = "red"
self.infoList[key]['foreground'] = "white"
self.infoList[key]['text'] = "NC"
self.compliance = False
if self.compliance == True:
self.STATUStxt["text"] = lang.all[globs.CNIRlang]["COMPLIANT"]
self.STATUStxt["foreground"] = "green"
self.statusbar.set(lang.all[globs.CNIRlang]["COMPLIANT"])
else:
self.STATUStxt["text"] = lang.all[globs.CNIRlang]["IMPROPER"]
self.STATUStxt["foreground"] = "red"
self.statusbar.set(lang.all[globs.CNIRlang]["IMPROPER"])
## Print functions
def logOnTerm(self, text): def logOnTerm(self, text):
"""
Writes on the monitor
"""
self.monlog['state'] = 'normal' self.monlog['state'] = 'normal'
self.monlog.insert('end', text) self.monlog.insert('end', text)
self.monlog['state'] = 'disabled' self.monlog['state'] = 'disabled'
self.monlog.yview(END) self.monlog.yview(END)
def clearTerm(self): def clearTerm(self):
"""
Clears the monitor
"""
self.monlog['state'] = 'normal' self.monlog['state'] = 'normal'
self.monlog.delete('1.0', 'end') self.monlog.delete('1.0', 'end')
self.monlog['state'] = 'disabled' self.monlog['state'] = 'disabled'
self.monlog.yview(END) self.monlog.yview(END)
def speedResultPrint(self, text): def speedResultPrint(self, text):
"""
Prints a result in the quick entry terminal
"""
self.speedResult['state'] = 'normal' self.speedResult['state'] = 'normal'
self.speedResult.delete("1.0", 'end') self.speedResult.delete("1.0", 'end')
self.speedResult.insert('end', text) self.speedResult.insert('end', text)
self.speedResult['state'] = 'disabled' self.speedResult['state'] = 'disabled'
## Document display related functions
def DisplayUpdate(self, image=None, setplace=False):
"""
Reload the displayer to display the image or not
"""
if image:
self.imageViewer.image = image
self.imageViewer.ZONE.itemconfigure(self.STATUSimg, image=(self.imageViewer.image))
self.imageViewer.ZONE.configure(scrollregion=self.imageViewer.ZONE.bbox("all"))
def goPageChoice(self, event): def goPageChoice(self, event):
"""
Change the current viewed page of the multipage tiff if needed
"""
self.imageViewer.pagenumber = int(self.toolbar.pageChooser.get()) - 1 self.imageViewer.pagenumber = int(self.toolbar.pageChooser.get()) - 1
self.resizeScan() self.resizeScan()
def openingScan(self): def openingScan(self):
"""
Open the scan, ask its path and displays it
"""
path = '' path = ''
path = filedialog.askopenfilename(parent=self, title=lang.all[globs.CNIRlang]["Open a scan of document..."], filetypes=(('TIF files', '*.tif'), path = filedialog.askopenfilename(parent=self, title=lang.all[globs.CNIRlang]["Open a scan of document..."], filetypes=(('TIF files', '*.tif'),
('TIF files', '*.tiff'), ('TIF files', '*.tiff'),
@ -662,7 +792,9 @@ class mainWindow(Tk):
self.openScanFile(path) self.openScanFile(path)
def openScanFile(self, path): def openScanFile(self, path):
"""
Open an image file at path to display it on the displayer
"""
# Check if the file is valid # Check if the file is valid
if ( path[-3:] != 'jpg' if ( path[-3:] != 'jpg'
and path[-3:] != 'tif' and path[-3:] != 'tif'
@ -702,7 +834,7 @@ class mainWindow(Tk):
# Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage # Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img)) photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img))
self.statusUpdate(photo) self.DisplayUpdate(photo)
def zoomInScan50(self, quantity = 50): def zoomInScan50(self, quantity = 50):
if self.imageViewer.image: if self.imageViewer.image:
@ -763,6 +895,9 @@ class mainWindow(Tk):
self.resizeScan() self.resizeScan()
def negativeScan(self): def negativeScan(self):
"""
Invert the bits to make a negative of the scan (and highlight the contrasts)
"""
if self.imageViewer.image: if self.imageViewer.image:
# Load an image using OpenCV # Load an image using OpenCV
cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber] cv_img = cv2.imreadmulti(self.imageViewer.imagePath)[1][self.imageViewer.pagenumber]
@ -777,6 +912,9 @@ class mainWindow(Tk):
self.resizeScan(cv_img) self.resizeScan(cv_img)
def resizeScan(self, cv_img = None): def resizeScan(self, cv_img = None):
"""
Reloads the image according to settings
"""
if self.imageViewer.image: if self.imageViewer.image:
try: try:
if not hasattr(cv_img, 'shape'): if not hasattr(cv_img, 'shape'):
@ -806,7 +944,7 @@ class mainWindow(Tk):
cv_img = cv2.resize(cv_img, dim, interpolation = cv2.INTER_AREA) cv_img = cv2.resize(cv_img, dim, interpolation = cv2.INTER_AREA)
# Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage # Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img)) photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img))
self.statusUpdate( photo) self.DisplayUpdate( photo)
except Exception as e: except Exception as e:
logfile.printerr("Error with opencv : {}".format(e)) logfile.printerr("Error with opencv : {}".format(e))
ihm.crashCNIR() ihm.crashCNIR()
@ -824,19 +962,26 @@ class mainWindow(Tk):
height, width, channels_no = cv_img.shape height, width, channels_no = cv_img.shape
# Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage # Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img)) photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img))
self.statusUpdate(photo) self.DisplayUpdate(photo)
except Exception as e: except Exception as e:
logfile.printerr("Critical error with opencv : ".format(e)) logfile.printerr("Critical error with opencv : ".format(e))
ihm.crashCNIR() ihm.crashCNIR()
showerror(lang.all[globs.CNIRlang]["OpenCV error (image processing)"], lang.all[globs.CNIRlang]["A critical error has occurred in the OpenCV image processing manager used by CNIRevelator, the application will reset itself"]) showerror(lang.all[globs.CNIRlang]["OpenCV error (image processing)"], lang.all[globs.CNIRlang]["A critical error has occurred in the OpenCV image processing manager used by CNIRevelator, the application will reset itself"])
self.initialize() self.initialize()
## IHM and user interface related functions
def newEntry(self): def newEntry(self):
"""
Reinits the IHM and invite
"""
self.initialize() self.initialize()
self.logOnTerm('\n\n{}\n'.format(lang.all[globs.CNIRlang]["Please type a MRZ or open a scan"])) self.logOnTerm('\n\n{}\n'.format(lang.all[globs.CNIRlang]["Please type a MRZ or open a scan"]))
def infobox(self): def infobox(self):
"""
Shows the About dialog
"""
Tk().withdraw() Tk().withdraw()
showinfo( lang.all[globs.CNIRlang]["About CNIRevelator"], showinfo( lang.all[globs.CNIRlang]["About CNIRevelator"],
@ -846,6 +991,9 @@ class mainWindow(Tk):
parent=self) parent=self)
def helpbox(self): def helpbox(self):
"""
Shows the keyboard help summary
"""
Tk().withdraw() Tk().withdraw()
showinfo( lang.all[globs.CNIRlang]["Keyboard commands"], showinfo( lang.all[globs.CNIRlang]["Keyboard commands"],
@ -856,79 +1004,55 @@ class mainWindow(Tk):
parent=self) parent=self)
def openIssuePage(self): def openIssuePage(self):
"""
Opens the Github Issue Repository page
"""
webbrowser.open_new("https://github.com/neox95/CNIRevelator/issues") webbrowser.open_new("https://github.com/neox95/CNIRevelator/issues")
def computeSigma(self): def showChangeLog(self):
changelogWin = ihm.ChangelogDialog(self, ('{} : CNIRevelator {}\n\n{}'.format(lang.all[globs.CNIRlang]["Program version"], globs.verstring_full, lang.all[globs.CNIRlang]["CHANGELOG"])))
changelogWin.transient(self)
changelogWin.grab_set()
changelogWin.focus_force()
self.wait_window(changelogWin)
def updateSet(self):
""" """
Launch the checksum computation, infos validation and display the results Update Settings
""" """
# the regex changeupdateWin = ihm.updateSetDialog(self)
regex = re.compile("[^A-Z0-9<]") changeupdateWin.transient(self)
code = re.sub(regex, '', self.mrzChar) changeupdateWin.grab_set()
self.compliance = True changeupdateWin.focus_force()
self.wait_window(changeupdateWin)
allSums = mrz.computeAllControlSum(self.mrzDecided, code)["ctrlSumList"]
#print("Code : _{}_ | Sums : {}".format(code, allSums)) def languageSet(self):
"""
self.termtext.tag_remove("conforme", "1.0", "end") Lang Settings
self.termtext.tag_remove("nonconforme", "1.0", "end") """
changelangWin = ihm.langDialog(self)
self.clearTerm() changelangWin.transient(self)
self.logOnTerm(lang.all[globs.CNIRlang]["Document Review: {}\n\n"].format(self.mrzDecided[2])) changelangWin.grab_set()
changelangWin.focus_force()
for sum in allSums: self.wait_window(changelangWin)
x = sum[1] // len(self.mrzDecided[0][0]) +1
y = sum[1] % len(self.mrzDecided[0][0]) global mrz
#print("index : {}.{}".format(x,y)) mrz = reload(mrz)
#print("{} == {}".format(code[sum[1]], sum[2]))
self.initialize()
self.logOnTerm(lang.all[globs.CNIRlang]["Check sum position {}: Lu {} VS Calculated {} and {}\n"].format(sum[1], code[sum[1]], sum[2], sum[3]))
def panelResize(self):
# if sum is facultative or if sum is ok """
try: Shows or hides the panel
if sum[3] or int(code[sum[1]]) == int(sum[2]): """
self.termtext.tag_add("conforme", "{}.{}".format(x,y), "{}.{}".format(x,y+1)) if self.currentw > int(2.15 * (self.ws / 2 * 0.3333333333333333)):
self.termtext.tag_configure("conforme", background="green", foreground="white") self.currentw = int(2.15 * (self.ws / 2 * 0.3333333333333333))
else: self.geometry('%dx%d+%d+%d' % (self.currentw, self.h, self.x, self.y))
self.termtext.tag_add("nonconforme", "{}.{}".format(x,y), "{}.{}".format(x,y+1)) self.update()
self.termtext.tag_configure("nonconforme", background="red", relief='raised', foreground="white")
self.compliance = False
except ValueError:
self.termtext.tag_add("nonconforme", "{}.{}".format(x,y), "{}.{}".format(x,y+1))
self.termtext.tag_configure("nonconforme", background="red", relief='raised', foreground="white")
self.compliance = False
# get the infos
docInfos = mrz.getDocInfos(self.mrzDecided, code)
#print(docInfos)
# display the infos
for key in [ e for e in docInfos ]:
#print(docInfos[key])
if key in ["CODE", "CTRL", "CTRLF"]:
continue
if not docInfos[key] == False:
self.infoList[key]['text'] = docInfos[key]
self.infoList[key]['background'] = self['background']
self.infoList[key]['foreground'] = "black"
else:
self.infoList[key]['background'] = "red"
self.infoList[key]['foreground'] = "white"
self.infoList[key]['text'] = "NC"
self.compliance = False
if self.compliance == True:
self.STATUStxt["text"] = lang.all[globs.CNIRlang]["COMPLIANT"]
self.STATUStxt["foreground"] = "green"
else: else:
self.STATUStxt["text"] = lang.all[globs.CNIRlang]["IMPROPER"] self.currentw = self.w
self.STATUStxt["foreground"] = "red" self.geometry('%dx%d+%d+%d' % (self.currentw, self.h, self.x, self.y))
self.update()
return

View File

@ -28,6 +28,7 @@ import re
import datetime import datetime
import logger # logger.py import logger # logger.py
import globs # globs.py
import lang # lang.py import lang # lang.py
## SEX CODES ## SEX CODES
@ -35,527 +36,9 @@ sexcode = {'M':'Homme', 'F':'Femme', 'X':'Non spécifié'}
## COUNTRY CODES ## COUNTRY CODES
landcode2 = { landcode2 = lang.all[globs.CNIRlang]["LANDCODE2"]
'AW': 'Aruba',
'AF': 'Afghanistan',
'AO': 'Angola',
'AI': 'Anguilla',
'AL': 'Albanie',
'AD': 'Andorre',
'AE': 'Emirats arabes unis',
'AR': 'Argentine',
'AM': 'Arménie',
'AS': 'Samoa américaines',
'AQ': 'Antarctique',
'TF': 'Terres australes et antarctiques françaises',
'AG': 'Antigua-et-Barbuda',
'AU': 'Australie',
'AT': 'Autriche',
'AZ': 'Azerbaidjan',
'BI': 'Burundi',
'BE': 'Belgique',
'BJ': 'Benin',
'BQ': 'Pays-Bas caribéens',
'BF': 'Burkina Faso',
'BD': 'Bangladesh',
'BG': 'Bulgarie',
'BH': 'Bahrein',
'BS': 'Bahamas',
'BA': 'Bosnie-Herzegovine',
'BL': 'Saint-Barthélemy',
'BY': 'Bielorussie',
'BZ': 'Belize',
'BM': 'Bermudes',
'BO': 'Bolivie',
'BR': 'Brésil',
'BB': 'Barbade',
'BN': 'Brunei',
'BT': 'Bhoutan',
'BW': 'Botswana',
'CF': 'République Centrafricaine',
'CA': 'Canada',
'CC': 'Îles Cocos',
'CH': 'Suisse',
'CL': 'Chili',
'CN': 'Chine',
'CI': "Côte d'Ivoire",
'CM': 'Cameroun',
'CD': 'Congo (République démocratique)',
'CG': 'Congo (République)',
'CK': 'Îles Cook',
'CO': 'Colombie',
'KM': 'Comores',
'CV': 'Cap-Vert',
'CR': 'Costa Rica',
'CU': 'Cuba',
'CW': 'Curaçao',
'CX': 'Île Christmas',
'KY': 'Caimans',
'CY': 'Chypre',
'CZ': 'Tchéquie',
'DE': 'Allemagne',
'DJ': 'Djibouti',
'DM': 'Dominique',
'DK': 'Danemark',
'DO': 'République dominicaine',
'DZ': 'Algérie',
'EC': 'Equateur',
'EG': 'Egypte',
'ER': 'Erythrée',
'EH': 'Sahara occidental',
'ES': 'Espagne',
'EE': 'Estonie',
'ET': 'Ethiopie',
'FI': 'Finlande',
'FJ': 'Fidji',
'FK': 'Îles Malouines',
'FR': 'France',
'FO': 'Féroé',
'FM': 'Micronésie',
'GA': 'Gabon',
'GB': 'Royaume-Uni',
'GE': 'Géorgie',
'GG': 'Guernesey',
'GH': 'Ghana',
'GI': 'Gibraltar',
'GN': 'Guinée',
'GP': 'Guadeloupe',
'GM': 'Gambie',
'GW': 'Guinée-Bissau',
'GQ': 'Guinée équatoriale',
'GR': 'Grèce',
'GD': 'Grenade',
'GL': 'Groenland',
'GT': 'Guatemala',
'GF': 'Guyane',
'GU': 'Guam',
'GY': 'Guyana',
'HK': 'Hong Kong',
'HN': 'Honduras',
'HR': 'Croatie',
'HT': 'Haïti',
'HU': 'Hongrie',
'ID': 'Indonésie',
'IM': 'Île de Man',
'IN': 'Inde',
'IO': "Territoire britannique de l'océan Indien",
'IE': 'Irlande',
'IR': 'Irak',
'IQ': 'Iran',
'IS': 'Islande',
'IL': 'Israël',
'IT': 'Italie',
'JM': 'Jamaïque',
'JE': 'Jersey',
'JO': 'Jordanie',
'JP': 'Japon',
'KZ': 'Kazakhstan',
'KE': 'Kenya',
'KG': 'Kirghizistan',
'KH': 'Cambodge',
'KI': 'Kiribati',
'KN': 'Saint-Christophe-et-Niévès',
'KR': 'Corée du Sud',
'KW': 'Koweït',
'LA': 'Laos',
'LB': 'Liban',
'LR': 'Liberia',
'LY': 'Libye',
'LC': 'Sainte-Lucie',
'LI': 'Liechtenstein',
'LK': 'Sri Lanka',
'LS': 'Lesotho',
'LT': 'Lituanie',
'LU': 'Luxembourg',
'LV': 'Lettonie',
'MO': 'Macao',
'MF': 'Sint-Maarten',
'MA': 'Maroc',
'MC': 'Monaco',
'MD': 'Moldavie',
'MG': 'Madagascar',
'MV': 'Maldives',
'MX': 'Mexique',
'MH': 'Marshall',
'MK': 'Macedoine',
'ML': 'Mali',
'MT': 'Malte',
'MM': 'Birmanie',
'ME': 'Monténégro',
'MN': 'Mongolie',
'MP': 'Îles Mariannes du Nord',
'MZ': 'Mozambique',
'MR': 'Mauritanie',
'MS': 'Montserrat',
'MQ': 'Martinique',
'MU': 'Maurice',
'MW': 'Malawi',
'MY': 'Malaisie',
'YT': 'Mayotte',
'NA': 'Namibie',
'NC': 'Nouvelle-Calédonie',
'NE': 'Niger',
'NF': 'Île Norfolk',
'NG': 'Nigeria',
'NI': 'Nicaragua',
'NU': 'Niue',
'NL': 'Pays-Bas',
'NO': 'Norvège',
'NP': 'Nepal',
'NR': 'Nauru',
'NZ': 'Nouvelle-Zélande',
'OM': 'Oman',
'PK': 'Pakistan',
'PA': 'Panama',
'PN': 'Îles Pitcairn',
'PE': 'Pérou',
'PH': 'Philippines',
'PW': 'Palaos',
'PG': 'Papouasie-Nouvelle-Guinée',
'PL': 'Pologne',
'PR': 'Porto Rico',
'KP': 'Corée du Nord',
'PT': 'Portugal',
'PY': 'Paraguay',
'PS': 'Palestine',
'PF': 'Polynésie française',
'QA': 'Qatar',
'RE': 'Réunion',
'RO': 'Roumanie',
'RU': 'Russie',
'RW': 'Rwanda',
'SA': 'Arabie saoudite',
'SD': 'Soudan',
'SN': 'Sénégal',
'SG': 'Singapour',
'GS': 'Georgie du Sud-et-les iles Sandwich du Sud',
'SH': 'Sainte-Hélène, Ascension et Tristan da Cunha',
'SJ': 'Svalbard et île Jan Mayen',
'SB': 'Salomon',
'SL': 'Sierra Leone',
'SV': 'Salvador',
'SM': 'Saint-Marin',
'SO': 'Somalie',
'PM': 'Saint-Pierre-et-Miquelon',
'RS': 'Serbie',
'SS': 'Soudan du Sud',
'ST': 'Sao Tomé-et-Principe',
'SR': 'Suriname',
'SK': 'Slovaquie',
'SI': 'Slovénie',
'SE': 'Suède',
'SZ': 'eSwatani',
'SX': 'Saint-Martin ',
'SC': 'Seychelles',
'SY': 'Syrie',
'TC': 'Îles Turques-et-Caïques',
'TD': 'Tchad',
'TG': 'Togo',
'TH': 'Thaïlande',
'TJ': 'Tadjikistan',
'TK': 'Tokelau',
'TM': 'Turkmenistan',
'TL': 'Timor oriental',
'TO': 'Tonga',
'TT': 'Trinité-et-Tobago',
'TN': 'Tunisie',
'TR': 'Turquie',
'TV': 'Tuvalu',
'TW': 'Taiwan',
'TZ': 'Tanzanie',
'UG': 'Ouganda',
'UA': 'Ukraine',
'UY': 'Uruguay',
'US': 'Etats-Unis',
'UZ': 'Ouzbékistan',
'VA': 'Saint-Siège (État de la Cité du Vatican)',
'VC': 'Saint-Vincent-et-les-Grenadines',
'VE': 'Venezuela',
'VG': 'Îles Vierges britanniques',
'VI': 'Îles Vierges des États-Unis',
'VN': 'Viêt Nam',
'VU': 'Vanuatu',
'WF': 'Wallis-et-Futuna',
'WS': 'Samoa',
'XK': 'Kosovo',
'YE': 'Yémen',
'ZA': 'Afrique du Sud',
'ZM': 'Zambie',
'ZW': 'Zimbabwe'
}
landcode3 = { landcode3 = lang.all[globs.CNIRlang]["LANDCODE3"]
'ABW': 'Aruba',
'AFG': 'Afghanistan',
'AGO': 'Angola',
'AIA': 'Anguilla',
'ALB': 'Albanie',
'AND': 'Andorre',
'ARE': 'Emirats arabes unis',
'ARG': 'Argentine',
'ARM': 'Arménie',
'ASM': 'Samoa américaines',
'ATA': 'Antarctique',
'ATF': 'Terres australes et antarctiques françaises',
'ATG': 'Antigua-et-Barbuda',
'AUS': 'Australie',
'AUT': 'Autriche',
'AZE': 'Azerbaidjan',
'BDI': 'Burundi',
'BEL': 'Belgique',
'BEN': 'Benin',
'BES': 'Pays-Bas caribéens',
'BFA': 'Burkina Faso',
'BGD': 'Bangladesh',
'BGR': 'Bulgarie',
'BHR': 'Bahrein',
'BHS': 'Bahamas',
'BIH': 'Bosnie-Herzegovine',
'BLM': 'Saint-Barthélemy',
'BLR': 'Bielorussie',
'BLZ': 'Belize',
'BMU': 'Bermudes',
'BOL': 'Bolivie',
'BRA': 'Brésil',
'BRB': 'Barbade',
'BRN': 'Brunei',
'BTN': 'Bhoutan',
'BWA': 'Botswana',
'CAF': 'République Centrafricaine',
'CAN': 'Canada',
'CCK': 'Îles Cocos',
'CHE': 'Suisse',
'CHL': 'Chili',
'CHN': 'Chine',
'CIV': "Côte d'Ivoire",
'CMR': 'Cameroun',
'COD': 'Congo (République démocratique)',
'COG': 'Congo (République)',
'COK': 'Îles Cook',
'COL': 'Colombie',
'COM': 'Comores',
'CPV': 'Cap-Vert',
'CRI': 'Costa Rica',
'CUB': 'Cuba',
'CUW': 'Curaçao',
'CXR': 'Île Christmas',
'CYM': 'Caimans',
'CYP': 'Chypre',
'CZE': 'Tchéquie',
'DEU': 'Allemagne',
'DJI': 'Djibouti',
'DMA': 'Dominique',
'DNK': 'Danemark',
'DOM': 'République dominicaine',
'DZA': 'Algérie',
'ECU': 'Equateur',
'EGY': 'Egypte',
'ERI': 'Erythrée',
'ESH': 'Sahara occidental',
'ESP': 'Espagne',
'EST': 'Estonie',
'ETH': 'Ethiopie',
'FIN': 'Finlande',
'FJI': 'Fidji',
'FLK': 'Îles Malouines',
'FRA': 'France',
'FRO': 'Féroé',
'FSM': 'Micronésie',
'GAB': 'Gabon',
'GBR': 'Royaume-Uni',
'GEO': 'Géorgie',
'GGY': 'Guernesey',
'GHA': 'Ghana',
'GIB': 'Gibraltar',
'GIN': 'Guinée',
'GLP': 'Guadeloupe',
'GMB': 'Gambie',
'GNB': 'Guinée-Bissau',
'GNQ': 'Guinée équatoriale',
'GRC': 'Grèce',
'GRD': 'Grenade',
'GRL': 'Groenland',
'GTM': 'Guatemala',
'GUF': 'Guyane',
'GUM': 'Guam',
'GUY': 'Guyana',
'HKG': 'Hong Kong',
'HND': 'Honduras',
'HRV': 'Croatie',
'HTI': 'Haïti',
'HUN': 'Hongrie',
'IDN': 'Indonésie',
'IMN': 'Île de Man',
'IND': 'Inde',
'IOT': "Territoire britannique de l'océan Indien",
'IRL': 'Irlande',
'IRN': 'Irak',
'IRQ': 'Iran',
'ISL': 'Islande',
'ISR': 'Israël',
'ITA': 'Italie',
'JAM': 'Jamaïque',
'JEY': 'Jersey',
'JOR': 'Jordanie',
'JPN': 'Japon',
'KAZ': 'Kazakhstan',
'KEN': 'Kenya',
'KGZ': 'Kirghizistan',
'KHM': 'Cambodge',
'KIR': 'Kiribati',
'KNA': 'Saint-Christophe-et-Niévès',
'KOR': 'Corée du Sud',
'KWT': 'Koweït',
'LAO': 'Laos',
'LBN': 'Liban',
'LBR': 'Liberia',
'LBY': 'Libye',
'LCA': 'Sainte-Lucie',
'LIE': 'Liechtenstein',
'LKA': 'Sri Lanka',
'LSO': 'Lesotho',
'LTU': 'Lituanie',
'LUX': 'Luxembourg',
'LVA': 'Lettonie',
'MAC': 'Macao',
'MAF': 'Sint-Maarten',
'MAR': 'Maroc',
'MCO': 'Monaco',
'MDA': 'Moldavie',
'MDG': 'Madagascar',
'MDV': 'Maldives',
'MEX': 'Mexique',
'MHL': 'Marshall',
'MKD': 'Macedoine',
'MLI': 'Mali',
'MLT': 'Malte',
'MMR': 'Birmanie',
'MNE': 'Monténégro',
'MNG': 'Mongolie',
'MNP': 'Îles Mariannes du Nord',
'MOZ': 'Mozambique',
'MRT': 'Mauritanie',
'MSR': 'Montserrat',
'MTQ': 'Martinique',
'MUS': 'Maurice',
'MWI': 'Malawi',
'MYS': 'Malaisie',
'MYT': 'Mayotte',
'NAM': 'Namibie',
'NCL': 'Nouvelle-Calédonie',
'NER': 'Niger',
'NFK': 'Île Norfolk',
'NGA': 'Nigeria',
'NIC': 'Nicaragua',
'NIU': 'Niue',
'NLD': 'Pays-Bas',
'NOR': 'Norvège',
'NPL': 'Nepal',
'NRU': 'Nauru',
'NZL': 'Nouvelle-Zélande',
'OMN': 'Oman',
'PAK': 'Pakistan',
'PAN': 'Panama',
'PCN': 'Îles Pitcairn',
'PER': 'Pérou',
'PHL': 'Philippines',
'PLW': 'Palaos',
'PNG': 'Papouasie-Nouvelle-Guinée',
'POL': 'Pologne',
'PRI': 'Porto Rico',
'PRK': 'Corée du Nord',
'PRT': 'Portugal',
'PRY': 'Paraguay',
'PSE': 'Palestine',
'PYF': 'Polynésie française',
'QAT': 'Qatar',
'REU': 'Réunion',
'ROU': 'Roumanie',
'RUS': 'Russie',
'RWA': 'Rwanda',
'SAU': 'Arabie saoudite',
'SDN': 'Soudan',
'SEN': 'Sénégal',
'SGP': 'Singapour',
'SGS': 'Georgie du Sud-et-les iles Sandwich du Sud',
'SHN': 'Sainte-Hélène, Ascension et Tristan da Cunha',
'SJM': 'Svalbard et île Jan Mayen',
'SLB': 'Salomon',
'SLE': 'Sierra Leone',
'SLV': 'Salvador',
'SMR': 'Saint-Marin',
'SOM': 'Somalie',
'SPM': 'Saint-Pierre-et-Miquelon',
'SRB': 'Serbie',
'SSD': 'Soudan du Sud',
'STP': 'Sao Tomé-et-Principe',
'SUR': 'Suriname',
'SVK': 'Slovaquie',
'SVN': 'Slovénie',
'SWE': 'Suède',
'SWZ': 'eSwatani',
'SXM': 'Saint-Martin ',
'SYC': 'Seychelles',
'SYR': 'Syrie',
'TCA': 'Îles Turques-et-Caïques',
'TCD': 'Tchad',
'TGO': 'Togo',
'THA': 'Thaïlande',
'TJK': 'Tadjikistan',
'TKL': 'Tokelau',
'TKM': 'Turkmenistan',
'TLS': 'Timor oriental',
'TON': 'Tonga',
'TTO': 'Trinité-et-Tobago',
'TUN': 'Tunisie',
'TUR': 'Turquie',
'TUV': 'Tuvalu',
'TWN': 'Taiwan',
'TZA': 'Tanzanie',
'UGA': 'Ouganda',
'UKR': 'Ukraine',
'URY': 'Uruguay',
'USA': 'Etats-Unis',
'UZB': 'Ouzbékistan',
'VAT': 'Saint-Siège (État de la Cité du Vatican)',
'VCT': 'Saint-Vincent-et-les-Grenadines',
'VEN': 'Venezuela',
'VGB': 'Îles Vierges britanniques',
'VIR': 'Îles Vierges des États-Unis',
'VNM': 'Viêt Nam',
'VUT': 'Vanuatu',
'WLF': 'Wallis-et-Futuna',
'WSM': 'Samoa',
'XKX': 'Kosovo',
'YEM': 'Yémen',
'ZAF': 'Afrique du Sud',
'ZMB': 'Zambie',
'ZWE': 'Zimbabwe',
'NTZ': 'Zone neutre',
'UNO': 'Fonctionnaire des Nations Unies',
'UNA': "Fonctionnaire d'une organisation affiliée aux Nations Unies",
'UNK': 'Représentant des Nations Unies au Kosovo',
'XXA': 'Apatride Convention 1954',
'XXB': 'Réfugié Convention 1954',
'XXC': 'Réfugié autre',
'XXX': 'Résident Légal de Nationalité Inconnue',
'D': 'Allemagne',
'EUE': 'Union Européenne',
'GBD': "Citoyen Britannique d'Outre-mer (BOTC)",
'GBN': 'British National (Overseas)',
'GBO': 'British Overseas Citizen',
'GBP': 'British Protected Person',
'GBS': 'British Subject',
'XBA': 'Banque Africaine de Développement',
'XIM': "Banque Africaine d'ExportImport",
'XCC': 'Caribbean Community or one of its emissaries',
'XCO': 'Common Market for Eastern and Southern Africa',
'XEC': 'Economic Community of West African States',
'XPO': 'International Criminal Police Organization',
'XOM': 'Sovereign Military Order of Malta',
'RKS': 'Kosovo',
'WSA': 'World Service Authority World Passport'
}
## DOCUMENTS TYPES ## DOCUMENTS TYPES
@ -577,7 +60,7 @@ P = [
"D": ["1", "CTRLF", "[0-9]", "C"], "D": ["1", "CTRLF", "[0-9]", "C"],
"E": ["1", "CTRL", "[0-9]", "4578ABCD"] "E": ["1", "CTRL", "[0-9]", "4578ABCD"]
}, },
"Passeport" lang.all[globs.CNIRlang]["Passeport"]
] ]
IP = [ IP = [
@ -597,7 +80,7 @@ IP = [
"C": ["11", "FACULT", ".+"], "C": ["11", "FACULT", ".+"],
"D": ["1", "CTRL", "[0-9]", "345679AC"] "D": ["1", "CTRL", "[0-9]", "345679AC"]
}, },
"Carte-passeport" lang.all[globs.CNIRlang]["Carte-passeport"]
] ]
I_ = [ I_ = [
@ -617,7 +100,7 @@ I_ = [
"C": ["11", "FACULT", ".+"], "C": ["11", "FACULT", ".+"],
"D": ["1", "CTRL", "[0-9]", "345679AC"] "D": ["1", "CTRL", "[0-9]", "345679AC"]
}, },
"Titre d'identité/de voyage" lang.all[globs.CNIRlang]["Titre d'identité/de voyage"]
] ]
AC = [ AC = [
@ -638,7 +121,7 @@ AC = [
"C": ["11", "FACULT", ".+"], "C": ["11", "FACULT", ".+"],
"D": ["1", "CTRL", "[0-9]","345679AC"] "D": ["1", "CTRL", "[0-9]","345679AC"]
}, },
"Certificat de membre d'équipage" lang.all[globs.CNIRlang]["Certificat de membre d'équipage"]
] ]
VA = [ VA = [
@ -657,7 +140,7 @@ VA = [
"B": ["1", "CTRL", "[0-9]", "A"], "B": ["1", "CTRL", "[0-9]", "A"],
"C": ["16", "FACULT", ".+"] "C": ["16", "FACULT", ".+"]
}, },
"Visa de type A" lang.all[globs.CNIRlang]["Visa de type A"]
] ]
VB = [ VB = [
@ -676,7 +159,7 @@ VB = [
"B": ["1", "CTRL", "[0-9]", "A"], "B": ["1", "CTRL", "[0-9]", "A"],
"C": ["8", "FACULT", ".+"] "C": ["8", "FACULT", ".+"]
}, },
"Visa de type B" lang.all[globs.CNIRlang]["Visa de type B"]
] ]
TSF = [ TSF = [
@ -695,7 +178,7 @@ TSF = [
"B": ["1", "CTRL", "[0-9]", "A"], "B": ["1", "CTRL", "[0-9]", "A"],
"C": ["8", "FACULT", ".+"] "C": ["8", "FACULT", ".+"]
}, },
"Carte de séjour" lang.all[globs.CNIRlang]["Carte de séjour"]
] ]
I__ = [ I__ = [
@ -715,7 +198,7 @@ I__ = [
"C": ["7", "FACULT", ".+"], "C": ["7", "FACULT", ".+"],
"D": ["1", "CTRL", "[0-9]", "4578ABC"] "D": ["1", "CTRL", "[0-9]", "4578ABC"]
}, },
"Pièce d'identité/de voyage" lang.all[globs.CNIRlang]["Pièce d'identité/de voyage"]
] ]
IDFR = [ IDFR = [
@ -735,7 +218,7 @@ IDFR = [
"C": ["1", "SEX", "[A-Z]"], "C": ["1", "SEX", "[A-Z]"],
"D": ["1", "CTRL", "[0-9]", "123456789ABCE"] "D": ["1", "CTRL", "[0-9]", "123456789ABCE"]
}, },
"Pièce d'identité FR" lang.all[globs.CNIRlang]["Pièce d'identité FR"]
] ]
DL = [ DL = [
@ -749,7 +232,7 @@ DL = [
"6": ["8", "NOM", "([A-Z]|<)+"], "6": ["8", "NOM", "([A-Z]|<)+"],
"7": ["1", "CTRL", "[0-9]", "123456"] "7": ["1", "CTRL", "[0-9]", "123456"]
}, },
"Permis de conduire" lang.all[globs.CNIRlang]["Permis de conduire"]
] ]
TYPES = [IDFR, I__, VB, VA, AC, I_, IP, P, DL, TSF] TYPES = [IDFR, I__, VB, VA, AC, I_, IP, P, DL, TSF]
@ -1011,6 +494,14 @@ def getDocInfos(doc, code):
res["INDIC"] += value res["INDIC"] += value
except KeyError: except KeyError:
res["INDIC"] = value res["INDIC"] = value
# Sex
elif field[0] == 'SEX':
if not value in "MF":
res[field[0]] = False
else:
res[field[0]] = value
# All other cases # All other cases
else: else:
if value != "": if value != "":

View File

@ -80,6 +80,14 @@ def exitProcess(arg):
if process.pid == os.getpid(): if process.pid == os.getpid():
process.terminate() process.terminate()
sys.exit(arg) sys.exit(arg)
def updateChannel(choice):
if choice == "Beta":
with open(globs.CNIRUrlConfig, 'w') as (configFile):
configFile.write("{}\n0\n0".format(globs.CNIRBetaURL))
else:
with open(globs.CNIRUrlConfig, 'w') as (configFile):
configFile.write("{}\n0\n0".format(globs.CNIRDefaultURL))
def getLatestVersion(credentials): def getLatestVersion(credentials):
""" """
@ -114,7 +122,7 @@ def getLatestVersion(credentials):
except: except:
pass pass
with open(globs.CNIRUrlConfig, 'w') as (configFile): with open(globs.CNIRUrlConfig, 'w') as (configFile):
configFile.write("https://raw.githubusercontent.com/neox95/CNIRevelator/master/VERSIONS.LST\n0\n0") configFile.write("{}\n0\n0".format(globs.CNIRDefaultURL))
# Getting the list of versions of the software # Getting the list of versions of the software
logfile.printdbg('Retrieving the software versions') logfile.printdbg('Retrieving the software versions')