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

New language system, some changes on the update system

This commit is contained in:
Adrien Bourmault 2019-08-12 17:07:37 +02:00 committed by GitHub
parent 1548fae87b
commit 2df174b234
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 493 additions and 216 deletions

View File

@ -28,14 +28,17 @@ import sys
import os
import subprocess
import threading
import traceback
import psutil
from tkinter import *
from tkinter.messagebox import *
import launcher # launcher.py"
import updater # updater.py
import globs # globs.py
import pytesseract # pytesseract.py
import logger # logger.py
import lang # lang.py
import ihm # ihm.py
from main import * # main.py
@ -59,15 +62,15 @@ def main():
text = 'Tesseract version ' + str(tesser_version) + ' Licensed Apache 2004 successfully initiated\n'
mainw.logOnTerm(text)
mainw.logOnTerm('\n\nEntrez la première ligne de MRZ svp \n')
mainw.logOnTerm('\n\n{} \n'.format(lang.all[globs.CNIRlang]["Please type a MRZ or open a scan"]))
if globs.CNIRNewVersion:
showinfo('Changelog : résumé de mise à jour', ('Version du logiciel : CNIRevelator ' + globs.verstring_full + '\n\n' + globs.changelog), parent=mainw)
showinfo("Changelog : update summary", ('{} : CNIRevelator {}\n\n{}'.format(lang.all[globs.CNIRlang]["Program version"], globs.verstring_full, globs.changelog)), parent=mainw)
logfile.printdbg('main() : **** Launching App_main() ****')
try:
mainw.mainloop()
except Exception as e:
showerror("CNIRevelator Fatal Error", "An error has occured : {}".format(e), parent=mainw)
showerror(lang.all[globs.CNIRlang]["CNIRevelator Fatal Error"], "{} : {}".format(lang.all[globs.CNIRlang]["An error has occured"],e), parent=mainw)
logfile.printdbg('main() : **** Ending App_main() ****')
logfile.printdbg('*** CNIRevelator LOGFILE. Goodbye World ! ***')
@ -76,15 +79,36 @@ def main():
## BOOTSTRAP OF CNIREVELATOR
# 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:
with open(globs.CNIRLangFile, 'w') as (configFile):
try:
# Writing it
configFile.write(globs.CNIRlang)
except Exception as e:
ihm.crashCNIR()
raise IOError(str(e))
# 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 ' + globs.CNIRFolder
args = updater.UPATH + '\\CNIRevelator.exe' + " DELETE " + globs.CNIRFolder
cd = updater.UPATH
for i in range(0,3):
try:
@ -99,6 +123,6 @@ if updater.UPDATE_IS_MADE:
try:
main()
except Exception as e:
traceback.print_exc(file=sys.stdout)
ihm.crashCNIR()
updater.exitProcess(0)

View File

@ -35,6 +35,7 @@ from time import time
import logger # logger.py
import globs # globs.py
import ihm # ihm.py
import lang # lang.py
class AESCipher(object):
@ -184,8 +185,8 @@ class newdownload:
reducedFilename = filename.split("\\")[-1]
launcherWindow.printmsg('Downloading {}'.format(title))
logfile.printdbg('Requesting download of {}'.format(reducedFilename))
launcherWindow.printmsg('{} {}'.format(lang.all[globs.CNIRlang]["Downloading"], title))
logfile.printdbg('{} {}'.format("Downloading", reducedFilename))
try:
os.remove(filename)
@ -201,12 +202,12 @@ class newdownload:
launcherWindow.progressBar.stop()
launcherWindow.progressBar.configure(mode='determinate', value=(int(Percent)), maximum=100)
launcherWindow.printmsg('Downloading {}'.format(title) + ' : {:4.2f} %'.format(Percent))
launcherWindow.printmsg('{} {}'.format(lang.all[globs.CNIRlang]["Downloading"], title) + ' : {:4.2f} %'.format(Percent))
launcherWindow.progressBar.configure(mode='indeterminate', value=0, maximum=20)
launcherWindow.progressBar.start()
logfile.printdbg('Successful retrieved {}'.format(filename))
logfile.printdbg('{} {}'.format(lang.all[globs.CNIRlang]["Successful retrieved"], filename))
return filename

View File

