diff --git a/CNIRevelator Documentation.docx b/CNIRevelator Documentation.docx
index 5ee8079..d361ab2 100644
Binary files a/CNIRevelator Documentation.docx and b/CNIRevelator Documentation.docx differ
diff --git a/VERSIONS.LST b/VERSIONS.LST
index 2f449bd..5a70410 100644
--- a/VERSIONS.LST
+++ b/VERSIONS.LST
@@ -1,2 +1,2 @@
-# ver|url|checksum, and | as separator, one version per ||
-3.1.2|https://github.com/neox95/CNIRevelator/releases/download/3.1.2d/CNIRevelator.zip|8ed839f59ac63994fab1a5ceefbe183f04e89162||
+# ver|url|checksum, and | as separator, one version per ||
+3.1.3|https://github.com/neox95/CNIRevelator/releases/download/3.1.3e/CNIRevelator.zip|f42bb2cc8e72aa21caae4ea058ca1603e4153f48||
diff --git a/make.bat b/make.bat
index 5d6414b..2f31cc6 100644
--- a/make.bat
+++ b/make.bat
@@ -4,9 +4,9 @@ title Compilation de CNIRevelator
-call pyinstaller -w -D --exclude-module PyQt5 --bootloader-ignore-signals --add-data "C:\Users\adrie\Anaconda3\Lib\site-packages\tld\res\effective_tld_names.dat.txt";"tld\res" --add-data "src\id-card.ico";"id-card.ico" -i "src\id-card.ico" -n CNIRevelator src\CNIRevelator.py
-
+call pyinstaller -w -D --exclude-module PyQt5 --bootloader-ignore-signals --add-data "C:\Users\pf04950\AppData\Local\Continuum\anaconda3\Lib\site-packages\tld\res\effective_tld_names.dat.txt";"tld\res" --add-data "src\id-card.ico";"id-card.ico" -i "src\id-card.ico" --version-file "src\version.res" -n CNIRevelator src\CNIRevelator.py
+rem call pyi-set_version "src\version.res" "dist\CNIRevelator\CNIRevelator.exe"
copy LICENSE dist\CNIRevelator\LICENSE
copy src\id-card.ico dist\CNIRevelator\id-card.ico
diff --git a/src/critical.py b/src/critical.py
index 3e6fb08..d04f643 100644
--- a/src/critical.py
+++ b/src/critical.py
@@ -31,9 +31,10 @@ import traceback
import psutil
import os
-import lang # lang.py
-import logger # logger.py
-import globs # globs.py
+import lang # lang.py
+import logger # logger.py
+import globs # globs.py
+import github # github.py
def crashCNIR(shutdown=True):
"""
@@ -45,13 +46,29 @@ def crashCNIR(shutdown=True):
root.withdraw()
logfile = logger.logCur
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 the log file ?"])
+
+ res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to report this bug ?"])
if res == "yes":
- webbrowser.open_new(globs.CNIRErrLog)
- res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to open an issue on Github to report this bug ?"])
- if res == "yes":
- webbrowser.open_new("https://github.com/neox95/CNIRevelator/issues")
+ # read the log
+ data = "No log."
+ try:
+ with open(globs.CNIRMainLog, 'r') as file:
+ data = file.read()
+ except:
+ pass
+
+ # send it
+ success = github.reportBug(traceback.format_exc(), data)
+
+ if not success:
+ res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to open the log file ?"])
+ if res == "yes":
+ webbrowser.open_new(globs.CNIRErrLog)
+ else:
+ showinfo(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Bug reported successfully. Thanks."])
+
root.destroy()
# Quit ?
diff --git a/src/github.py b/src/github.py
new file mode 100644
index 0000000..47c4730
--- /dev/null
+++ b/src/github.py
@@ -0,0 +1,49 @@
+# -*- coding: utf8 -*-
+"""
+********************************************************************************
+* CNIRevelator *
+* *
+* Desc: Github Stuff for CNIRevelator *
+* *
+* 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 . *
+********************************************************************************
+"""
+from requests.auth import HTTPProxyAuth
+from pypac import PACSession
+from requests import Session
+import json
+
+credentials = False
+
+def reportBug(reason="",log=""):
+
+ if not credentials:
+ return False
+
+ 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"]}
+
+ handler = session.post('https://api.github.com/repos/neox95/cnirevelator/issues', headers={'Authorization': 'token %s' % "1a3c589eafc2b6557a1da852a3b2cc279bd5bf33"}, data=json.dumps(payload))
+
+ if handler.reason == "Created":
+ return True
+ else:
+ return False
+
+
diff --git a/src/globs.py b/src/globs.py
index a0e031f..742343e 100644
--- a/src/globs.py
+++ b/src/globs.py
@@ -27,7 +27,7 @@ import os
# CNIRevelator version
verType = "final release"
-version = [3, 1, 2]
+version = [3, 1, 3]
verstring_full = "{}.{}.{} {}".format(version[0], version[1], version[2], verType)
verstring = "{}.{}".format(version[0], version[1])
diff --git a/src/ihm.py b/src/ihm.py
index 672233f..ca5e68a 100644
--- a/src/ihm.py
+++ b/src/ihm.py
@@ -296,8 +296,6 @@ class LauncherWindow(Tk):
# if getattr(sys, 'frozen', False):
# cv_img = cv2.imread(sys._MEIPASS + r"\background.png\background.png")
# else:
- cv_img = cv2.imread("background.png")
-
cv_img = cv2.imread("background.png")
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
cv_img = cv2.blur(cv_img, (15, 15))
diff --git a/src/lang.py b/src/lang.py
index 6706883..66505a7 100644
--- a/src/lang.py
+++ b/src/lang.py
@@ -51,11 +51,13 @@ french = \
"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.",
+"an issue on Github" : "CNIRevelator s'est arrêté car une erreur fatale s'est produite. Consultez le journal pour plus d'informations et signalez le bogue.",
"Would you like to open the "
-"log file ?" : "Souhaitez-vous ouvrir le fichier de log ?",
-"Would you like to open an issue "
-"on Github to report this bug ?" : "Souhaitez-vous ouvrir un ticket sur Github pour signaler ce bogue?",
+"log file ?" : "Le signalement a échoué. Souhaitez-vous ouvrir le fichier de log ?",
+"Bug reported successfully. "
+"Thanks." : "Bogue signalé avec succès, merci.",
+"Would you like to report this "
+"bug ?" : "Souhaitez-vous signaler ce bogue?",
"Starting..." : "Lancement...",
"Informations about the current "
"document" : "Informations sur la pièce d'identité",
@@ -139,7 +141,8 @@ french = \
"Coller :\t\t\t\tCtrl-V \n"
"Forcer une nouvelle détection du document :\tEchap\n",
-"CHANGELOG" : "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" + \
+"CHANGELOG" : "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.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.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\n- Ajout des canaux de mise-à-jour\n\n" + \
"Version 3.0.8 finale\nCorrectif : bug du système de mise-à-jour'\n\n" + \
@@ -751,11 +754,13 @@ english = \
"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 ?",
+"an issue on Github" : "CNIRevelator crashed because a fatal error occured. View log for more infos and please report this bug.",
+"Would you like to report this "
+"bug ?" : "Would you like to report this bug ?",
"Would you like to open the "
-"log file ?" : "Would you like to open the log file ?",
+"log file ?" : "Reporting the bug has failed. Would you like to open the log file ?",
+"Bug reported successfully. "
+"Thanks." : "Bug reported successfully. Thanks.",
"Starting..." : "Starting...",
"Informations about the current "
"document" : "Informations about the current document",
@@ -841,7 +846,8 @@ english = \
"Paste:\t\t\t\tCtrl-V\n"
"Force a new document detection:\tEchap\n",
-"CHANGELOG" : "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" + \
+"CHANGELOG" : "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.1 \nMinor update with the following progressions: \n- Fixed a severe bug in the update system\n\n" + \
"Version 3.1.0 \nMajor update with the following progressions: \n- Cosmetic modifications of the user interface \n- Stabilization of the changes made on the minor version 3.0 : user interface, OCR, VISA A and B, logging\n- Rationalization of the language system\n- Added update channels\n\n" + \
"Version 3.0.8 final\nCorrection: bug in the update system'\n\n" + \
diff --git a/src/main.py b/src/main.py
index cd4ea93..0274f76 100644
--- a/src/main.py
+++ b/src/main.py
@@ -311,9 +311,9 @@ class mainWindow(Tk):
self.speed731.grid_columnconfigure(9, weight=1)
self.speed731.grid_rowconfigure(0, weight=1)
self.speed731text = Entry(self.speed731, font='Terminal 14')
- self.speed731text.grid(column=0, row=0, sticky='NEW', padx=5, pady=5)
+ self.speed731text.grid(column=0, row=0, columnspan=7, sticky='NEW', padx=5, pady=5)
self.speedResult = Text((self.speed731), state='disabled', width=1, height=1, wrap='none', font='Terminal 14')
- self.speedResult.grid(column=2, row=0, sticky='NEW', padx=5, pady=5)
+ self.speedResult.grid(column=7, row=0, sticky='NEW', padx=5, pady=5)
# The monitor that indicates some useful infos
self.monitor = ttk.Labelframe(self, text=lang.all[globs.CNIRlang]["Monitor"])
@@ -384,7 +384,7 @@ class mainWindow(Tk):
self.imageViewer.pagenumber = 0
# Some bindings
- self.termtext.bind('', self.entryValidation)
+ self.bind('', self.entryValidation)
self.termtext.bind('<>', self.pasteValidation)
self.speed731text.bind('', self.speedValidation)
self.imageViewer.ZONE.bind("", self.rectangleSelectScan)
@@ -478,7 +478,7 @@ class mainWindow(Tk):
self.termtext.insert("1.0", self.mrzChar)
self.mrzChar = self.mrzChar + char
- self.stringValidation("")
+ self.stringValidation(isFull=True)
#print(self.mrzChar)
# Reinstall tesseract
@@ -497,7 +497,7 @@ class mainWindow(Tk):
## Regex and document detection + control related functions
- def stringValidation(self, keysym):
+ def stringValidation(self, keysym="", isFull=False):
"""
Analysis of the already typed document
"""
@@ -505,7 +505,7 @@ class mainWindow(Tk):
# If we must decide the type of the document
if not self.mrzDecided:
# Get the candidates
- candidates = mrz.allDocMatch(self.mrzChar.split("\n"))
+ candidates = mrz.allDocMatch(self.mrzChar.split("\n"), final=isFull)
if len(candidates) == 2 and len(self.mrzChar) >= 8:
# Parameters for the choice invite
@@ -545,10 +545,13 @@ class mainWindow(Tk):
self.termtext.insert("1.0", self.mrzChar)
# stop when limit reached
elif (len(self.mrzChar) - 3 >= 2 * len(self.mrzDecided[0][0])):
- self.mrzChar = self.termtext.get("1.0", "end")[:-1]
- self.termtext.delete("1.0","end")
- self.termtext.insert("1.0", self.mrzChar[:-1])
- self.termtext.mark_set(INSERT, curPos)
+ i = len(self.mrzChar) - 3
+ while i >= 2 * len(self.mrzDecided[0][0]):
+ i-=1
+ self.mrzChar = self.termtext.get("1.0", "end")[:-1]
+ self.termtext.delete("1.0","end")
+ self.termtext.insert("1.0", self.mrzChar[:-1])
+ self.termtext.mark_set(INSERT, curPos)
# compute the control sum if needed
self.computeSigma()
@@ -720,9 +723,14 @@ class mainWindow(Tk):
if key in ["CODE", "CTRL", "CTRLF"]:
continue
if not docInfos[key] == False:
- self.infoList[key]['text'] = docInfos[key]
- self.infoList[key]['background'] = self['background']
- self.infoList[key]['foreground'] = "black"
+ if not docInfos[key] == "":
+ self.infoList[key]['text'] = docInfos[key]
+ self.infoList[key]['background'] = self['background']
+ self.infoList[key]['foreground'] = "black"
+ else:
+ self.infoList[key]['text'] = lang.all[globs.CNIRlang]["Unknown"]
+ self.infoList[key]['background'] = self['background']
+ self.infoList[key]['foreground'] = "black"
else:
self.infoList[key]['background'] = "red"
self.infoList[key]['foreground'] = "white"
@@ -789,6 +797,7 @@ class mainWindow(Tk):
"""
Open the scan, ask its path and displays it
"""
+ self.initialize()
path = ''
path = filedialog.askopenfilename(parent=self, title=lang.all[globs.CNIRlang]["Open a scan of document..."], filetypes=(('TIF files', '*.tif'),
('TIF files', '*.tiff'),
@@ -806,7 +815,7 @@ class mainWindow(Tk):
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
+ return
# Load an image using OpenCV
self.imageViewer.imagePath = path
diff --git a/src/mrz.py b/src/mrz.py
index 190b5b4..a2013d4 100644
--- a/src/mrz.py
+++ b/src/mrz.py
@@ -151,7 +151,7 @@ VA = [
{
"1": ["2", "CODE", "V."],
"2": ["3", "PAYS", "[A-Z]+"],
- "3": ["39", "NOM", "[A-Z]+"],
+ "3": ["39", "NOM", "([A-Z]|<)+"],
"4": ["9", "NO", ".+"],
"5": ["1", "CTRL", "[0-9]","4"],
"6": ["3", "NAT", "[A-Z]+"],
@@ -342,7 +342,7 @@ def docMatch(doc, strs):
# logfile.printdbg(" REGEX : {}, match : {}".format(regex, matching))
# exit the loop
- #logfile.printdbg("{} level : {}/{} (+{})".format(doc[2], level, nchar, bonus))
+ logfile.printdbg("{} level : {}/{} (+{})".format(doc[2], level, nchar, bonus))
return (level, nchar, bonus)
def allDocMatch(strs, final=False):
@@ -368,14 +368,25 @@ def allDocMatch(strs, final=False):
candidate = SCORES.index(max(SCORES))
candidates = []
canditxt = []
+
# Search the candidates
for i in range(len(SCORES)):
if SCORES[i] == SCORES[candidate]:
candidates += [TYPES[i]]
canditxt += [TYPES[i][2]]
+ # Continue searching
+ if len(candidates) < 2:
+ tempRemovedCandidate = SCORES.pop(candidate)
+ if (SCORES.index(max(SCORES)) != candidate) and (max(SCORES) >= tempRemovedCandidate - 20):
+ if SCORES.index(max(SCORES)) < candidate:
+ candidates += [ TYPES[SCORES.index(max(SCORES))] ]
+ else:
+ candidates += [ TYPES[SCORES.index(max(SCORES)) + 1] ]
+ SCORES.insert(candidate, tempRemovedCandidate)
+
# Return the candidates
- #logfile.printdbg("Scores : {}".format(SCORES))
- #logfile.printdbg("Candidates : {}".format(canditxt))
+ logfile.printdbg("Scores : {}".format(SCORES))
+ logfile.printdbg("Candidates : {}".format(canditxt))
return candidates
def computeControlSum(code):
@@ -413,6 +424,11 @@ def computeAllControlSum(doc, code):
# iteration on each char of the given MRZ
for charPos in range(len(code)):
+
+ # Sanity check
+ if len(getDocString(doc)) <= charPos:
+ break
+
field = getDocString(doc)[charPos]
if doc[1][field][1] == "CTRL":
@@ -421,6 +437,12 @@ def computeAllControlSum(doc, code):
codeChain = ""
# iteration on the fields to control
for pos in range(len(code)):
+
+ #print("Len : {}, pos : {}".format(len(getDocString(doc)), pos))
+ # Sanity check
+ if len(getDocString(doc)) <= pos:
+ break
+
target = getDocString(doc)[pos]
if target in doc[1][field][3]:
#print("__field : {} {} {} {}".format(target, pos, field, doc[1][field][3]))
diff --git a/src/updater.py b/src/updater.py
index 54e08ae..4f69f94 100644
--- a/src/updater.py
+++ b/src/updater.py
@@ -38,6 +38,7 @@ import subprocess
import psutil
import critical # critical.py
+import github # github.py
import ihm # ihm.py
import logger # logger.py
import globs # globs.py
@@ -316,7 +317,6 @@ def umain():
# Global Handlers
logfile = logger.logCur
-
credentials = downloader.newcredentials()
if not credentials.valid:
@@ -325,6 +325,8 @@ def umain():
time.sleep(2)
launcherWindow.exit()
return 0
+
+ github.credentials = credentials
# Cleaner for the old version if detected
if len(sys.argv) > 2 and str(sys.argv[1]) == "DELETE":
diff --git a/src/version.res b/src/version.res
new file mode 100644
index 0000000..43adb08
--- /dev/null
+++ b/src/version.res
@@ -0,0 +1,43 @@
+# UTF-8
+#
+# For more details about fixed file info 'ffi' see:
+# http://msdn.microsoft.com/en-us/library/ms646997.aspx
+VSVersionInfo(
+ ffi=FixedFileInfo(
+# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
+# Set not needed items to zero 0.
+filevers=(3, 1, 3, 0),
+prodvers=(3, 1, 3, 0),
+# Contains a bitmask that specifies the valid bits 'flags'r
+mask=0x3f,
+# Contains a bitmask that specifies the Boolean attributes of the file.
+flags=0x0,
+# The operating system for which this file was designed.
+# 0x4 - NT and there is no need to change it.
+OS=0x4,
+# The general type of file.
+# 0x1 - the file is an application.
+fileType=0x1,
+# The function of the file.
+# 0x0 - the function is not defined for this fileType
+subtype=0x0,
+# Creation date and time stamp.
+date=(0, 0)
+),
+ kids=[
+StringFileInfo(
+ [
+ StringTable(
+ u'040904B0',
+ [StringStruct(u'CompanyName', u'Adrien Bourmault (neox95)'),
+ StringStruct(u'FileDescription', u'This file is part of CNIRevelator.'),
+ StringStruct(u'FileVersion', u'3.1.3'),
+ StringStruct(u'InternalName', u'CNIRevelator'),
+ StringStruct(u'LegalCopyright', u'Copyright (c) Adrien Bourmault (neox95)'),
+ StringStruct(u'OriginalFilename', u'CNIRevelator.exe'),
+ StringStruct(u'ProductName', u'CNIRevelator 3'),
+ StringStruct(u'ProductVersion', u'3.1.3')])
+ ]),
+VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
+ ]
+)
\ No newline at end of file