mirror of
https://gitlab.os-k.eu/neox/CNIRevelator.git
synced 2023-08-25 14:03:10 +02:00
commit
bbb2e43f61
@ -1,2 +1,2 @@
|
|||||||
# ver|url|checksum, and | as separator, one version per ||
|
# ver|url|checksum, and | as separator, one version per ||
|
||||||
3.1.4|https://github.com/neox95/CNIRevelator/releases/download/3.1.4e/CNIRevelator.zip|1acf3b6158506218b0b16948af1df51b11d81eea||
|
3.1.5|https://github.com/neox95/CNIRevelator/releases/download/3.1.5b/CNIRevelator.zip|5bdaf4042c5d6474bf9f87b43db6516f532938cf||
|
||||||
|
@ -84,6 +84,8 @@ def main():
|
|||||||
## BOOTSTRAP OF CNIREVELATOR
|
## BOOTSTRAP OF CNIREVELATOR
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
logfile.printdbg('CNIRevelator log file version {}'.format(globs.verstring_full))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# LANGUAGE
|
# LANGUAGE
|
||||||
lang.readLang()
|
lang.readLang()
|
||||||
|
@ -36,7 +36,7 @@ import logger # logger.py
|
|||||||
import globs # globs.py
|
import globs # globs.py
|
||||||
import github # github.py
|
import github # github.py
|
||||||
|
|
||||||
def crashCNIR(shutdown=True):
|
def crashCNIR(shutdown=True, option="", isVoluntary=False):
|
||||||
"""
|
"""
|
||||||
very last solution
|
very last solution
|
||||||
"""
|
"""
|
||||||
@ -47,7 +47,14 @@ def crashCNIR(shutdown=True):
|
|||||||
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"])
|
if not isVoluntary:
|
||||||
|
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"] + "\n\n{}\n{}".format(option, traceback.format_exc()))
|
||||||
|
|
||||||
|
# Force new update
|
||||||
|
try:
|
||||||
|
os.remove(globs.CNIRLastUpdate)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to report this bug ?"])
|
res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to report this bug ?"])
|
||||||
if res == "yes":
|
if res == "yes":
|
||||||
@ -60,7 +67,7 @@ def crashCNIR(shutdown=True):
|
|||||||
logfile.printerr("Can't read the log file.")
|
logfile.printerr("Can't read the log file.")
|
||||||
|
|
||||||
# send it
|
# send it
|
||||||
success = github.reportBug(traceback.format_exc(), data)
|
success = github.reportBug(traceback.format_exc(), data, isVoluntary)
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
logfile.printerr("Can't send to Github.")
|
logfile.printerr("Can't send to Github.")
|
||||||
|
@ -81,10 +81,11 @@ class newcredentials:
|
|||||||
self.trying += 1
|
self.trying += 1
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sessionAnswer = session.get('https://www.google.com')
|
sessionAnswer = session.get('http://www.google.com')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logfile.printdbg('Network Error : ' + str(e))
|
logfile.printdbg('Network Error : ' + str(e))
|
||||||
sessionAnswer = ''
|
self.login = "nointernet"
|
||||||
|
return
|
||||||
|
|
||||||
logfile.printdbg("Session Answer : " + str(sessionAnswer))
|
logfile.printdbg("Session Answer : " + str(sessionAnswer))
|
||||||
|
|
||||||
@ -94,11 +95,6 @@ class newcredentials:
|
|||||||
self.valid = True
|
self.valid = True
|
||||||
return
|
return
|
||||||
|
|
||||||
if str(sessionAnswer) != '<Response [407]>' and self.trying > 2:
|
|
||||||
# because sometimes the proxy does not return an error (especially if we do not provide either credentials)
|
|
||||||
logfile.printerr('Network Error, or need a proxy !')
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.trying > 4:
|
if self.trying > 4:
|
||||||
logfile.printerr('Invalid credentials : access denied, a maximum of 3 trials have been raised !')
|
logfile.printerr('Invalid credentials : access denied, a maximum of 3 trials have been raised !')
|
||||||
return
|
return
|
||||||
|
@ -25,15 +25,42 @@
|
|||||||
"""
|
"""
|
||||||
from requests.auth import HTTPProxyAuth
|
from requests.auth import HTTPProxyAuth
|
||||||
from pypac import PACSession
|
from pypac import PACSession
|
||||||
|
from Crypto import Random
|
||||||
|
from Crypto.Cipher import AES
|
||||||
from requests import Session
|
from requests import Session
|
||||||
import json
|
import json, hashlib, base64
|
||||||
|
|
||||||
import logger # logger.py
|
import logger # logger.py
|
||||||
import globs # globs.py
|
import globs # globs.py
|
||||||
|
|
||||||
credentials = False
|
credentials = False
|
||||||
|
|
||||||
def reportBug(reason="",log=""):
|
class AESCipher(object):
|
||||||
|
|
||||||
|
def __init__(self, key):
|
||||||
|
self.bs = 32
|
||||||
|
self.key = hashlib.sha256(key.encode()).digest()
|
||||||
|
|
||||||
|
def encrypt(self, raw):
|
||||||
|
raw = self._pad(raw)
|
||||||
|
iv = Random.new().read(AES.block_size)
|
||||||
|
cipher = AES.new(self.key, AES.MODE_CBC, iv)
|
||||||
|
return base64.b64encode(iv + cipher.encrypt(raw))
|
||||||
|
|
||||||
|
def decrypt(self, enc):
|
||||||
|
enc = base64.b64decode(enc)
|
||||||
|
iv = enc[:AES.block_size]
|
||||||
|
cipher = AES.new(self.key, AES.MODE_CBC, iv)
|
||||||
|
return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')
|
||||||
|
|
||||||
|
def _pad(self, s):
|
||||||
|
return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _unpad(s):
|
||||||
|
return s[:-ord(s[len(s) - 1:])]
|
||||||
|
|
||||||
|
def reportBug(reason="",log="", isVoluntary=False):
|
||||||
|
|
||||||
logfile = logger.logCur
|
logfile = logger.logCur
|
||||||
|
|
||||||
@ -43,15 +70,26 @@ def reportBug(reason="",log=""):
|
|||||||
|
|
||||||
session = credentials.sessionHandler
|
session = credentials.sessionHandler
|
||||||
|
|
||||||
payload = {'title':"CNIRevelator Bug Report", 'body':"**An error has been reported by a CNIRevelator instance.**\n\n**Here is the full reason of this issue:**\n{}\n\n**The full log is here:** {}".format(reason, log), "assignees":["neox95"], "labels":["bug", "AUTO"]}
|
if not isVoluntary:
|
||||||
|
payload = {'title':"CNIRevelator Bug Report", 'body':"**An error has been reported by a CNIRevelator instance.**\n\n**Here is the full reason of this issue:**\n{}\n\n**The full log is here:** {}".format(reason, log), "assignees":["neox95"], "labels":["bug", "AUTO"]}
|
||||||
|
else:
|
||||||
|
payload = {'title':"CNIRevelator Bug Report", 'body':"**A voluntary bug report has been reported by a CNIRevelator user.**\n\n**Possible reason:**\n{}\n\n**The full log is here:** {}".format(reason, log), "assignees":["neox95"], "labels":["bug", "AUTO"]}
|
||||||
|
|
||||||
handler = session.post('https://api.github.com/repos/neox95/cnirevelator/issues', headers={'Authorization': 'token %s' % globs.CNIRGitToken}, data=json.dumps(payload))
|
handler = session.post('https://api.github.com/repos/neox95/cnirevelator/issues', headers={'Authorization': 'token %s' % decryptToken(globs.CNIRGitToken)}, data=json.dumps(payload))
|
||||||
|
|
||||||
logfile.printdbg(handler.reason)
|
logfile.printdbg("Issue is " + handler.reason)
|
||||||
|
|
||||||
if handler.reason == "Created":
|
if handler.reason == "Created":
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def encryptToken(token):
|
||||||
|
AESObj = AESCipher(globs.CNIRCryptoKey)
|
||||||
|
return AESObj.encrypt(token)
|
||||||
|
|
||||||
|
def decryptToken(token):
|
||||||
|
AESObj = AESCipher(globs.CNIRCryptoKey)
|
||||||
|
return AESObj.decrypt(token)
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,12 +27,12 @@ import os
|
|||||||
|
|
||||||
# CNIRevelator version
|
# CNIRevelator version
|
||||||
verType = "stable release"
|
verType = "stable release"
|
||||||
version = [3, 1, 4]
|
version = [3, 1, 5]
|
||||||
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])
|
||||||
|
|
||||||
CNIRTesserHash = "947224361ffab8c01f05c9394b44b1bd7c8c3d4d"
|
CNIRTesserHash = "947224361ffab8c01f05c9394b44b1bd7c8c3d4d"
|
||||||
CNIRGitToken = "ef7737dd1e5ad8a35d3cc5fdbeb273e69a09f25f"
|
CNIRGitToken = "mJHKXqnazO/xZ9Fs18SDMqcGJ15A27OlZyd27cDe5dhHKklO2YShdWwUgEDUZQI02kpgYaLceMidTK37ZqakW+VYgPPuh0e9Ry2IH0KHc3o="
|
||||||
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)
|
||||||
|
38
src/ihm.py
38
src/ihm.py
@ -30,7 +30,6 @@ from tkinter import filedialog
|
|||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
import PIL.Image, PIL.ImageTk
|
import PIL.Image, PIL.ImageTk
|
||||||
import traceback
|
import traceback
|
||||||
import webbrowser
|
|
||||||
import cv2
|
import cv2
|
||||||
|
|
||||||
import critical # critical.py
|
import critical # critical.py
|
||||||
@ -45,13 +44,16 @@ controlKeys = ["Escape", "Right", "Left", "Up", "Down", "Home", "End", "BackSpac
|
|||||||
class DocumentAsk(Toplevel):
|
class DocumentAsk(Toplevel):
|
||||||
|
|
||||||
def __init__(self, parent, choices):
|
def __init__(self, parent, choices):
|
||||||
self.choice = 0
|
|
||||||
vals = [0, 1]
|
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.title("{} :".format(lang.all[globs.CNIRlang]["Choose the identity document"]))
|
self.title("{} :".format(lang.all[globs.CNIRlang]["Choose the identity document"]))
|
||||||
|
|
||||||
ttk.Radiobutton(self, text=choices[0], command=self.register0, value=vals[0]).pack()
|
self.choice = 0
|
||||||
ttk.Radiobutton(self, text=choices[1], command=self.register1, value=vals[1]).pack()
|
vals = [i[2] for i in choices]
|
||||||
|
for i in range(len(vals)):
|
||||||
|
a = ttk.Radiobutton(self, text=vals[i], command=self.createRegister(i), value=vals[i])
|
||||||
|
a.pack(fill=Y)
|
||||||
|
if i == 0:
|
||||||
|
a.invoke()
|
||||||
|
|
||||||
self.button = Button(self, text='OK', command=(self.ok)).pack()
|
self.button = Button(self, text='OK', command=(self.ok)).pack()
|
||||||
self.resizable(width=False, height=False)
|
self.resizable(width=False, height=False)
|
||||||
@ -68,10 +70,11 @@ class DocumentAsk(Toplevel):
|
|||||||
y = hs / 2 - h / 2
|
y = hs / 2 - h / 2
|
||||||
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
|
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
|
||||||
|
|
||||||
def register0(self):
|
def createRegister(self, i):
|
||||||
self.choice = 0
|
def register():
|
||||||
def register1(self):
|
self.choice = i
|
||||||
self.choice = 1
|
return register
|
||||||
|
|
||||||
def ok(self):
|
def ok(self):
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
@ -193,7 +196,7 @@ class ChangelogDialog(Toplevel):
|
|||||||
|
|
||||||
class langDialog(Toplevel):
|
class langDialog(Toplevel):
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent, currentLang):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
self.title(lang.all[globs.CNIRlang]["Language"])
|
self.title(lang.all[globs.CNIRlang]["Language"])
|
||||||
@ -202,7 +205,10 @@ class langDialog(Toplevel):
|
|||||||
|
|
||||||
vals = [i for i in lang.all]
|
vals = [i for i in lang.all]
|
||||||
for i in range(len(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)
|
a = ttk.Radiobutton(self, text=vals[i], command=self.createRegister(i), value=vals[i])
|
||||||
|
a.pack(fill=Y)
|
||||||
|
if i == vals.index(currentLang):
|
||||||
|
a.invoke()
|
||||||
|
|
||||||
ttk.Button(self, text="OK", command=(self.oki)).pack(fill=Y, pady=5)
|
ttk.Button(self, text="OK", command=(self.oki)).pack(fill=Y, pady=5)
|
||||||
|
|
||||||
@ -231,7 +237,7 @@ class langDialog(Toplevel):
|
|||||||
|
|
||||||
class updateSetDialog(Toplevel):
|
class updateSetDialog(Toplevel):
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent, currentChannel):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
self.title(lang.all[globs.CNIRlang]["Update options"])
|
self.title(lang.all[globs.CNIRlang]["Update options"])
|
||||||
@ -241,7 +247,11 @@ class updateSetDialog(Toplevel):
|
|||||||
self.vals = ["Stable", "Beta"]
|
self.vals = ["Stable", "Beta"]
|
||||||
vals = self.vals
|
vals = self.vals
|
||||||
for i in range(len(vals)):
|
for i in range(len(vals)):
|
||||||
ttk.Radiobutton(self, text=vals[i], command=self.createRegister(i), value=vals[i]).pack(fill=Y)
|
a = ttk.Radiobutton(self, text=vals[i], command=self.createRegister(i), value=vals[i])
|
||||||
|
a.pack(fill=Y)
|
||||||
|
if i == self.vals.index(currentChannel):
|
||||||
|
a.invoke()
|
||||||
|
|
||||||
|
|
||||||
ttk.Button(self, text="OK", command=(self.oki)).pack(fill=Y, pady=5)
|
ttk.Button(self, text="OK", command=(self.oki)).pack(fill=Y, pady=5)
|
||||||
|
|
||||||
@ -265,7 +275,7 @@ class updateSetDialog(Toplevel):
|
|||||||
|
|
||||||
def createRegister(self, i):
|
def createRegister(self, i):
|
||||||
def register():
|
def register():
|
||||||
updater.updateChannel(self.vals[i])
|
updater.setUpdateChannel(self.vals[i])
|
||||||
return register
|
return register
|
||||||
|
|
||||||
class LauncherWindow(Tk):
|
class LauncherWindow(Tk):
|
||||||
|
12
src/lang.py
12
src/lang.py
@ -141,7 +141,8 @@ french = \
|
|||||||
"Coller :\t\t\t\tCtrl-V \n"
|
"Coller :\t\t\t\tCtrl-V \n"
|
||||||
"Forcer une nouvelle détection du document :\tEchap\n",
|
"Forcer une nouvelle détection du document :\tEchap\n",
|
||||||
|
|
||||||
"CHANGELOG" : "Version 3.1.4 \nMise-à-jour mineure avec les progressions suivantes :\n- Correction d'un bug affectant la rotation de documents dans l'afficheur d'images\n- Ajout d'une période de mise-à-jour afin d'éviter de rechercher les mises-à-jour tous les jours\n\n" + \
|
"CHANGELOG" : "Version 3.1.5 \nMise-à-jour mineure avec les progressions suivantes :\n- Correction d'un bug affectant le signalement de bug\n- Améliorations de l'affichage de la conformité des informations\n- Ajout d'un nouveau système de selection plus simple et fiable'\n\n" + \
|
||||||
|
"Version 3.1.4 \nMise-à-jour mineure avec les progressions suivantes :\n- Correction d'un bug affectant la rotation de documents dans l'afficheur d'images\n- Ajout d'une période de mise-à-jour afin d'éviter de rechercher les mises-à-jour tous les jours\n\n" + \
|
||||||
"Version 3.1.3 \nMise-à-jour mineure avec les progressions suivantes :\n- Correction d'un bug de la détection automatique de documents\n- Ajout d'une fonctionnalité de rapport d'erreur\n\n" + \
|
"Version 3.1.3 \nMise-à-jour mineure avec les progressions suivantes :\n- Correction d'un bug de la détection automatique de documents\n- Ajout d'une fonctionnalité de rapport d'erreur\n\n" + \
|
||||||
"Version 3.1.2 \nMise-à-jour mineure avec les progressions suivantes :\n- Montée de version de Tesseract OCR : 5.0\n- Correction de noms des documents\n- Résolution d'un problème avec le système de mise-à-jour\n- Amélioration des effets sur images\n\n" + \
|
"Version 3.1.2 \nMise-à-jour mineure avec les progressions suivantes :\n- Montée de version de Tesseract OCR : 5.0\n- Correction de noms des documents\n- Résolution d'un problème avec le système de mise-à-jour\n- Amélioration des effets sur images\n\n" + \
|
||||||
"Version 3.1.1 \nMise-à-jour mineure avec les progressions suivantes :\n- Correction d'un bug sévère du système de mise à jour\n\n" + \
|
"Version 3.1.1 \nMise-à-jour mineure avec les progressions suivantes :\n- Correction d'un bug sévère du système de mise à jour\n\n" + \
|
||||||
@ -207,6 +208,9 @@ french = \
|
|||||||
"does not contain any non unicode "
|
"does not contain any non unicode "
|
||||||
"character such as accent and "
|
"character such as accent and "
|
||||||
"foreign characters." : "Une erreur critique s'est produite dans le gestionnaire de traitement d'images OpenCV utilisé par CNIRevelator. Veuillez vous assurer que le nom de fichier ne contient pas de caractères non unicode tels que des accents et des caractères étrangers.",
|
"foreign characters." : "Une erreur critique s'est produite dans le gestionnaire de traitement d'images OpenCV utilisé par CNIRevelator. Veuillez vous assurer que le nom de fichier ne contient pas de caractères non unicode tels que des accents et des caractères étrangers.",
|
||||||
|
"No Internet Error. No effective "
|
||||||
|
"update !" : "Aucune connectivité. Pas de mise-à-jour !",
|
||||||
|
"Project Webpage" : "Site internet du projet",
|
||||||
|
|
||||||
"LANDCODE2" : {
|
"LANDCODE2" : {
|
||||||
'AW': 'Aruba',
|
'AW': 'Aruba',
|
||||||
@ -809,6 +813,8 @@ english = \
|
|||||||
"the OpenCV image processing "
|
"the OpenCV image processing "
|
||||||
"manager used by CNIRevelator, the "
|
"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",
|
"application will reset itself" : "A critical error has occurred in the OpenCV image processing manager used by CNIRevelator, the application will reset itself",
|
||||||
|
"No Internet Error. No effective "
|
||||||
|
"update !" : "No Internet Error. No effective update !",
|
||||||
|
|
||||||
"ABOUT" : 'Software Version: CNIRevelator' + globs.verstring_full + '\n\n'
|
"ABOUT" : 'Software Version: CNIRevelator' + globs.verstring_full + '\n\n'
|
||||||
"Copyright © 2018-2019 Adrien Bourmault (neox95)" + "\n\n"
|
"Copyright © 2018-2019 Adrien Bourmault (neox95)" + "\n\n"
|
||||||
@ -847,7 +853,8 @@ english = \
|
|||||||
"Paste:\t\t\t\tCtrl-V\n"
|
"Paste:\t\t\t\tCtrl-V\n"
|
||||||
"Force a new document detection:\tEchap\n",
|
"Force a new document detection:\tEchap\n",
|
||||||
|
|
||||||
"CHANGELOG" : "Version 3.1.4 \nMinor update with the following progressions:\n- Correction of a bug affecting rotation of document in image viewer\n- Added a new update period to prevent updating everyday\n\n" + \
|
"CHANGELOG" : "Version 3.1.5 \nMinor update with the following progressions:\n- Correction of a bug affecting bug reporting\n - Enhancements on information compliance display\n- Added new selection system to be more userfriendly\n\n" + \
|
||||||
|
"Version 3.1.4 \nMinor update with the following progressions:\n- Correction of a bug affecting rotation of document in image viewer\n- Added a new update period to prevent updating everyday\n\n" + \
|
||||||
"Version 3.1.3 \nMinor update with the following progressions:\n- Correction of a bug affecting automated document detection\n- Added bug reporting functionnality\n\n" + \
|
"Version 3.1.3 \nMinor update with the following progressions:\n- Correction of a bug affecting automated document detection\n- Added bug reporting functionnality\n\n" + \
|
||||||
"Version 3.1.2 \nMinor update with the following progressions: \n- Tesseract OCR version upgrade : 5.0\n- Correction of document names\n- Fixed a problem with the update system\n- Some enhancements about effects on images\n\n" + \
|
"Version 3.1.2 \nMinor update with the following progressions: \n- Tesseract OCR version upgrade : 5.0\n- Correction of document names\n- Fixed a problem with the update system\n- Some enhancements about effects on images\n\n" + \
|
||||||
"Version 3.1.1 \nMinor update with the following progressions: \n- Fixed a severe bug in the update system\n\n" + \
|
"Version 3.1.1 \nMinor update with the following progressions: \n- Fixed a severe bug in the update system\n\n" + \
|
||||||
@ -913,6 +920,7 @@ english = \
|
|||||||
"does not contain any non unicode "
|
"does not contain any non unicode "
|
||||||
"character such as accent and "
|
"character such as accent and "
|
||||||
"foreign characters." : "A critical error has occurred in the OpenCV image processing manager used by CNIRevelator. Please be sure that the filename does not contain any non unicode character such as accent and foreign characters.",
|
"foreign characters." : "A critical error has occurred in the OpenCV image processing manager used by CNIRevelator. Please be sure that the filename does not contain any non unicode character such as accent and foreign characters.",
|
||||||
|
"Project Webpage" : "Project website",
|
||||||
|
|
||||||
"LANDCODE2" : {
|
"LANDCODE2" : {
|
||||||
"AW": "Aruba",
|
"AW": "Aruba",
|
||||||
|
81
src/main.py
81
src/main.py
@ -38,9 +38,9 @@ import re
|
|||||||
import cv2
|
import cv2
|
||||||
import PIL.Image, PIL.ImageTk
|
import PIL.Image, PIL.ImageTk
|
||||||
import os, shutil
|
import os, shutil
|
||||||
import webbrowser
|
|
||||||
import sys, os
|
import sys, os
|
||||||
import numpy
|
import numpy
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
import critical # critical.py
|
import critical # critical.py
|
||||||
import ihm # ihm.py
|
import ihm # ihm.py
|
||||||
@ -49,6 +49,7 @@ import mrz # mrz.py
|
|||||||
import globs # globs.py
|
import globs # globs.py
|
||||||
import pytesseract # pytesseract.py
|
import pytesseract # pytesseract.py
|
||||||
import lang # lang.py
|
import lang # lang.py
|
||||||
|
import updater # updater.py
|
||||||
|
|
||||||
# Global handler
|
# Global handler
|
||||||
logfile = logger.logCur
|
logfile = logger.logCur
|
||||||
@ -70,6 +71,7 @@ class mainWindow(Tk):
|
|||||||
self.Tags = []
|
self.Tags = []
|
||||||
self.compliance = True
|
self.compliance = True
|
||||||
self.corners = []
|
self.corners = []
|
||||||
|
self.indicators = []
|
||||||
self.validatedtext = ""
|
self.validatedtext = ""
|
||||||
|
|
||||||
# The icon
|
# The icon
|
||||||
@ -172,7 +174,7 @@ class mainWindow(Tk):
|
|||||||
"SEX" : self.sex,
|
"SEX" : self.sex,
|
||||||
"NAT" : self.nat,
|
"NAT" : self.nat,
|
||||||
"PAYS" : self.pays,
|
"PAYS" : self.pays,
|
||||||
"INDIC" : self.indic,
|
"INDIC" : self.indic
|
||||||
}
|
}
|
||||||
|
|
||||||
# The the image viewer
|
# The the image viewer
|
||||||
@ -351,6 +353,7 @@ class mainWindow(Tk):
|
|||||||
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]["Project Webpage"], command=(self.openProjectPage))
|
||||||
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))
|
menubar.add_command(label="<|>", command=(self.panelResize))
|
||||||
@ -409,11 +412,19 @@ class mainWindow(Tk):
|
|||||||
|
|
||||||
self.corners.append([canvas.canvasx(event.x), canvas.canvasy(event.y)])
|
self.corners.append([canvas.canvasx(event.x), canvas.canvasy(event.y)])
|
||||||
if len(self.corners) == 2:
|
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)
|
self.select = self.imageViewer.ZONE.create_rectangle(self.corners[0][0], self.corners[0][1], self.corners[1][0], self.corners[1][1], outline ='red', 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]))
|
||||||
|
|
||||||
|
# Reinit
|
||||||
if len(self.corners) > 2:
|
if len(self.corners) > 2:
|
||||||
self.corners = []
|
self.corners = []
|
||||||
self.imageViewer.ZONE.delete(self.select)
|
self.imageViewer.ZONE.delete(self.select)
|
||||||
|
for k in self.indicators:
|
||||||
|
self.imageViewer.ZONE.delete(k)
|
||||||
|
|
||||||
|
# Draw indicator
|
||||||
|
else:
|
||||||
|
self.indicators.append(self.imageViewer.ZONE.create_oval(canvas.canvasx(event.x)-4, canvas.canvasy(event.y)-4,canvas.canvasx(event.x)+4, canvas.canvasy(event.y)+4, fill='red', outline='red', width = 2))
|
||||||
|
|
||||||
def goOCRDetection(self):
|
def goOCRDetection(self):
|
||||||
"""
|
"""
|
||||||
@ -447,10 +458,13 @@ 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)
|
||||||
|
|
||||||
# Crop
|
# Crop
|
||||||
x0 = int(self.corners[0][0])
|
|
||||||
y0 = int(self.corners[0][1])
|
coords = self.imageViewer.ZONE.coords(self.select)
|
||||||
x1 = int(self.corners[1][0])
|
|
||||||
y1 = int(self.corners[1][1])
|
x0 = int(coords[0])
|
||||||
|
y0 = int(coords[1])
|
||||||
|
x1 = int(coords[2])
|
||||||
|
y1 = int(coords[3])
|
||||||
crop_img = cv_img[y0:y1, x0:x1]
|
crop_img = cv_img[y0:y1, x0:x1]
|
||||||
|
|
||||||
# Get the text by OCR
|
# Get the text by OCR
|
||||||
@ -510,9 +524,9 @@ class mainWindow(Tk):
|
|||||||
# Get the candidates
|
# Get the candidates
|
||||||
candidates = mrz.allDocMatch(self.mrzChar.split("\n"), final=isFull)
|
candidates = mrz.allDocMatch(self.mrzChar.split("\n"), final=isFull)
|
||||||
|
|
||||||
if len(candidates) == 2 and len(self.mrzChar) >= 8:
|
if len(candidates) >= 2 and len(candidates) < 4 and len(self.mrzChar) >= 8:
|
||||||
# Parameters for the choice invite
|
# Parameters for the choice invite
|
||||||
invite = ihm.DocumentAsk(self, [candidates[0][2], candidates[1][2]])
|
invite = ihm.DocumentAsk(self, candidates)
|
||||||
invite.transient(self)
|
invite.transient(self)
|
||||||
invite.grab_set()
|
invite.grab_set()
|
||||||
invite.focus_force()
|
invite.focus_force()
|
||||||
@ -606,9 +620,9 @@ class mainWindow(Tk):
|
|||||||
# Get the candidates
|
# Get the candidates
|
||||||
candidates = mrz.allDocMatch(self.mrzChar.split("\n"))
|
candidates = mrz.allDocMatch(self.mrzChar.split("\n"))
|
||||||
|
|
||||||
if len(candidates) == 2 and len(self.mrzChar) >= 8:
|
if len(candidates) >= 2 and len(candidates) < 4 and len(self.mrzChar) >= 8:
|
||||||
# Parameters for the choice invite
|
# Parameters for the choice invite
|
||||||
invite = ihm.DocumentAsk(self, [candidates[0][2], candidates[1][2]])
|
invite = ihm.DocumentAsk(self, candidates)
|
||||||
invite.transient(self)
|
invite.transient(self)
|
||||||
invite.grab_set()
|
invite.grab_set()
|
||||||
invite.focus_force()
|
invite.focus_force()
|
||||||
@ -723,12 +737,12 @@ class mainWindow(Tk):
|
|||||||
#print(docInfos)
|
#print(docInfos)
|
||||||
# display the infos
|
# display the infos
|
||||||
for key in [ e for e in docInfos ]:
|
for key in [ e for e in docInfos ]:
|
||||||
#print(docInfos[key])
|
#printkey)
|
||||||
if key in ["CODE", "CTRL", "CTRLF"]:
|
if key in ["CODE", "CTRL", "CTRLF", "FACULT", "NOINT"]:
|
||||||
continue
|
continue
|
||||||
if not docInfos[key] == False:
|
if not docInfos[key][1] == False:
|
||||||
if not docInfos[key] == "":
|
if not docInfos[key][0] == "":
|
||||||
self.infoList[key]['text'] = docInfos[key]
|
self.infoList[key]['text'] = docInfos[key][0]
|
||||||
self.infoList[key]['background'] = self['background']
|
self.infoList[key]['background'] = self['background']
|
||||||
self.infoList[key]['foreground'] = "black"
|
self.infoList[key]['foreground'] = "black"
|
||||||
else:
|
else:
|
||||||
@ -738,7 +752,7 @@ class mainWindow(Tk):
|
|||||||
else:
|
else:
|
||||||
self.infoList[key]['background'] = "red"
|
self.infoList[key]['background'] = "red"
|
||||||
self.infoList[key]['foreground'] = "white"
|
self.infoList[key]['foreground'] = "white"
|
||||||
self.infoList[key]['text'] = "NC"
|
self.infoList[key]['text'] = docInfos[key][0]
|
||||||
self.compliance = False
|
self.compliance = False
|
||||||
|
|
||||||
if self.compliance == True:
|
if self.compliance == True:
|
||||||
@ -841,7 +855,7 @@ class mainWindow(Tk):
|
|||||||
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
|
||||||
except:
|
except:
|
||||||
logfile.printerr("Error with : {} in {} with total of {} pages".format(cv2.imreadmulti(self.imageViewer.imagePath), self.imageViewer.imagePath, total))
|
logfile.printerr("Error with : {} in {} with total of {} pages".format(cv2.imreadmulti(self.imageViewer.imagePath), self.imageViewer.imagePath, total))
|
||||||
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. Please be sure that the filename does not contain any non unicode character such as accent and foreign characters."] + "\n\n" + self.imageViewer.imagePath)
|
critical.crashCNIR(False, "OpenCV openScanFile() error")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
||||||
@ -854,6 +868,10 @@ class mainWindow(Tk):
|
|||||||
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
# Get the image dimensions (OpenCV stores image data as NumPy ndarray)
|
||||||
height, width = cv_img.shape
|
height, width = cv_img.shape
|
||||||
|
|
||||||
|
|
||||||
|
# Update shape
|
||||||
|
self.imageViewer.height, self.imageViewer.width = cv_img.shape[:2]
|
||||||
|
|
||||||
# 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.DisplayUpdate(photo)
|
self.DisplayUpdate(photo)
|
||||||
@ -864,7 +882,7 @@ class mainWindow(Tk):
|
|||||||
self.resizeScan()
|
self.resizeScan()
|
||||||
|
|
||||||
def zoomOutScan50(self, quantity = 50):
|
def zoomOutScan50(self, quantity = 50):
|
||||||
if self.imageViewer.image:
|
if self.imageViewer.image and int(self.imageViewer.width * (self.imageViewer.imgZoom - quantity + 100) / 100) > 100:
|
||||||
self.imageViewer.imgZoom -= quantity
|
self.imageViewer.imgZoom -= quantity
|
||||||
self.resizeScan()
|
self.resizeScan()
|
||||||
|
|
||||||
@ -874,7 +892,7 @@ class mainWindow(Tk):
|
|||||||
self.resizeScan()
|
self.resizeScan()
|
||||||
|
|
||||||
def zoomOutScan20(self, quantity = 20):
|
def zoomOutScan20(self, quantity = 20):
|
||||||
if self.imageViewer.image:
|
if self.imageViewer.image and int(self.imageViewer.width * (self.imageViewer.imgZoom - quantity + 100) / 100) > 100:
|
||||||
self.imageViewer.imgZoom -= quantity
|
self.imageViewer.imgZoom -= quantity
|
||||||
self.resizeScan()
|
self.resizeScan()
|
||||||
|
|
||||||
@ -884,7 +902,7 @@ class mainWindow(Tk):
|
|||||||
self.resizeScan()
|
self.resizeScan()
|
||||||
|
|
||||||
def zoomOutScan(self, quantity = 1):
|
def zoomOutScan(self, quantity = 1):
|
||||||
if self.imageViewer.image:
|
if self.imageViewer.image and int(self.imageViewer.width * (self.imageViewer.imgZoom - quantity + 100) / 100) > 100:
|
||||||
self.imageViewer.imgZoom -= quantity
|
self.imageViewer.imgZoom -= quantity
|
||||||
self.resizeScan()
|
self.resizeScan()
|
||||||
|
|
||||||
@ -996,6 +1014,9 @@ class mainWindow(Tk):
|
|||||||
dim = (int(width * (self.imageViewer.imgZoom + 100) / 100), int(height * (self.imageViewer.imgZoom + 100) / 100))
|
dim = (int(width * (self.imageViewer.imgZoom + 100) / 100), int(height * (self.imageViewer.imgZoom + 100) / 100))
|
||||||
cv_img = cv2.resize(cv_img, dim, interpolation = cv2.INTER_AREA)
|
cv_img = cv2.resize(cv_img, dim, interpolation = cv2.INTER_AREA)
|
||||||
|
|
||||||
|
# Update shape
|
||||||
|
self.imageViewer.height, self.imageViewer.width = cv_img.shape[:2]
|
||||||
|
|
||||||
# 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.DisplayUpdate( photo)
|
self.DisplayUpdate( photo)
|
||||||
@ -1018,7 +1039,7 @@ class mainWindow(Tk):
|
|||||||
self.DisplayUpdate(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))
|
||||||
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"])
|
critical.crashCNIR(False, "OpenCV resizeScan() error")
|
||||||
self.initialize()
|
self.initialize()
|
||||||
|
|
||||||
## IHM and user interface related functions
|
## IHM and user interface related functions
|
||||||
@ -1057,9 +1078,15 @@ class mainWindow(Tk):
|
|||||||
|
|
||||||
def openIssuePage(self):
|
def openIssuePage(self):
|
||||||
"""
|
"""
|
||||||
Opens the Github Issue Repository page
|
Sends a bug report
|
||||||
"""
|
"""
|
||||||
webbrowser.open_new("https://github.com/neox95/CNIRevelator/issues")
|
critical.crashCNIR(shutdown=False, option="Voluntary Bug Report", isVoluntary=True)
|
||||||
|
|
||||||
|
def openProjectPage(self):
|
||||||
|
"""
|
||||||
|
Opens the Project Repository webpage
|
||||||
|
"""
|
||||||
|
webbrowser.open_new("https://github.com/neox95/CNIRevelator")
|
||||||
|
|
||||||
def showChangeLog(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 = ihm.ChangelogDialog(self, ('{} : CNIRevelator {}\n\n{}'.format(lang.all[globs.CNIRlang]["Program version"], globs.verstring_full, lang.all[globs.CNIRlang]["CHANGELOG"])))
|
||||||
@ -1072,7 +1099,7 @@ class mainWindow(Tk):
|
|||||||
"""
|
"""
|
||||||
Update Settings
|
Update Settings
|
||||||
"""
|
"""
|
||||||
changeupdateWin = ihm.updateSetDialog(self)
|
changeupdateWin = ihm.updateSetDialog(self, updater.getUpdateChannel())
|
||||||
changeupdateWin.transient(self)
|
changeupdateWin.transient(self)
|
||||||
changeupdateWin.grab_set()
|
changeupdateWin.grab_set()
|
||||||
changeupdateWin.focus_force()
|
changeupdateWin.focus_force()
|
||||||
@ -1082,7 +1109,7 @@ class mainWindow(Tk):
|
|||||||
"""
|
"""
|
||||||
Lang Settings
|
Lang Settings
|
||||||
"""
|
"""
|
||||||
changelangWin = ihm.langDialog(self)
|
changelangWin = ihm.langDialog(self, globs.CNIRlang)
|
||||||
changelangWin.transient(self)
|
changelangWin.transient(self)
|
||||||
changelangWin.grab_set()
|
changelangWin.grab_set()
|
||||||
changelangWin.focus_force()
|
changelangWin.focus_force()
|
||||||
|
35
src/mrz.py
35
src/mrz.py
@ -490,18 +490,19 @@ def getDocInfos(doc, code):
|
|||||||
for field in infoTypes:
|
for field in infoTypes:
|
||||||
|
|
||||||
value = code[ field[1][0] : field[1][1] ].replace("<", " ").strip()
|
value = code[ field[1][0] : field[1][1] ].replace("<", " ").strip()
|
||||||
|
res[field[0]] = [0,0]
|
||||||
|
|
||||||
# State code
|
# State code
|
||||||
if field[0] == 'PAYS' or field[0] == 'NAT':
|
if field[0] == 'PAYS' or field[0] == 'NAT':
|
||||||
try:
|
try:
|
||||||
if len(value) == 3 and value[-1] != "<":
|
if len(value) == 3 and value[-1] != "<":
|
||||||
res[field[0]] = landcode3[value]
|
res[field[0]] = (landcode3[value], True)
|
||||||
elif len(value) == 3 and value[-1] == "<":
|
elif len(value) == 3 and value[-1] == "<":
|
||||||
res[field[0]] = landcode2[value[:-1]]
|
res[field[0]] = (landcode2[value[:-1]], True)
|
||||||
else:
|
else:
|
||||||
res[field[0]] = landcode2[value]
|
res[field[0]] = (landcode2[value], True)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
res[field[0]] = False
|
res[field[0]] = [value, False]
|
||||||
|
|
||||||
# Dates
|
# Dates
|
||||||
elif field[0][1:] == 'DATE':
|
elif field[0][1:] == 'DATE':
|
||||||
@ -517,39 +518,43 @@ def getDocInfos(doc, code):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
#print(value)
|
#print(value)
|
||||||
if value != "":
|
if value != "":
|
||||||
res[field[0]] = False
|
res[field[0]] = [value, False]
|
||||||
else:
|
else:
|
||||||
res[field[0]] = value
|
res[field[0]] = [value, True]
|
||||||
|
|
||||||
# Numbers
|
# Numbers
|
||||||
elif field[0][:-1] == 'NOINT':
|
elif field[0][:-1] == 'NOINT':
|
||||||
try:
|
try:
|
||||||
res["NO"] += value
|
res["NO"][0] += value
|
||||||
|
res["NO"][1] = True
|
||||||
except KeyError:
|
except KeyError:
|
||||||
res["NO"] = value
|
res["NO"] = [value, True]
|
||||||
|
|
||||||
elif field[0] == 'NOINT':
|
elif field[0] == 'NOINT':
|
||||||
try:
|
try:
|
||||||
res["NO"] += value
|
res["NO"][0] += value
|
||||||
|
res["NO"][1] = True
|
||||||
except KeyError:
|
except KeyError:
|
||||||
res["NO"] = value
|
res["NO"] = [value, True]
|
||||||
|
|
||||||
elif field[0] == 'FACULT':
|
elif field[0] == 'FACULT':
|
||||||
try:
|
try:
|
||||||
res["INDIC"] += value
|
res["INDIC"][0] += value
|
||||||
|
res["INDIC"][1] = True
|
||||||
except KeyError:
|
except KeyError:
|
||||||
res["INDIC"] = value
|
res["INDIC"] = [value, True]
|
||||||
|
|
||||||
# Sex
|
# Sex
|
||||||
elif field[0] == 'SEX':
|
elif field[0] == 'SEX':
|
||||||
if not value in "MF":
|
if not value in "MF":
|
||||||
res[field[0]] = False
|
res[field[0]] = [value, False]
|
||||||
else:
|
else:
|
||||||
res[field[0]] = value
|
res[field[0]] = [value, True]
|
||||||
|
|
||||||
# All other cases
|
# All other cases
|
||||||
else:
|
else:
|
||||||
if value != "":
|
if value != "":
|
||||||
res[field[0]] = value
|
res[field[0]] = [value, True]
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
* along with CNIRevelator. If not, see <https:*www.gnu.org/licenses/>. *
|
* along with CNIRevelator. If not, see <https:*www.gnu.org/licenses/>. *
|
||||||
********************************************************************************
|
********************************************************************************
|
||||||
"""
|
"""
|
||||||
|
import logger # logger.pu
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import Image
|
import Image
|
||||||
@ -248,7 +248,7 @@ def image_to_string(image, lang=None, config='', nice=0, boxes=False, output_typ
|
|||||||
Returns the result of a Tesseract OCR run on the provided image to string
|
Returns the result of a Tesseract OCR run on the provided image to string
|
||||||
"""
|
"""
|
||||||
if boxes:
|
if boxes:
|
||||||
print("\nWarning: Argument 'boxes' is deprecated and will be removed in future versions. Use function image_to_boxes instead.\n")
|
logfile.printdbg("\nWarning: Argument 'boxes' is deprecated and will be removed in future versions. Use function image_to_boxes instead.\n")
|
||||||
return image_to_boxes(image, lang, config, nice, output_type)
|
return image_to_boxes(image, lang, config, nice, output_type)
|
||||||
else:
|
else:
|
||||||
args = [
|
args = [
|
||||||
@ -317,7 +317,7 @@ def main():
|
|||||||
sys.stderr.write('Usage: python pytesseract.py [-l lang] input_file\n')
|
sys.stderr.write('Usage: python pytesseract.py [-l lang] input_file\n')
|
||||||
exit(2)
|
exit(2)
|
||||||
try:
|
try:
|
||||||
print(image_to_string((Image.open(filename)), lang=lang))
|
logfile.printdbg(image_to_string((Image.open(filename)), lang=lang))
|
||||||
except IOError:
|
except IOError:
|
||||||
sys.stderr.write('ERROR: Could not open file "%s"\n' % filename)
|
sys.stderr.write('ERROR: Could not open file "%s"\n' % filename)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -88,14 +88,38 @@ def exitProcess(arg):
|
|||||||
process.terminate()
|
process.terminate()
|
||||||
sys.exit(arg)
|
sys.exit(arg)
|
||||||
|
|
||||||
def updateChannel(choice):
|
def setUpdateChannel(choice):
|
||||||
|
"""
|
||||||
|
Sets the new update channel and forces new update at next launch
|
||||||
|
"""
|
||||||
if choice == "Beta":
|
if choice == "Beta":
|
||||||
with open(globs.CNIRUrlConfig, 'w') as (configFile):
|
with open(globs.CNIRUrlConfig, 'w') as (configFile):
|
||||||
configFile.write("{}\n0\n0".format(globs.CNIRBetaURL))
|
configFile.write("{}\n0\n0".format(globs.CNIRBetaURL))
|
||||||
else:
|
# Force new update
|
||||||
|
try:
|
||||||
|
os.remove(globs.CNIRLastUpdate)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
elif choice == "Stable":
|
||||||
with open(globs.CNIRUrlConfig, 'w') as (configFile):
|
with open(globs.CNIRUrlConfig, 'w') as (configFile):
|
||||||
configFile.write("{}\n0\n0".format(globs.CNIRDefaultURL))
|
configFile.write("{}\n0\n0".format(globs.CNIRDefaultURL))
|
||||||
|
# Force new update
|
||||||
|
try:
|
||||||
|
os.remove(globs.CNIRLastUpdate)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def getUpdateChannel():
|
||||||
|
"""
|
||||||
|
Returns the current update channel
|
||||||
|
"""
|
||||||
|
with open(globs.CNIRUrlConfig, 'r') as (configFile):
|
||||||
|
url = configFile.read()
|
||||||
|
if not "master" in url:
|
||||||
|
return "Beta"
|
||||||
|
else:
|
||||||
|
return "Stable"
|
||||||
|
|
||||||
def getLatestVersion(credentials):
|
def getLatestVersion(credentials):
|
||||||
"""
|
"""
|
||||||
Returns the latest version of the software
|
Returns the latest version of the software
|
||||||
@ -354,8 +378,12 @@ def umain():
|
|||||||
credentials = downloader.newcredentials()
|
credentials = downloader.newcredentials()
|
||||||
|
|
||||||
if not credentials.valid:
|
if not credentials.valid:
|
||||||
logfile.printerr("Credentials Error. No effective update !")
|
if credentials.login == "nointernet":
|
||||||
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Credentials Error. No effective update !"])
|
logfile.printerr("No Internet Error. No effective update !")
|
||||||
|
launcherWindow.printmsg(lang.all[globs.CNIRlang]["No Internet Error. No effective update !"])
|
||||||
|
else:
|
||||||
|
logfile.printerr("Credentials Error. No effective update !")
|
||||||
|
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Credentials Error. No effective update !"])
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
launcherWindow.exit()
|
launcherWindow.exit()
|
||||||
return 0
|
return 0
|
||||||
@ -371,25 +399,15 @@ def umain():
|
|||||||
# Reading it
|
# Reading it
|
||||||
lastUpdate = datetime.datetime.strptime(configFile.read(),"%d/%m/%Y")
|
lastUpdate = datetime.datetime.strptime(configFile.read(),"%d/%m/%Y")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
critical.crashCNIR()
|
critical.crashCNIR(False)
|
||||||
raise IOError(str(e))
|
time.sleep(3)
|
||||||
|
launcherWindow.exit()
|
||||||
|
return 1
|
||||||
else:
|
else:
|
||||||
# Recreating the url file
|
lastUpdate = datetime.datetime(1970,1,1)
|
||||||
lastUpdate = currentDate
|
|
||||||
try:
|
|
||||||
os.mkdir(globs.CNIRFolder + '\\config')
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
with open(globs.CNIRLastUpdate, 'w') as (configFile):
|
|
||||||
try:
|
|
||||||
# Writing it
|
|
||||||
configFile.write("{}/{}/{}".format(currentDate.day, currentDate.month, currentDate.year))
|
|
||||||
except Exception as e:
|
|
||||||
critical.crashCNIR()
|
|
||||||
raise IOError(str(e))
|
|
||||||
|
|
||||||
if not globs.CNIRNewVersion and os.path.exists(globs.CNIRFolder + '\\Tesseract-OCR5\\') and (currentDate - lastUpdate).days < 7:
|
if not globs.CNIRNewVersion and os.path.exists(globs.CNIRFolder + '\\Tesseract-OCR5\\') and (currentDate - lastUpdate).days < 7:
|
||||||
|
logfile.printdbg("No need to update, {} days remaining".format(7 - (currentDate - lastUpdate).days))
|
||||||
launcherWindow.exit()
|
launcherWindow.exit()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@ -399,7 +417,7 @@ def umain():
|
|||||||
# EXECUTING THE UPDATE BATCH
|
# EXECUTING THE UPDATE BATCH
|
||||||
success = batch(credentials)
|
success = batch(credentials)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
critical.crashCNIR()
|
critical.crashCNIR(False)
|
||||||
launcherWindow.printmsg('ERROR : ' + str(e))
|
launcherWindow.printmsg('ERROR : ' + str(e))
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
launcherWindow.exit()
|
launcherWindow.exit()
|
||||||
@ -408,20 +426,36 @@ def umain():
|
|||||||
if success:
|
if success:
|
||||||
logfile.printdbg("Software is up-to-date !")
|
logfile.printdbg("Software is up-to-date !")
|
||||||
launcherWindow.printmsg('Software is up-to-date !')
|
launcherWindow.printmsg('Software is up-to-date !')
|
||||||
|
# Recreating the url file
|
||||||
|
lastUpdate = currentDate
|
||||||
|
try:
|
||||||
|
os.mkdir(globs.CNIRFolder + '\\config')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
with open(globs.CNIRLastUpdate, 'w') as (configFile):
|
||||||
|
try:
|
||||||
|
# Writing it
|
||||||
|
configFile.write("{}/{}/{}".format(currentDate.day, currentDate.month, currentDate.year))
|
||||||
|
except Exception as e:
|
||||||
|
critical.crashCNIR(False)
|
||||||
|
time.sleep(3)
|
||||||
|
launcherWindow.exit()
|
||||||
|
return
|
||||||
|
if UPDATE_IS_MADE:
|
||||||
|
launcherWindow.exit()
|
||||||
|
return 0
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logfile.printerr("An error occured. No effective update !")
|
logfile.printerr("An error occured. No effective update !")
|
||||||
launcherWindow.printmsg(lang.all[globs.CNIRlang]['An error occured. No effective update !'])
|
launcherWindow.printmsg(lang.all[globs.CNIRlang]['An error occured. No effective update !'])
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
launcherWindow.exit()
|
launcherWindow.exit()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if UPDATE_IS_MADE:
|
|
||||||
launcherWindow.exit()
|
|
||||||
return 0
|
|
||||||
except:
|
except:
|
||||||
critical.crashCNIR()
|
critical.crashCNIR(False)
|
||||||
launcherWindow.exit()
|
launcherWindow.exit()
|
||||||
sys.exit(2)
|
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -429,7 +463,7 @@ def umain():
|
|||||||
# INSTALLING TESSERACT OCR
|
# INSTALLING TESSERACT OCR
|
||||||
success = tessInstall(globs.CNIRFolder, credentials)
|
success = tessInstall(globs.CNIRFolder, credentials)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
critical.crashCNIR()
|
critical.crashCNIR(False)
|
||||||
launcherWindow.printmsg('ERROR : ' + str(e))
|
launcherWindow.printmsg('ERROR : ' + str(e))
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
launcherWindow.exit()
|
launcherWindow.exit()
|
||||||
@ -446,9 +480,8 @@ def umain():
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
except:
|
except:
|
||||||
critical.crashCNIR()
|
critical.crashCNIR(False)
|
||||||
launcherWindow.exit()
|
launcherWindow.exit()
|
||||||
exitProcess(2)
|
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
@ -6,8 +6,8 @@ VSVersionInfo(
|
|||||||
ffi=FixedFileInfo(
|
ffi=FixedFileInfo(
|
||||||
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
||||||
# Set not needed items to zero 0.
|
# Set not needed items to zero 0.
|
||||||
filevers=(3, 1, 4, 0),
|
filevers=(3, 1, 5, 0),
|
||||||
prodvers=(3, 1, 4, 0),
|
prodvers=(3, 1, 5, 0),
|
||||||
# Contains a bitmask that specifies the valid bits 'flags'r
|
# Contains a bitmask that specifies the valid bits 'flags'r
|
||||||
mask=0x3f,
|
mask=0x3f,
|
||||||
# Contains a bitmask that specifies the Boolean attributes of the file.
|
# Contains a bitmask that specifies the Boolean attributes of the file.
|
||||||
@ -31,12 +31,12 @@ StringFileInfo(
|
|||||||
u'040904B0',
|
u'040904B0',
|
||||||
[StringStruct(u'CompanyName', u'Adrien Bourmault (neox95)'),
|
[StringStruct(u'CompanyName', u'Adrien Bourmault (neox95)'),
|
||||||
StringStruct(u'FileDescription', u'This file is part of CNIRevelator.'),
|
StringStruct(u'FileDescription', u'This file is part of CNIRevelator.'),
|
||||||
StringStruct(u'FileVersion', u'3.1.4'),
|
StringStruct(u'FileVersion', u'3.1.5'),
|
||||||
StringStruct(u'InternalName', u'CNIRevelator'),
|
StringStruct(u'InternalName', u'CNIRevelator'),
|
||||||
StringStruct(u'LegalCopyright', u'Copyright (c) Adrien Bourmault (neox95)'),
|
StringStruct(u'LegalCopyright', u'Copyright (c) Adrien Bourmault (neox95)'),
|
||||||
StringStruct(u'OriginalFilename', u'CNIRevelator.exe'),
|
StringStruct(u'OriginalFilename', u'CNIRevelator.exe'),
|
||||||
StringStruct(u'ProductName', u'CNIRevelator 3.1'),
|
StringStruct(u'ProductName', u'CNIRevelator 3.1'),
|
||||||
StringStruct(u'ProductVersion', u'3.1.4')])
|
StringStruct(u'ProductVersion', u'3.1.5')])
|
||||||
]),
|
]),
|
||||||
VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
|
VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user