@ -31,7 +31,7 @@ verstring_full = "{}.{}.{} {}".format(version[0], version[1], version[2], v
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"
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()
@ -39,6 +39,8 @@ CNIRLColor = "#006699"
CNIRName = "CNIRevelator {}".format(verstring)
CNIRCryptoKey = '82Xh!efX3#@P~2eG'
CNIRNewVersion = False
CNIRLangFile = CNIRFolder + '\\config\\lang.ig'
CNIRlang = "fr"
CNIRConfig = CNIRFolder + '\\config\\conf.ig'
CNIRTesser = CNIRFolder + '\\Tesseract-OCR4\\'
@ -47,3 +49,5 @@ CNIRMainLog = CNIRFolder + '\\logs\\main.log'
CNIRUrlConfig = CNIRFolder + '\\config\\urlconf.ig'
CNIRVerStock = CNIRFolder + '\\downloads\\versions.lst'
CNIREnv = CNIRFolder + '\\Data\\'
CNIROpenFile = True

View File

@ -24,14 +24,17 @@
"""
from tkinter import *
import webbrowser
from tkinter.messagebox import *
from tkinter import filedialog
from tkinter import ttk
import cv2
import PIL.Image, PIL.ImageTk
import traceback
import logger # logger.py
import globs # globs.py
import lang # lang.py
controlKeys = ["Escape", "Right", "Left", "Up", "Down", "Home", "End", "BackSpace", "Delete", "Inser", "Shift_L", "Shift_R", "Control_R", "Control_L"]
@ -42,7 +45,7 @@ class DocumentAsk(Toplevel):
self.choice = 0
vals = [0, 1]
super().__init__(parent)
self.title("Choisir le document d'identité :")
self.title("{} :".format(lang.all[globs.CNIRlang]["Choose the identity document"]))
ttk.Radiobutton(self, text=choices[0], command=self.register0, value=vals[0]).pack()
ttk.Radiobutton(self, text=choices[1], command=self.register1, value=vals[1]).pack()
@ -68,19 +71,19 @@ class DocumentAsk(Toplevel):
self.choice = 1
def ok(self):
self.destroy()
class OpenScanDialog(Toplevel):
def __init__(self, parent, text):
super().__init__(parent)
self.parent = parent
self.title('Validation de la MRZ détectée par OCR')
self.title(lang.all[globs.CNIRlang]["OCR Detection Validation"])
self.resizable(width=False, height=False)
self.termtext = Text(self, state='normal', width=45, height=2, wrap='none', font='Terminal 17', fg='#121f38')
self.termtext.grid(column=0, row=0, sticky='NEW', padx=5, pady=5)
self.termtext.insert('end', text + '\n')
self.button = Button(self, text='Valider', command=(self.valid))
self.button = Button(self, text=lang.all[globs.CNIRlang]["Validate"], command=(self.valid))
self.button.grid(column=0, row=1, sticky='S', padx=5, pady=5)
self.update()
hs = self.winfo_screenheight()
@ -102,27 +105,27 @@ class OpenScanDialog(Toplevel):
for i in range(len(texting)):
for char in texting[i]:
if char not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789<':
showerror('Erreur de validation', 'La MRZ soumise contient des caractères invalides', parent=self)
showerror(lang.all[globs.CNIRlang]["Validation Error"], lang.all[globs.CNIRlang]["The submitted MRZ contains invalid characters"], parent=self)
self.parent.validatedtext = ''
self.destroy()
class LoginDialog(Toplevel):
def __init__(self, parent):
self.key = ''
self.login = ''
super().__init__(parent)
self.title('Connexion')
self.title(lang.all[globs.CNIRlang]["Connection"])
Label(self, text='IPN : ').pack()
self.entry_login = Entry(self)
self.entry_login.insert(0, '')
self.entry_login.pack()
Label(self, text='Mot de passe : ').pack()
Label(self, text='{} : '.format(lang.all[globs.CNIRlang]["Password"])).pack()
self.entry_pass = Entry(self, show='*')
self.entry_pass.insert(0, '')
self.entry_pass.pack()
Button(self, text='Connexion', command=(self.connecti)).pack()
Button(self, text=lang.all[globs.CNIRlang]["Connection"], command=(self.connecti)).pack()
self.resizable(width=False, height=False)
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
@ -185,7 +188,7 @@ class LauncherWindow(Tk):
self.mainCanvas.create_text((wwidth / 2), (wheight / 3), text=(globs.CNIRName), font='Helvetica 30', fill='white')
self.mainCanvas.create_text((wwidth / 2), (wheight / 2), text="version " + (globs.verstring_full), font='Helvetica 8', fill='white')
self.msg = self.mainCanvas.create_text((wwidth / 2), (wheight / 1.20), text='Booting up...', font='Helvetica 9', fill='white')
self.msg = self.mainCanvas.create_text((wwidth / 2), (wheight / 1.20), text=lang.all[globs.CNIRlang]["Booting up..."], font='Helvetica 9', fill='white')
#self.pBarZone = Frame(self.mainCanvas, width=wwidth, height=wheight/10)
self.update()
@ -205,7 +208,8 @@ class LauncherWindow(Tk):
self.iconbitmap('id-card.ico')
logfile = logger.logCur
logfile.printdbg('Launcher IHM successful')
self.protocol('WM_DELETE_WINDOW', lambda : self.destroy())
self.protocol('WM_DELETE_WINDOW', lambda : 0)
self.attributes("-topmost", 1)
self.update()
@ -230,7 +234,24 @@ class ResizeableCanvas(Canvas):
self.height = event.height
# rescale all the objects tagged with the "all" tag
self.scale("all",0,0,wscale,hscale)
def crashCNIR():
"""
last solution
"""
# Global handler
logfile = logger.logCur
# hide main window
root = Tk()
root.withdraw()
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"])
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":
webbrowser.open_new("https://github.com/neox95/CNIRevelator/issues")
root.destroy()
## Global Handler
launcherWindowCur = LauncherWindow()

299
src/lang.py Normal file
View File

@ -0,0 +1,299 @@
"""
********************************************************************************
* CNIRevelator *
* *
* Desc: Application langage file *
* *
* Copyright © 2018-2019 Adrien Bourmault (neox95) *
* *
* This file is part of CNIRevelator. *
* *
* 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. *
* *
* CNIRevelator is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY*without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with CNIRevelator. If not, see <https:*www.gnu.org/licenses/>. *
********************************************************************************
"""
import globs # globs.py
## FRENCH LANGUAGE
french = \
{
"Please type a MRZ or open a scan" : "Veuillez taper une MRZ ou ouvrir un scan svp",
"Changelog : update summary" : "Changelog : résumé de mise à jour",
"Program version" : "Version du logiciel",
"CNIRevelator Fatal Error" : "Erreur fatale de CNIRevelator",
"An error has occured" : "Une erreur s'est produite",
"Downloading" : "Téléchargement de",
"Successful retrieved" : "Réussite du téléchargement de",
"Choose the identity document" : "Choisir le document d'identité",
"OCR Detection Validation" : "Validation de la MRZ détectée par OCR",
"Validate" : "Valider",
"Validation Error" : "Erreur de validation",
"The submitted MRZ contains invalid "
"characters" : "La MRZ soumise contient des caractères invalides",
"Connection" : "Connexion",
"Password" : "Mot de passe",
"Booting up..." : "Démarrage",
"CNIRevelator Fatal Eror" : "Erreur Fatale de CNIRevelator",
"CNIRevelator crashed because a "
"fatal error occured. View log for "
"more infos and please open "
"an issue on Github" : "CNIRevelator s'est arrêté car une erreur fatale s'est produite. Consultez le journal pour plus d'informations et ouvrez s'il vous plaît un ticket sur Github.",
"Would you like to open an issue "
"on Github to report this bug ?" : "Souhaitez-vous ouvrir un ticket sur Github pour signaler ce bogue?",
"Starting..." : "Lancement...",
"Informations about the current "
"document" : "Informations sur la pièce d'identité",
"IDLE" : "EN ATTENTE",
"Status" : "Statut",
"Name" : "Nom",
"Birth date" : "Date de naissance",
"Issue date" : "Date de délivrance",
"Expiration date" : "Date d'expiration",
"Sex" : "Sexe",
"Issuing country" : "Pays émetteur",
"Nationality" : "Nationalité",
"Registration" : "Immatriculation",
"Document number" : "Numéro de document",
"Unknown" : "Inconnu(e)",
"Display and processing of "
"documents" : "Affichage et traitement de documents",
"Complete MRZ capture terminal" : "Terminal de saisie de MRZ complète",
"Quick entry terminal (731)" : "Terminal de saisie rapide (731)",
"Monitor" : "Moniteur",
"New" : "Nouveau",
"Open scan..." : "Ouvrir scan...",
"Quit" : "Quitter",
"File" : "Fichier",
"Keyboard commands" : "Commandes au clavier",
"Report a bug" : "Signaler un problème",
"About CNIRevelator" : "A propos de CNIRevelator",
"Help" : "Aide",
"OCR module error" : "Erreur du module OCR",
"The OCR module located at {} "
"can not be found or corrupted. "
"It will be reinstalled at "
"the next run" : "Le module OCR localisé en {} est introuvable ou corrompu. Il sera réinstallé à la prochaine exécution",
"The Tesseract module "
"encountered a problem: {}" : "Le module Tesseract a rencontré un problème : {}",
"Tesseract error : {}. "
"Will be reinstallated" : "Erreur de Tesseract : {}. Le module sera réinstallé",
"Document detected: {}\n" : "Document detecté : {}\n",
"Document detected again: {}\n" : "Document re-detecté : {}\n",
"Character not accepted !\n" : "Caractère non accepté !\n",
"Open a scan of document..." : "Ouvrir un scan de document...",
"OpenCV error (image processing)" : "Erreur OpenCV (traitement d'images)",
"A critical error has occurred in "
"the OpenCV image processing "
"manager used by CNIRevelator, the "
"application will reset itself" : "Une erreur critique s'est produite dans le gestionnaire de traitement d'images OpenCV utilisé par CNIRevelator. L'application va se réinitialiser",
"ABOUT" : 'Version du logiciel : CNIRevelator ' + globs.verstring_full + '\n\n'
"Copyright © 2018-2019 Adrien Bourmault (neox95)" + "\n\n"
"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"
"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"
"Le module d'OCR Tesseract 4.0 est soumis à l'Apache License 2004."
"\n\n"
"Les bibliothèques python et l'environnement Anaconda 3 sont soumis à la licence BSD 2018-2019."
"\n\n"
"Le code source de ce programme est disponible sur Github à l'adresse <https://github.com/neox95/CNIRevelator>.\n"
"Son fonctionnement est conforme aux normes et directives du document 9303 de l'OACI régissant les documents de voyages et d'identité." + '\n\n'
" En cas de problèmes ou demande particulière, ouvrez-y une issue ou bien envoyez un mail à neox@os-k.eu !\n\n",
"KEYBHELP" : "Terminal de saisie rapide (731) : \n\n"
"Caractères autorisés : Alphanumériques en majuscule et le caractère '<'. Pas de minuscules ni caractères spéciaux, autrement la somme est mise à zéro \n\n"
"Calculer résultat :\t\t\tTouche Ctrl droite \n"
"Copier :\t\t\t\tCtrl-C \n"
"Coller :\t\t\t\tCtrl-V \n"
"\n\n"
"Terminal de saisie MRZ complète : \n\n"
"Caractères autorisés : Alphanumériques en majuscule et le caractère '<'. Pas de minuscules ni caractères spéciaux, autrement la somme est mise à zéro \n\n"
"Calculer résultat :\t\t\tTouche Ctrl droite \n"
"Compléter champ :\t\t\tTouche Tab \n"
"Copier :\t\t\t\tCtrl-C \n"
"Coller :\t\t\t\tCtrl-V \n"
"Forcer une nouvelle détection du document :\tEchap\n",
"Document Review: {}\n\n" : "Examen du document : {}\n\n",
"Check sum position {}: Lu {} VS "
"Calculated {} and {}\n" : "Check sum position {}: Lu {} VS Calculated {} and {}\n",
"COMPLIANT" : "CONFORME",
"IMPROPER" : "NON CONFORME",
"Installing the updates" : "Installation des mises-à-jour",
"Verifying download..." : "Vérification du téléchargement ...",
"Preparing installation..." : "Préparation de l'installation",
"Success !" : "Installation terminée !",
"Launching the new version..." : "Lancement de la nouvelle version...",
"Credentials Error. No effective "
"update !" : "Identifiants incorrects. Pas de mise-à-jour !",
"Deleting old version" : "Suppression de l'ancienne version",
'Software is up-to-date !' : "Logiciel à jour !",
"An error occured. "
"No effective update !" : "Une erreur s'est produite. Pas de mise-à-jour !",
"Shortcut creation" : "Création de raccourci",
"Would you like to create/update "
"the shortcut for CNIRevelator "
"on your desktop ?" : "Souhaitez vous créer/mettre à jour le raccourci pour CNIRevelator sur votre bureau ?",
"The file you provided is "
"not found : {}" : "Fichier transmis non trouvé : {}"
}
## ENGLISH LANGUAGE
english = \
{
"Please type a MRZ or open a scan" : "Please type a MRZ or open a scan",
"Changelog : update summary" : "Changelog : update summary",
"Program version" : "Program version",
"CNIRevelator Fatal Error" : "CNIRevelator Fatal Error" ,
"An error has occured" : "An error has occured",
"Downloading" : "Downloading",
"Successful retrieved" : "Successful retrieved",
"Choose the identity document" : "Choose the identity document" ,
"OCR Detection Validation" : "OCR Detection Validation",
"Validate" : "Validate",
"Validation Error" : "Validation Error",
"The submitted MRZ contains invalid "
"characters" : "The submitted MRZ contains invalid characters",
"Connection" : "Connection",
"Password" : "Password",
"Booting up..." : "Booting up...",
"CNIRevelator Fatal Eror" : "CNIRevelator Fatal Eror",
"CNIRevelator crashed because a "
"fatal error occured. View log for "
"more infos and please open "
"an issue on Github" : "CNIRevelator crashed because a fatal error occured. View log for more infos and please open an issue on Github",
"Would you like to open an issue "
"on Github to report this bug ?" : "Would you like to open an issue on Github to report this bug ?",
"Starting..." : "Starting...",
"Informations about the current "
"document" : "Informations about the current document",
"IDLE" : "IDLE",
"Status" : "Status",
"Name" : "Name",
"Birth date" : "Birth date",
"Issue date" : "Date de délivrance",
"Expiration date" : "Issue date",
"Sex" : "Sex",
"Issuing country" : "Issuing country",
"Nationality" : "Nationality",
"Registration" : "Registration",
"Document number" : "Document number",
"Unknown" : "Unknown",
"Display and processing of "
"documents" : "Display and processing of documents",
"Complete MRZ capture terminal" : "Complete MRZ capture terminal",
"Quick entry terminal (731)" : "Quick entry terminal (731)",
"Monitor" : "Monitor",
"New" : "New",
"Open scan..." : "Open scan...",
"Quit" : "Quit",
"File" : "File",
"Keyboard commands" : "Keyboard commands",
"Report a bug" : "Report a bug",
"About CNIRevelator" : "About CNIRevelator",
"Help" : "Help",
"OCR module error" : "OCR module error",
"The OCR module located at {} "
"can not be found or corrupted. "
"It will be reinstalled at "
"the next run" : "The OCR module located at {} can not be found or corrupted. It will be reinstalled at the next run",
"The Tesseract module "
"encountered a problem: {}" : "The Tesseract module encountered a problem: {}",
"Tesseract error : {}. "
"Will be reinstallated" : "Tesseract error : {}. Will be reinstallated",
"Document detected: {}\n" : "Document detected : {}\n",
"Document detected again: {}\n" : "Document detected again : {}\n",
"Character not accepted !\n" : "Character not accepted !\n",
"Open a scan of document..." : "Open a scan of document...",
"OpenCV error (image processing)" : "OpenCV error (image processing)",
"A critical error has occurred in "
"the OpenCV image processing "
"manager used by CNIRevelator, the "
"application will reset itself" : "A critical error has occurred in the OpenCV image processing manager used by CNIRevelator, the application will reset itself",
"ABOUT" : 'Software Version: CNIRevelator' + globs.verstring_full + '\n\n'
"Copyright © 2018-2019 Adrien Bourmault (neox95)" + "\n\n"
"CNIRevelator is free software: you have the right to modify and / or distribute it"
"in the terms of the GNU General Public License as published by"
"Free Software Foundation, version 3 or"
"later." + "\n\n"
"CNIRevelator is distributed in the hope of being useful, without however"
"imply any guarantee of"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE Refer to the"
"GNU General Public License for more details about this."
"\n\n"
"You should have received a copy of the GNU General Public License"
"with CNIRevelator, if this is not the case, take a look at <https://www.gnu.org/licenses/>."
"\n\n"
"The Tesseract 4.0 OCR module is subject to the 2004 Apache License."
"\n\n"
"Python libraries and the Anaconda 3 environment are subject to the BSD 2018-2019 license."
"\n\n"
"The source code for this program is available on Github at <https://github.com/neox95/CNIRevelator>. \n"
"Its operation is in accordance with the standards and guidelines of ICAO document 9303 governing travel and identity documents." + '\n\n'
"In case of problems or special request, open an issue or send an email to neox@os-k.eu! \n\n",
"KEYBHELP" : "Fast entry terminal (731): \n\n"
"Allowed characters: Alphanumeric uppercase and the character '<' No lowercase or special characters, otherwise the sum is set to zero \n\n"
"Calculate Result:\t\t\tControl Right\n"
"Copy:\t\t\t\tCtrl-C\n"
"Paste:\t\t\t\tCtrl-V\n"
"\n\n"
"MRZ input terminal complete: \n\n"
"Allowed characters: Alphanumeric uppercase and the character '<' No lowercase or special characters, otherwise the sum is set to zero \n\n"
"Calculate Result:\t\t\tControl Right\n"
"Complete field:\t\t\tTab button\n"
"Copy:\t\t\t\tCtrl-C\n"
"Paste:\t\t\t\tCtrl-V\n"
"Force a new document detection:\tEchap\n",
"Document Review: {}\n\n" : "Document Review: {}\n\n",
"Check sum position {}: Lu {} VS "
"Calculated {} and {}\n" : "Check sum position {}: Lu {} VS Calculated {} and {}\n",
"COMPLIANT" : "COMPLIANT",
"IMPROPER" : "IMPROPER",
"Installing the updates" : "Installing the updates",
"Verifying download..." : "Verifying download...",
"Preparing installation..." : "Preparing installation...",
"Success !" : "Success !",
"Launching the new version..." : "Launching the new version...",
"Credentials Error. No effective "
"update !" : "Credentials Error. No effective update !",
"Deleting old version" : "Deleting old version",
'Software is up-to-date !' : "Software is up-to-date !",
"An error occured. "
"No effective update !" : "An error occured. No effective update !",
"Shortcut creation" : "Shortcut creation",
"Would you like to create/update "
"the shortcut for CNIRevelator on "
"your desktop ?" : "Would you like to create/update the shortcut for CNIRevelator on your desktop ?",
"The file you provided is not "
"found : {}" : "The file you provided is not found : {}"
}
## MAIN DICT
all = \
{
"fr" : french,
"en" : english
}

View File

@ -26,12 +26,12 @@
import sys
import os
import threading
import traceback
import updater # updater.py
import ihm # ihm.py
import globs # globs.py
import logger # logger.py
import lang # lang.py
## Main function
def lmain(mainThread):
@ -44,7 +44,7 @@ def lmain(mainThread):
# Hello user
launcherWindow.progressBar.configure(mode='indeterminate', value=0, maximum=20)
launcherWindow.printmsg('Starting...')
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Starting..."])
launcherWindow.progressBar.start()
# Starting the main update thread

View File

@ -32,17 +32,18 @@ from tkinter import ttk
import threading
from datetime import datetime
import re
import traceback
import cv2
import PIL.Image, PIL.ImageTk
import os, shutil
import webbrowser
import sys, os
import ihm # ihm.py
import logger # logger.py
import mrz # mrz.py
import globs # globs.py
import pytesseract # pytesseract.py
import lang # lang.py
# Global handler
logfile = logger.logCur
@ -78,7 +79,7 @@ class mainWindow(Tk):
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é")
self.lecteur_ci = ttk.Labelframe(self, text=lang.all[globs.CNIRlang]["Informations about the current document"])
self.lecteur_ci.grid_columnconfigure(0, weight=1)
self.lecteur_ci.grid_columnconfigure(1, weight=1)
self.lecteur_ci.grid_columnconfigure(2, weight=1)
@ -92,50 +93,50 @@ class mainWindow(Tk):
self.lecteur_ci.grid_rowconfigure(5, weight=1)
# Fill the data sections
ttk.Label((self.lecteur_ci), text='Statut : ').grid(column=0, row=0, padx=5, pady=5)
self.STATUStxt = ttk.Label((self.lecteur_ci), text='EN ATTENTE', font=("TkDefaultFont", 13, "bold"), foreground="orange", anchor=CENTER)
ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Status"])).grid(column=0, row=0, padx=5, pady=5)
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)
ttk.Label((self.lecteur_ci), text='Nom : ').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)
self.nom = ttk.Label((self.lecteur_ci), text=' ')
self.nom.grid(column=1, row=1, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='Nom (2) : ').grid(column=0, row=2, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='{} (2) : '.format(lang.all[globs.CNIRlang]["Name"])).grid(column=0, row=2, padx=5, pady=5)
self.prenom = ttk.Label((self.lecteur_ci), text=' ')
self.prenom.grid(column=1, row=2, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='Date de naissance : ').grid(column=0, row=3, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Birth date"])).grid(column=0, row=3, padx=5, pady=5)
self.bdate = ttk.Label((self.lecteur_ci), text=' ')
self.bdate.grid(column=1, row=3, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='Date de délivrance : ').grid(column=0, row=4, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Issue date"])).grid(column=0, row=4, padx=5, pady=5)
self.ddate = ttk.Label((self.lecteur_ci), text=' ')
self.ddate.grid(column=1, row=4, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text="Date d'expiration : ").grid(column=0, row=5, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text="{} : ".format(lang.all[globs.CNIRlang]["Expiration date"])).grid(column=0, row=5, padx=5, pady=5)
self.edate = ttk.Label((self.lecteur_ci), text=' ')
self.edate.grid(column=1, row=5, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='Sexe du porteur : ').grid(column=4, row=1, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Sex"])).grid(column=4, row=1, padx=5, pady=5)
self.sex = ttk.Label((self.lecteur_ci), text=' ')
self.sex.grid(column=5, row=1, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='Pays de délivrance : ').grid(column=4, row=2, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Issuing country"])).grid(column=4, row=2, padx=5, pady=5)
self.pays = ttk.Label((self.lecteur_ci), text=' ')
self.pays.grid(column=5, row=2, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='Nationalité du porteur : ').grid(column=4, row=3, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Nationality"])).grid(column=4, row=3, padx=5, pady=5)
self.nat = ttk.Label((self.lecteur_ci), text=' ')
self.nat.grid(column=5, row=3, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='Immatriculation : ').grid(column=4, row=4, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Registration"])).grid(column=4, row=4, padx=5, pady=5)
self.indic = ttk.Label((self.lecteur_ci), text=' ')
self.indic.grid(column=5, row=4, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='Numéro de document : ').grid(column=4, row=5, padx=5, pady=5)
ttk.Label((self.lecteur_ci), text='{} : '.format(lang.all[globs.CNIRlang]["Document number"])).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)'
self.ddate['text'] = 'Inconnu(e)'
self.edate['text'] = 'Inconnu(e)'
self.no['text'] = 'Inconnu(e)'
self.sex['text'] = 'Inconnu(e)'
self.nat['text'] = 'Inconnu(e)'
self.pays['text'] = 'Inconnu(e)'
self.indic['text'] = 'Inconnu(e)'
self.nom['text'] = lang.all[globs.CNIRlang]["Unknown"]
self.prenom['text'] = lang.all[globs.CNIRlang]["Unknown"]
self.bdate['text'] = lang.all[globs.CNIRlang]["Unknown"]
self.ddate['text'] = lang.all[globs.CNIRlang]["Unknown"]
self.edate['text'] = lang.all[globs.CNIRlang]["Unknown"]
self.no['text'] = lang.all[globs.CNIRlang]["Unknown"]
self.sex['text'] = lang.all[globs.CNIRlang]["Unknown"]
self.nat['text'] = lang.all[globs.CNIRlang]["Unknown"]
self.pays['text'] = lang.all[globs.CNIRlang]["Unknown"]
self.indic['text'] = lang.all[globs.CNIRlang]["Unknown"]
self.infoList = \
@ -153,7 +154,7 @@ class mainWindow(Tk):
}
# The the image viewer
self.imageViewer = ttk.Labelframe(self, text='Affichage et traitement de documents')
self.imageViewer = ttk.Labelframe(self, text=lang.all[globs.CNIRlang]["Display and processing of documents"])
self.imageViewer.grid_columnconfigure(0, weight=1)
self.imageViewer.grid_columnconfigure(1, weight=0)
self.imageViewer.grid_rowconfigure(0, weight=1)
@ -258,7 +259,7 @@ class mainWindow(Tk):
# The terminal to enter the MRZ
self.terminal = ttk.Labelframe(self, text='Terminal de saisie de MRZ complète')
self.terminal = ttk.Labelframe(self, text=lang.all[globs.CNIRlang]["Complete MRZ capture terminal"])
self.terminal.grid_columnconfigure(0, weight=1)
self.terminal.grid_rowconfigure(0, weight=1)
self.termframe = Frame(self.terminal)
@ -272,7 +273,7 @@ class mainWindow(Tk):
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 = ttk.Labelframe(self, text=lang.all[globs.CNIRlang]["Quick entry terminal (731)"])
self.terminal2.grid_columnconfigure(0, weight=1)
self.terminal2.grid_rowconfigure(0, weight=1)
self.speed731 = Frame(self.terminal2)
@ -294,7 +295,7 @@ class mainWindow(Tk):
self.speedResult.grid(column=2, row=0, sticky='NEW', padx=5, pady=5)
# The monitor that indicates some useful infos
self.monitor = ttk.Labelframe(self, text='Moniteur')
self.monitor = ttk.Labelframe(self, text=lang.all[globs.CNIRlang]["Monitor"])
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)
self.scrollb = ttk.Scrollbar((self.monitor), command=(self.monlog.yview))
@ -313,17 +314,17 @@ class mainWindow(Tk):
# What is a window without a menu bar ?
menubar = Menu(self)
menu1 = Menu(menubar, tearoff=0)
menu1.add_command(label='Nouveau', command=(self.newEntry))
menu1.add_command(label='Ouvrir scan...', command=(self.openingScan))
menu1.add_command(label=lang.all[globs.CNIRlang]["New"], command=(self.newEntry))
menu1.add_command(label=lang.all[globs.CNIRlang]["Open scan..."], command=(self.openingScan))
menu1.add_separator()
menu1.add_command(label='Quitter', command=(self.destroy))
menubar.add_cascade(label='Fichier', menu=menu1)
menu1.add_command(label=lang.all[globs.CNIRlang]["Quit"], command=(self.destroy))
menubar.add_cascade(label=lang.all[globs.CNIRlang]["File"], menu=menu1)
menu3 = Menu(menubar, tearoff=0)
menu3.add_command(label='Commandes au clavier', command=(self.helpbox))
menu3.add_command(label='Signaler un problème', command=(self.openIssuePage))
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_separator()
menu3.add_command(label='A propos de CNIRevelator', command=(self.infobox))
menubar.add_cascade(label='Aide', menu=menu3)
menu3.add_command(label=lang.all[globs.CNIRlang]["About CNIRevelator"], command=(self.infobox))
menubar.add_cascade(label=lang.all[globs.CNIRlang]["Help"], menu=menu3)
self.config(menu=menubar)
# The title
@ -347,6 +348,7 @@ class mainWindow(Tk):
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
self.update()
self.deiconify()
self.attributes("-topmost", 1)
self.minsize(self.winfo_width(), self.winfo_height())
# Set image
@ -364,6 +366,9 @@ class mainWindow(Tk):
self.imageViewer.ZONE.bind("<Button-1>", self.rectangleSelectScan)
logfile.printdbg('Initialization successful')
if globs.CNIROpenFile:
self.after_idle(lambda : self.openScanFile(sys.argv[1]))
def statusUpdate(self, image=None, setplace=False):
if image:
@ -374,12 +379,12 @@ class mainWindow(Tk):
def rectangleSelectScan(self, event):
if self.imageViewer.image:
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))
self.corners.append([canvas.canvasx(event.x), canvas.canvasy(event.y)])
if len(self.corners) == 2:
self.select = self.imageViewer.ZONE.create_rectangle(self.corners[0][0], self.corners[0][1], self.corners[1][0], self.corners[1][1], outline ='cyan', width = 2)
print("Get rectangle : [{}, {}], for [{}, {}]".format(self.corners[0][0], self.corners[0][1], self.corners[1][0], self.corners[1][1]))
#print("Get rectangle : [{}, {}], for [{}, {}]".format(self.corners[0][0], self.corners[0][1], self.corners[1][0], self.corners[1][1]))
if len(self.corners) > 2:
self.corners = []
self.imageViewer.ZONE.delete(self.select)
@ -434,7 +439,7 @@ class mainWindow(Tk):
invite.focus_force()
self.wait_window(invite)
print("text : {}".format(self.validatedtext))
#print("text : {}".format(self.validatedtext))
self.mrzChar = ""
@ -445,7 +450,7 @@ class mainWindow(Tk):
self.mrzChar = self.mrzChar + char
self.stringValidation("")
print(self.mrzChar)
#print(self.mrzChar)
# Reinstall tesseract
except pytesseract.TesseractNotFoundError as e:
@ -453,13 +458,13 @@ class mainWindow(Tk):
shutil.rmtree(globs.CNIRTesser)
except Exception:
pass
showerror('Erreur de module OCR', ('Le module OCR localisé en ' + str(os.environ['PATH']) + 'est introuvable ou corrompu. Il sera réinstallé à la prochaine exécution'), parent=self)
logfile.printerr("Tesseract error : {}. Will be reinstallated".format(e))
showerror(lang.all[globs.CNIRlang]["OCR module error"], (lang.all[globs.CNIRlang]["The OCR module located at {} can not be found or corrupted. It will be reinstalled at the next run"].format(os.environ['PATH'])), parent=self)
logfile.printerr(lang.all[globs.CNIRlang]["Tesseract error : {}. Will be reinstallated"].format(e))
# Tesseract error
except pytesseract.TesseractError as e:
logfile.printerr("Tesseract error : {}".format(e))
showerror('Erreur de module OCR', ("Le module Tesseract a rencontré un problème : {}".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)
def stringValidation(self, keysym):
@ -478,11 +483,11 @@ class mainWindow(Tk):
self.wait_window(invite)
self.logOnTerm("Document detecté : {}\n".format(candidates[invite.choice][2]))
self.logOnTerm(lang.all[globs.CNIRlang]["Document detected: {}\n"].format(candidates[invite.choice][2]))
self.mrzDecided = candidates[invite.choice]
elif len(candidates) == 1:
self.logOnTerm("Document detecté : {}\n".format(candidates[0][2]))
self.logOnTerm(lang.all[globs.CNIRlang]["Document detected: {}\n"].format(candidates[0][2]))
self.mrzDecided = candidates[0]
else:
# corrects some problems
@ -569,11 +574,11 @@ class mainWindow(Tk):
self.wait_window(invite)
self.logOnTerm("Document re-detecté : {}\n".format(candidates[invite.choice][2]))
self.logOnTerm(lang.all[globs.CNIRlang]["Document detected again: {} \ n"].format(candidates[invite.choice][2]))
self.mrzDecided = candidates[invite.choice]
elif len(candidates) == 1:
self.logOnTerm("Document re-detecté : {}\n".format(candidates[0][2]))
self.logOnTerm(lang.all[globs.CNIRlang]["Document detected again: {} \ n"].format(candidates[0][2]))
self.mrzDecided = candidates[0]
return "break"
@ -583,7 +588,7 @@ class mainWindow(Tk):
regex = re.compile("[A-Z]|<|[0-9]")
# match !
if not regex.fullmatch(event.char):
self.logOnTerm("Caractère non accepté !\n")
self.logOnTerm(lang.all[globs.CNIRlang]["Character not accepted !\n"])
return "break"
# Adds the entry
tempChar = self.termtext.get("1.0", "end")[:-1]
@ -650,10 +655,22 @@ class mainWindow(Tk):
def openingScan(self):
path = ''
path = filedialog.askopenfilename(parent=self, title='Ouvrir un scan de CNI...', 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'),
('JPEG files', '*.jpg'),
('JPEG files', '*.jpeg')))
self.openScanFile(path)
def openScanFile(self, path):
# Check if the file is valid
if ( path[-3:] != 'jpg'
and path[-3:] != 'tif'
and path[-4:] != 'jpeg'
and path[-4:] != 'tiff' ) or not os.path.isfile(path):
showerror(lang.all[globs.CNIRlang]["Open a scan of document..."], lang.all[globs.CNIRlang]["The file you provided is not valid : {}"].format(path))
return
# Load an image using OpenCV
self.imageViewer.imagePath = path
self.imageViewer.imgZoom = 1
@ -685,7 +702,7 @@ class mainWindow(Tk):
# Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(cv_img))
self.statusUpdate(photo)
self.statusUpdate(photo)
def zoomInScan50(self, quantity = 50):
if self.imageViewer.image:
@ -792,7 +809,7 @@ class mainWindow(Tk):
self.statusUpdate( photo)
except Exception as e:
logfile.printerr("Error with opencv : {}".format(e))
traceback.print_exc(file=sys.stdout)
ihm.crashCNIR()
try:
# Reload an image using OpenCV
path = self.imageViewer.imagePath
@ -810,70 +827,37 @@ class mainWindow(Tk):
self.statusUpdate(photo)
except Exception as e:
logfile.printerr("Critical error with opencv : ".format(e))
traceback.print_exc(file=sys.stdout)
showerror("Erreur OpenCV (traitement d'images)", "Une erreur critique s'est produite dans le gestionnaire de traitement d'images OpenCV utilisé par CNIRevelator. L'application va se réinitialiser")
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"])
self.initialize()
def newEntry(self):
self.initialize()
self.logOnTerm('\n\nEntrez la première ligne de MRZ svp \n')
self.logOnTerm('\n\n{}\n'.format(lang.all[globs.CNIRlang]["Please type a MRZ or open a scan"]))
def infobox(self):
Tk().withdraw()
showinfo('A propos de CNIRevelator',
( 'Version du logiciel : CNIRevelator ' + globs.verstring_full + '\n\n'
"Copyright © 2018-2019 Adrien Bourmault (neox95)" + "\n\n"
"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"
"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"
"Le module d'OCR Tesseract 4.0 est soumis à l'Apache License 2004."
"\n\n"
"Les bibliothèques python et l'environnement Anaconda 3 sont soumis à la licence BSD 2018-2019."
"\n\n"
"Le code source de ce programme est disponible sur Github à l'adresse <https://github.com/neox95/CNIRevelator>.\n"
"Son fonctionnement est conforme aux normes et directives du document 9303 de l'OACI régissant les documents de voyages et d'identité." + '\n\n'
" En cas de problèmes ou demande particulière, ouvrez-y une issue ou bien envoyez un mail à neox@os-k.eu !\n\n"
showinfo( lang.all[globs.CNIRlang]["About CNIRevelator"],
(
lang.all[globs.CNIRlang]["ABOUT"]
),
parent=self)
def helpbox(self):
Tk().withdraw()
showinfo('Aide sur les contrôles au clavier',
( "Terminal de saisie rapide (731) : \n\n"
" Caractères autorisés : Alphanumériques en majuscule et le caractère '<'. Pas de minuscules ni caractères spéciaux, autrement la somme est mise à zéro \n\n"
" Calculer résultat :\t\t\tTouche Ctrl droite \n"
" Copier :\t\t\t\tCtrl-C \n"
" Coller :\t\t\t\tCtrl-V \n"
"\n\n"
"Terminal de saisie MRZ complète : \n\n"
" Caractères autorisés : Alphanumériques en majuscule et le caractère '<'. Pas de minuscules ni caractères spéciaux, autrement la somme est mise à zéro \n\n"
" Calculer résultat :\t\t\tTouche Ctrl droite \n"
" Compléter champ :\t\t\tTouche Tab \n"
" Copier :\t\t\t\tCtrl-C \n"
" Coller :\t\t\t\tCtrl-V \n"
" Forcer une nouvelle détection du document :\tEchap\n"
showinfo( lang.all[globs.CNIRlang]["Keyboard commands"],
(
lang.all[globs.CNIRlang]["KEYBHELP"]
),
parent=self)
def openIssuePage(self):
self.openBrowser("https://github.com/neox95/CNIRevelator/issues")
webbrowser.open_new("https://github.com/neox95/CNIRevelator/issues")
def openBrowser(self, url):
webbrowser.open_new(url)
def computeSigma(self):
"""
Launch the checksum computation, infos validation and display the results
@ -890,7 +874,7 @@ class mainWindow(Tk):
self.termtext.tag_remove("nonconforme", "1.0", "end")
self.clearTerm()
self.logOnTerm("Examen du document : {}\n\n".format(self.mrzDecided[2]))
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
@ -898,7 +882,7 @@ class mainWindow(Tk):
#print("index : {}.{}".format(x,y))
#print("{} == {}".format(code[sum[1]], sum[2]))
self.logOnTerm("Somme de contrôle position {} : Lu {} VS Calculé {}\n".format(sum[1], code[sum[1]], sum[2]))
self.logOnTerm(lang.all[globs.CNIRlang]["Check sum position {}: Lu {} VS Calculated {} and {}\n"].format(sum[1], code[sum[1]], sum[2], sum[3]))
# if sum is facultative or if sum is ok
try:
@ -920,7 +904,7 @@ class mainWindow(Tk):
# display the infos
for key in [ e for e in docInfos ]:
#print(docInfos[key])
if key in ["CODE", "CTRL"]:
if key in ["CODE", "CTRL", "CTRLF"]:
continue
if not docInfos[key] == False:
self.infoList[key]['text'] = docInfos[key]
@ -933,10 +917,10 @@ class mainWindow(Tk):
self.compliance = False
if self.compliance == True:
self.STATUStxt["text"] = "CONFORME"
self.STATUStxt["text"] = lang.all[globs.CNIRlang]["COMPLIANT"]
self.STATUStxt["foreground"] = "green"
else:
self.STATUStxt["text"] = "NON CONFORME"
self.STATUStxt["text"] = lang.all[globs.CNIRlang]["IMPROPER"]
self.STATUStxt["foreground"] = "red"
return

View File

@ -24,11 +24,12 @@
********************************************************************************
"""
import re
import logger # logger.py
import re
import datetime
import logger # logger.py
import lang # lang.py
## SEX CODES
sexcode = {'M':'Homme', 'F':'Femme', 'X':'Non spécifié'}

View File

@ -24,7 +24,6 @@
"""
from win32com.client import Dispatch
import traceback
import sys
import time
import os
@ -38,6 +37,7 @@ import ihm # ihm.py
import logger # logger.py
import globs # globs.py
import downloader # downloader.py
import lang # lang.py
UPDATE_IS_MADE = False
UPATH = ' '
@ -81,47 +81,6 @@ def exitProcess(arg):
process.terminate()
sys.exit(arg)
def runPowershell(scriptblock, cwd=os.getcwd()):
"""
Executes a powershell command
"""
log.debug("Running PowerShell Block:\r\n%s", scriptblock)
log.debug("Current Directory: %s\r\n" % cwd)
psProc = subprocess.Popen([r'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe',
'-ExecutionPolicy', 'Bypass',
'-noprofile',
'-c', '-',],
cwd=cwd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdoutdata, stderrdata = psProc.communicate(scriptblock)
if stdoutdata:
log.debug("Script Output:\r\n%s" % stdoutdata)
elif not stderrdata:
log.debug("Script completed succssfully (no stdout/stderr).")
if stderrdata:
log.error("Script Error:\r\n%s" % stderrdata)
return stdoutdata, stderrdata
def getCertificates(server_list, location="LocalMachine", store="My"):
"""
Returns the json data of all installed certificates
"""
cmd = '''
$sb = { ls Cert:\%s\%s | Select Subject,ThumbPrint }
$Servers = '%s' | ConvertFrom-Json
Invoke-Command -ComputerName $Servers -ScriptBlock $sb -Authentication Negotiate | ConvertTo-Json -Depth 999
''' % (location, store, json.dumps(server_list))
stdoutdata, stderrdata = runPowershell(cmd)
return json.loads(stdoutdata)
def getLatestVersion(credentials):
"""
Returns the latest version of the software
@ -228,7 +187,7 @@ def tessInstall(PATH, credentials):
# Unzip Tesseract
logfile.printdbg("Unzipping the package")
launcherWindow.printmsg('Installing the updates')
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Installing the updates"])
zip_ref = zipfile.ZipFile(PATH + '\\downloads\\TsrtPackage.zip', 'r')
zip_ref.extractall(PATH)
zip_ref.close()
@ -261,7 +220,7 @@ def batch(credentials):
getTheUpdate = downloader.newdownload(credentials, finalurl, globs.CNIRFolder + '\\downloads\\CNIPackage.zip', "CNIRevelator {}.{}.{}".format(finalver[0], finalver[1], finalver[2])).download()
launcherWindow.printmsg('Verifying download...')
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Verifying download..."])
# CHECKSUM
BUF_SIZE = 65536 # lets read stuff in 64kb chunks!
@ -286,7 +245,7 @@ def batch(credentials):
global UPATH
UPATH = globs.CNIRFolder + '\\..\\CNIRevelator' + "{}.{}.{}".format(finalver[0], finalver[1], finalver[2])
logfile.printdbg("Make place")
launcherWindow.printmsg('Preparing installation...')
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Preparing installation..."])
# Cleanup
try:
shutil.rmtree(UPATH + 'temp')
@ -298,7 +257,7 @@ def batch(credentials):
logfile.printdbg('Unable to cleanup : ' +str(e))
# Unzip
logfile.printdbg("Unzipping the package")
launcherWindow.printmsg('Installing the updates')
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Installing the updates"])
zip_ref = zipfile.ZipFile(globs.CNIRFolder + '\\downloads\\CNIPackage.zip', 'r')
zip_ref.extractall(UPATH + "temp")
zip_ref.close()
@ -309,9 +268,15 @@ def batch(credentials):
logfile.printdbg('Extracted :' + UPATH + '\\CNIRevelator.exe')
# Make a shortcut
createShortcut("CNIRevelator.lnk", UPATH + '\\CNIRevelator.exe', UPATH)
# hide main window
root = Tk()
root.withdraw()
res = askquestion(lang.all[globs.CNIRlang]["Shortcut creation"], lang.all[globs.CNIRlang]["Would you like to create/update the shortcut for CNIRevelator on your desktop ?"])
if res == "yes":
createShortcut("CNIRevelator.lnk", UPATH + '\\CNIRevelator.exe', UPATH)
root.destroy()
launcherWindow.printmsg('Success !')
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Success !"])
# Cleanup
try:
@ -319,7 +284,7 @@ def batch(credentials):
except:
pass
# Time to quit
launcherWindow.printmsg('Launched the new process.')
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Launching the new version..."])
global UPDATE_IS_MADE
UPDATE_IS_MADE = True
return True
@ -335,19 +300,19 @@ def umain():
if not credentials.valid:
logfile.printerr("Credentials Error. No effective update !")
launcherWindow.printmsg('Credentials Error. No effective update !')
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Credentials Error. No effective update !"])
time.sleep(2)
launcherWindow.exit()
return 0
# Cleaner for the old version if detected
if len(sys.argv) > 2:
if len(sys.argv) > 2 and str(sys.argv[1]) == "DELETE":
globs.CNIRNewVersion = True
launcherWindow.printmsg('Deleting old version !')
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Deleting old version"])
logfile.printdbg("Old install detected : {}".format(sys.argv[1]))
while os.path.exists(str(sys.argv[2])):
try:
os.remove(str(sys.argv[2]))
shutil.rmtree(str(sys.argv[2]))
except Exception as e:
logfile.printerr(str(e))
logfile.printdbg('Trying stop the process !')
@ -361,45 +326,23 @@ def umain():
else:
logfile.printdbg('Terminating process !')
process.terminate()
os.remove(str(sys.argv[2]))
shutil.rmtree(str(sys.argv[2]))
break
except Exception as e:
logfile.printerr(str(e))
launcherWindow.printmsg('Fail :{}'.format(e))
launcherWindow.printmsg('Starting...')
elif len(sys.argv) > 1:
globs.CNIRNewVersion = True
launcherWindow.printmsg('Deleting old version !')
logfile.printdbg("Old install detected : {}".format(sys.argv[1]))
while os.path.exists(str(sys.argv[1])):
try:
shutil.rmtree(str(sys.argv[1]))
except Exception as e:
logfile.printerr(str(e))
logfile.printdbg('Trying stop the process !')
launcherWindow.printmsg('Fail :{}'.format(e))
try:
for process in psutil.process_iter():
if process.name() == 'CNIRevelator.exe':
logfile.printdbg('Process found. Command line: {}'.format(process.cmdline()))
if process.pid == os.getpid():
logfile.printdbg("Don't touch us ! {} = {}".format(process.pid, os.getpid()))
else:
logfile.printdbg('Terminating process !')
process.terminate()
shutil.rmtree(str(sys.argv[1]))
break
except Exception as e:
logfile.printerr(str(e))
launcherWindow.printmsg('Fail :{}'.format(e))
launcherWindow.printmsg('Starting...')
launcherWindow.printmsg(lang.all[globs.CNIRlang]['Starting...'])
# check we want open a file
elif len(sys.argv) > 1 and str(sys.argv[1]) != "DELETE":
globs.CNIROpenFile = True
try:
try:
# EXECUTING THE UPDATE BATCH
success = batch(credentials)
except Exception as e:
logfile.printerr("An error occured on the thread : " + str(traceback.format_exc()))
ihm.crashCNIR()
launcherWindow.printmsg('ERROR : ' + str(e))
time.sleep(3)
launcherWindow.exit()
@ -410,7 +353,7 @@ def umain():
launcherWindow.printmsg('Software is up-to-date !')
else:
logfile.printerr("An error occured. No effective update !")
launcherWindow.printmsg('An error occured. No effective update !')
launcherWindow.printmsg(lang.all[globs.CNIRlang]['An error occured. No effective update !'])
time.sleep(2)
launcherWindow.exit()
return 0
@ -419,7 +362,7 @@ def umain():
launcherWindow.exit()
return 0
except:
logfile.printerr("A FATAL ERROR OCCURED : " + str(traceback.format_exc()))
ihm.crashCNIR()
launcherWindow.exit()
sys.exit(2)
return 2
@ -429,7 +372,7 @@ def umain():
# INSTALLING TESSERACT OCR
success = tessInstall(globs.CNIRFolder, credentials)
except Exception as e:
logfile.printerr("An error occured on the thread : " + str(traceback.format_exc()))
ihm.crashCNIR()
launcherWindow.printmsg('ERROR : ' + str(e))
time.sleep(3)
launcherWindow.exit()
@ -437,16 +380,16 @@ def umain():
if success:
logfile.printdbg("Software is up-to-date !")
launcherWindow.printmsg('Software is up-to-date !')
launcherWindow.printmsg(lang.all[globs.CNIRlang]['Software is up-to-date !'])
else:
logfile.printerr("An error occured. No effective update !")
launcherWindow.printmsg('An error occured. No effective update !')
launcherWindow.printmsg(lang.all[globs.CNIRlang]['An error occured. No effective update !'])
time.sleep(2)
launcherWindow.exit()
return 0
except:
logfile.printerr("A FATAL ERROR OCCURED : " + str(traceback.format_exc()))
ihm.crashCNIR()
launcherWindow.exit()
sys.exit(2)
return 2