Compare commits

...

135 Commits

Author SHA1 Message Date
Adrien Bourmault e52c34319f
Update README.MD 2020-01-06 00:00:22 +01:00
Adrien Bourmault fba076d245
test gpg 2019-10-06 21:17:39 +02:00
Adrien Bourmault 9ca31bd744
test gpg 2019-10-06 21:14:39 +02:00
Adrien Bourmault 3ab1ed9570
Test ssh 2019-09-26 19:01:10 +02:00
Adrien Bourmault db84dbd13c Update VERSIONS.LST 2019-08-30 15:26:08 +02:00
Adrien Bourmault 88c41b2a48 Update VERSIONS.LST 2019-08-30 15:26:08 +02:00
Adrien Bourmault 17acb12992 Enhancing UI/Infos and resolving bugs about Visas 2019-08-30 15:26:08 +02:00
Adrien Bourmault bbb2e43f61
Merge pull request #47 from neox95/v3.1
V3.1.5
2019-08-30 11:25:58 +02:00
Adrien Bourmault 01b4a6ea4b
Update VERSIONS.LST 2019-08-30 11:21:17 +02:00
Adrien Bourmault f744c6fedd
Correcting some bugs and enhance the selection and UI 2019-08-30 11:18:51 +02:00
Adrien Bourmault e230d65cd4
Update VERSIONS.LST 2019-08-29 15:00:29 +02:00
Adrien Bourmault d1bf646118
Somes changes on UI and update system 2019-08-29 12:54:43 +02:00
Adrien Bourmault 4f36d5904e
Update VERSIONS.LST 2019-08-29 11:15:07 +02:00
Adrien Bourmault 102b1d1e67
Add files via upload 2019-08-29 11:04:50 +02:00
Adrien Bourmault de31c9d79c
Update VERSIONS.LST 2019-08-28 16:47:02 +02:00
Adrien Bourmault 535583e010
Update changelog 2019-08-28 16:38:18 +02:00
Adrien Bourmault c880645949
Bug reporting bug correction (encrypt the token was the solution) 2019-08-28 16:24:02 +02:00
Adrien Bourmault 83a6e110f6
Correcting "token clear in repo" 2019-08-27 16:49:01 +02:00
Adrien Bourmault 624b78d9d1
Merge pull request #39 from neox95/v3.1
V3.1.4
2019-08-27 14:22:18 +02:00
Adrien Bourmault 1fe97b425a
Update VERSIONS.LST 2019-08-27 14:07:31 +02:00
Adrien Bourmault 6a7d8ea5fb
Correcting bug reporting bug ;) 2019-08-27 14:06:33 +02:00
Adrien Bourmault 5e616e5283
Update VERSIONS.LST 2019-08-27 13:30:16 +02:00
Adrien Bourmault 072f1a2510
Correction of a bug in bug reporting system 2019-08-27 13:24:12 +02:00
Adrien Bourmault a7a22be152
Update VERSIONS.LST 2019-08-27 09:37:49 +02:00
Adrien Bourmault 7aed2c6623
Update VERSIONS.LST 2019-08-27 09:37:15 +02:00
Adrien Bourmault b78d2842bf
Update VERSIONS.LST 2019-08-27 09:34:18 +02:00
Adrien Bourmault f44fd1add7
Release 3.1.4 2019-08-27 09:26:16 +02:00
Adrien Bourmault 9972359ac1
Update VERSIONS.LST 2019-08-26 16:58:08 +02:00
Adrien Bourmault b69e312cf7
Add files via upload 2019-08-26 16:54:03 +02:00
Adrien Bourmault 30e1b15dd1
Added temporization on update to prevent updating every launch 2019-08-26 16:50:51 +02:00
Adrien Bourmault 6d4104e6fa
Add files via upload 2019-08-26 13:46:22 +02:00
Adrien Bourmault 98cae9b951
Update VERSIONS.LST 2019-08-26 13:46:00 +02:00
Adrien Bourmault 1cce5184fd
Add files via upload 2019-08-26 13:45:33 +02:00
Adrien Bourmault bf508555da
Merge pull request #33 from neox95/v3.1
V3.1.3
2019-08-26 10:11:36 +02:00
Adrien Bourmault 9e57123850
Update VERSIONS.LST 2019-08-26 10:03:56 +02:00
Adrien Bourmault 685f7aab5a
Update VERSIONS.LST 2019-08-26 10:03:19 +02:00
Adrien Bourmault 43fca39314
Update VERSIONS.LST 2019-08-26 10:02:33 +02:00
Adrien Bourmault 3110872310
Added version.res 2019-08-26 10:00:46 +02:00
Adrien Bourmault 46b7eb8c26
Update VERSIONS.LST 2019-08-26 09:47:52 +02:00
Adrien Bourmault c7fb8d4c4b
Patching 3.1.3 2019-08-26 09:45:03 +02:00
Adrien Bourmault fe940585ac
Added version.res in the buildchain 2019-08-26 09:43:41 +02:00
Adrien Bourmault 2dee9b79cf
Update VERSIONS.LST 2019-08-23 16:57:18 +02:00
Adrien Bourmault e037bba76e
Add files via upload 2019-08-23 16:46:25 +02:00
Adrien Bourmault e7d164d355
Add files via upload 2019-08-23 16:44:58 +02:00
Adrien Bourmault 19684df1c1 Update issue templates 2019-08-23 15:22:27 +02:00
Adrien Bourmault c2503d411b Update issue templates 2019-08-23 15:15:35 +02:00
Adrien Bourmault d5620bdd30 Update issue templates 2019-08-23 15:14:40 +02:00
Adrien Bourmault 1f19344896
Merge pull request #19 from neox95/v3.1
Update VERSIONS.LST
2019-08-21 16:07:17 +02:00
Adrien Bourmault 085cb2f571
Update VERSIONS.LST 2019-08-21 16:07:00 +02:00
Adrien Bourmault e45af9d903
Merge pull request #18 from neox95/v3.1
Correction of some bugs with the image processing and adding some too…
2019-08-21 14:55:42 +02:00
Adrien Bourmault 4062d68b2b
Correction of some bugs with the image processing and adding some tools for images 2019-08-21 14:54:05 +02:00
Adrien Bourmault cb46844fec
Merge pull request #17 from neox95/v3.1
V3.1
2019-08-21 10:44:32 +02:00
Adrien Bourmault 1c38f1c8b4
Merge branch 'master' into v3.1 2019-08-21 10:44:22 +02:00
Adrien Bourmault a277295374
Create VERSIONS.LST 2019-08-21 10:43:58 +02:00
Adrien Bourmault 0897452d06
Delete VERSIONS.LST 2019-08-21 10:43:19 +02:00
Adrien Bourmault 20c0b44d7b
Delete CNIRevelator Documentation.docx 2019-08-21 10:42:58 +02:00
Adrien Bourmault d45a0a9e9c
Update VERSIONS.LST 2019-08-21 10:38:56 +02:00
Adrien Bourmault 17ad747e50
Release 3.1.2 2019-08-21 10:36:57 +02:00
Adrien Bourmault 086d98fa3d
Delete zoomOut50.png 2019-08-21 10:35:54 +02:00
Adrien Bourmault 840d70d9a3
Delete rotateRight1.png 2019-08-21 10:35:48 +02:00
Adrien Bourmault cff6c44c91
Delete logger.py 2019-08-21 10:35:40 +02:00
Adrien Bourmault f58e964e78
Delete ihm.py 2019-08-21 10:35:33 +02:00
Adrien Bourmault 31672ec6f6
Delete globs.py 2019-08-21 10:35:25 +02:00
Adrien Bourmault dfd0b9c988
Delete main.py 2019-08-21 10:34:53 +02:00
Adrien Bourmault 0b0661bfa9
Delete launcher.py 2019-08-21 10:34:52 +02:00
Adrien Bourmault 1483797828
Delete lang.py 2019-08-21 10:34:51 +02:00
Adrien Bourmault a59b9cfff1
Delete id-card.svg 2019-08-21 10:34:49 +02:00
Adrien Bourmault ff5c480929
Delete id-card.ico.png 2019-08-21 10:34:48 +02:00
Adrien Bourmault 20532650eb
Delete id-card.ico 2019-08-21 10:34:41 +02:00
Adrien Bourmault 2be7a7568e
Delete downloader.py 2019-08-21 10:34:39 +02:00
Adrien Bourmault 31a3518213
Delete critical.py 2019-08-21 10:34:38 +02:00
Adrien Bourmault 2bc2c9c13b
Delete background.svg 2019-08-21 10:34:37 +02:00
Adrien Bourmault a9b7056114
Delete background.png 2019-08-21 10:34:36 +02:00
Adrien Bourmault eabb676c28
Delete OCR.png 2019-08-21 10:34:34 +02:00
Adrien Bourmault e065642f8b
Delete zoomOut20.png 2019-08-21 10:34:33 +02:00
Adrien Bourmault a13ca281ba
Delete zoomOut.png 2019-08-21 10:34:32 +02:00
Adrien Bourmault f1dd2129ca
Delete zoomIn50.png 2019-08-21 10:34:31 +02:00
Adrien Bourmault 659d47f47f
Delete zoomIn20.png 2019-08-21 10:34:31 +02:00
Adrien Bourmault 942f6dd9da
Delete zoomIn.png 2019-08-21 10:34:30 +02:00
Adrien Bourmault bcf0fde819
Delete updater.py 2019-08-21 10:34:28 +02:00
Adrien Bourmault 14f98e8493
Delete rotateRight.png 2019-08-21 10:33:50 +02:00
Adrien Bourmault afed0fe6ec
Delete rotateLeft1.png 2019-08-21 10:33:46 +02:00
Adrien Bourmault d55146b532
Delete rotateLeft.png 2019-08-21 10:33:41 +02:00
Adrien Bourmault ea40cf5938
Delete pytesseract.py 2019-08-21 10:33:30 +02:00
Adrien Bourmault 99ce7d59f7
Delete mrz.py 2019-08-21 10:33:26 +02:00
Adrien Bourmault 5eb98d2004
Delete Invert.png 2019-08-21 10:32:35 +02:00
Adrien Bourmault 06d50121c7
Delete CNIRevelator.py 2019-08-21 10:32:26 +02:00
Adrien Bourmault 017329257e
Add files via upload 2019-08-21 10:31:53 +02:00
Adrien Bourmault 81313007b0
Releasing 3.1.2 2019-08-21 10:26:17 +02:00
Adrien Bourmault ad813c0b14
Update VERSIONS.LST 2019-08-20 19:14:15 +02:00
Adrien Bourmault ea93e4a7dd
Merge pull request #16 from neox95/v3.1
V3.1.2
2019-08-20 19:13:23 +02:00
Adrien Bourmault 45d8734f7d
Update VERSIONS.LST 2019-08-20 19:12:57 +02:00
Adrien Bourmault 9d7e866807
Update VERSIONS.LST 2019-08-20 19:08:40 +02:00
Adrien Bourmault fd7c68e4a1
Update VERSIONS.LST 2019-08-20 19:07:04 +02:00
Adrien Bourmault 26b2c7c564
Update VERSIONS.LST 2019-08-20 19:01:40 +02:00
Adrien Bourmault 4bf8fad661
Update VERSIONS.LST 2019-08-20 18:59:33 +02:00
Adrien Bourmault 16f1d00e35
Update VERSIONS.LST 2019-08-20 18:58:20 +02:00
Adrien Bourmault d399c4d7ca
Update VERSIONS.LST 2019-08-20 18:56:58 +02:00
Adrien Bourmault 1054884b51
Update VERSIONS.LST 2019-08-20 18:54:26 +02:00
Adrien Bourmault 5547305794
Update VERSIONS.LST 2019-08-20 18:50:09 +02:00
Adrien Bourmault 822b206280
Add files via upload 2019-08-20 18:41:33 +02:00
Adrien Bourmault 6d514b1ada
Add files via upload 2019-08-20 18:41:07 +02:00
Adrien Bourmault 2db1c28e24
Upgrade Tesseract to 5.0 2019-08-20 18:38:22 +02:00
Adrien Bourmault 6c480d49b9
Add files via upload 2019-08-20 15:43:00 +02:00
Adrien Bourmault 73f0c1b583
Merge pull request #15 from neox95/v3.1
Release 3.1.1
2019-08-20 10:31:02 +02:00
Adrien Bourmault 9423e316eb
Release 3.1.1 2019-08-20 10:30:30 +02:00
Adrien Bourmault 9bc808d785
Merge pull request #14 from neox95/v3.1
V3.1.1 release
2019-08-20 10:29:59 +02:00
Adrien Bourmault 49ee60e58a
Merge branch 'master' into v3.1 2019-08-20 10:29:48 +02:00
Adrien Bourmault f117fb8658
Testing 3.1.1 update system 2019-08-20 10:21:56 +02:00
Adrien Bourmault fcf8949c6b
Release 3.1.1 2019-08-20 10:19:32 +02:00
Adrien Bourmault dda773cd75
Correction of a bug in updater.py and preparing 3.1.1 2019-08-20 10:14:54 +02:00
Adrien Bourmault b0d4fbf2fc
Update VERSIONS.LST 2019-08-20 09:43:36 +02:00
Adrien Bourmault 73e06d37df
Update VERSIONS.LST 2019-08-20 08:52:12 +02:00
Adrien Bourmault ec7cd0e11d
Preparing update 3.1.0 2019-08-19 18:03:24 +02:00
Adrien Bourmault 6b6589b772
Preparing update 3.1.0 2019-08-19 17:56:23 +02:00
Adrien Bourmault b9a24fca1e
Bug with open file 2019-08-12 18:11:56 +02:00
Adrien Bourmault 67b5c903d2
hotfix on the language system 2019-08-12 17:29:22 +02:00
Adrien Bourmault c34a88abc5
Minor correction 2019-08-12 17:15:51 +02:00
Adrien Bourmault 8e389ddf25
Minor correction 2019-08-12 17:14:41 +02:00
Adrien Bourmault 2df174b234
New language system, some changes on the update system 2019-08-12 17:07:37 +02:00
Adrien Bourmault 1548fae87b
Merge pull request #13 from neox95/v3.0
V3.0.8 release and now working on 3.1
2019-08-12 00:00:28 +02:00
Adrien Bourmault 89d95de3d8 Some cosmetics changes 2019-08-11 23:57:30 +02:00
Adrien Bourmault 79b0a21e0a Release 3.0.8 2019-08-11 21:54:28 +02:00
Adrien Bourmault b0fc8a05e0
Merge pull request #12 from neox95/v3.0
V3.0.6 release
2019-08-07 16:52:47 +02:00
Adrien Bourmault 07dd43404f
Merge pull request #11 from neox95/v3.0
V3.0.6
2019-08-07 15:31:17 +02:00
Adrien Bourmault d93b4fe893
Working on image display 2019-08-07 15:27:44 +02:00
Adrien Bourmault b77283a3ae
Add files via upload 2019-08-07 15:26:27 +02:00
Adrien Bourmault 34922d6ed5
Merge pull request #10 from neox95/v3.0
V3.0.5 release
2019-08-06 11:34:53 +02:00
Adrien Bourmault f8f9ffb9a8
Merge pull request #9 from neox95/v3.0
V3.0.4 release
2019-08-06 10:34:35 +02:00
Adrien Bourmault 2dce322a34
Merge pull request #8 from neox95/v3.0
Update VERSIONS.LST
2019-08-06 10:03:15 +02:00
Adrien Bourmault 6231bef794
Merge pull request #7 from neox95/v3.0
V3.0.4 release
2019-08-06 10:02:16 +02:00
Adrien Bourmault 9438ee3d9e
Merge pull request #6 from neox95/v3.0
Stopping all updates
2019-08-06 08:55:00 +02:00
Adrien Bourmault 5f0e5c7e58
Merge pull request #5 from neox95/v3.0
V3.0.3 release
2019-08-06 08:42:13 +02:00
Adrien Bourmault 30a558ac3a
Merge pull request #4 from neox95/v3.0
V3.0.3 release
2019-08-05 17:12:35 +02:00
Adrien Bourmault cd6f590d97
Merge pull request #3 from neox95/v3.0
V3.0.2 release
2019-08-05 16:44:42 +02:00
20 changed files with 2900 additions and 1033 deletions

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

Binary file not shown.

View File

@ -1,5 +1,5 @@
# CNIRevelator
| ![FSF Logo](https://www.os-k.eu/GPLLOGO.PNG) | This program is free software, released under the terms of the [GNU GPL](COPYING) version 3 or later as published by the Free Software Foundation |
| ![FSF Logo](https://www.os-k.eu/GPLLOGO.png) | This program is free software, released under the terms of the [GNU GPL](COPYING) version 3 or later as published by the Free Software Foundation |
|----------------------------------------------|----------------------------------------------------------------------|
### Analyzer for MRZ Codes on identity cards, passports and others for Windows.

View File

@ -1,2 +1,2 @@
# ver|url|checksum, and | as separator, one version per ||
3.0.4|https://github.com/neox95/CNIRevelator/releases/download/3.0.4/CNIRevelator.zip|d03a18b35dfbb20d90664dc2c0f990adc5522e46||3.0.5|https://github.com/neox95/CNIRevelator/releases/download/3.0.5/CNIRevelator.zip|8b52290fb0910d8b9c4ec43293b08017e0031ca2||3.0.6|https://github.com/neox95/CNIRevelator/releases/download/3.0.6/CNIRevelator.zip|4bb4606dc9310d7b34b1fb38f9a0c2daf9518dc5||3.0.7|https://github.com/neox95/CNIRevelator/releases/download/3.0.7/CNIRevelator.zip|9aea1627c0b75610225a02458d5705563ca0d6af||
# ver|url|checksum, and | as separator, one version per ||
3.1.6|https://github.com/neox95/CNIRevelator/releases/download/3.1.6/CNIRevelator.zip|8977e1f335d08419be68133fe229ead453279b7f||

View File

@ -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

View File

@ -1,3 +1,4 @@
# -*- coding: utf8 -*-
"""
********************************************************************************
* CNIRevelator *
@ -23,22 +24,26 @@
* along with CNIRevelator. If not, see <https:*www.gnu.org/licenses/>. *
********************************************************************************
"""
import sys
# Import critical files
import os
import subprocess
import threading
import traceback
import psutil
import launcher # launcher.py"
import updater # updater.py
import globs # globs.py
import pytesseract # pytesseract.py
import lang # lang.py
import logger # logger.py
import globs # globs.py
import critical # critical.py
# Import all other files and crash if necessary
try:
from main import * # main.py
import launcher # launcher.py"
import updater # updater.py
import pytesseract # pytesseract.py
import ihm # ihm.py
from tkinter.messagebox import *
from tkinter import *
except:
critical.crashCNIR()
# Global handler
logfile = logger.logCur
@ -50,8 +55,8 @@ def main():
mainw = mainWindow()
try:
os.environ['PATH'] = globs.CNIRFolder + '\\Tesseract-OCR4\\'
os.environ['TESSDATA_PREFIX'] = globs.CNIRFolder + '\\Tesseract-OCR4\\tessdata'
os.environ['PATH'] = globs.CNIRFolder + '\\Tesseract-OCR5\\'
os.environ['TESSDATA_PREFIX'] = globs.CNIRFolder + '\\Tesseract-OCR5\\tessdata'
tesser_version = pytesseract.get_tesseract_version()
except Exception as e:
logfile.printerr('ERROR WITH TESSERACT MODULE ' + str(e))
@ -59,15 +64,17 @@ 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"]))
# changelog
if globs.CNIRNewVersion:
showinfo('Changelog : résumé de mise à jour', ('Version du logiciel : CNIRevelator ' + globs.verstring_full + '\n\n' + globs.changelog), parent=mainw)
mainw.after_idle(mainw.showChangeLog)
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 ! ***')
@ -75,30 +82,46 @@ def main():
## BOOTSTRAP OF CNIREVELATOR
try:
launcherThread = threading.Thread(target=updater.umain, daemon=False)
launcher.lmain(launcherThread)
except Exception:
updater.exitProcess(1)
if updater.UPDATE_IS_MADE:
# Launch app !
args = updater.UPATH + '\\CNIRevelator.exe ' + globs.CNIRFolder
cd = updater.UPATH
for i in range(0,3):
try:
updater.spawnProcess(args, cd)
except:
time.sleep(3)
continue
break
updater.exitProcess(0)
logfile.printdbg('CNIRevelator log file version {}'.format(globs.verstring_full))
# Here we go !
try:
main()
except Exception as e:
traceback.print_exc(file=sys.stdout)
try:
# LANGUAGE
lang.readLang()
except:
critical.crashCNIR()
updater.exitProcess(1)
from main import * # main.py
# GO
try:
launcherThread = threading.Thread(target=updater.umain, daemon=False)
launcher.lmain(launcherThread)
except Exception:
critical.crashCNIR(False)
if updater.UPDATE_IS_MADE:
# Launch app !
args = updater.UPATH + '\\CNIRevelator.exe' + " DELETE " + globs.CNIRFolder
cd = updater.UPATH
for i in range(0,3):
try:
updater.spawnProcess(args, cd)
except:
time.sleep(3)
continue
break
updater.exitProcess(0)
# Here we go !
try:
main()
except Exception as e:
critical.crashCNIR()
updater.exitProcess(1)
except:
critical.crashCNIR()
updater.exitProcess(0)

92
src/critical.py Normal file
View File

@ -0,0 +1,92 @@
# -*- coding: utf8 -*-
"""
********************************************************************************
* CNIRevelator *
* *
* Desc: Critical 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 <https:*www.gnu.org/licenses/>. *
********************************************************************************
"""
from tkinter.messagebox import *
from importlib import reload
from tkinter import *
import webbrowser
import traceback
import psutil
import os
import lang # lang.py
import logger # logger.py
import globs # globs.py
import github # github.py
def crashCNIR(shutdown=True, option="", isVoluntary=False):
"""
very last solution
"""
try:
root = Tk()
root.withdraw()
logfile = logger.logCur
logfile.printerr("FATAL ERROR : see traceback below.\n{}".format(traceback.format_exc()))
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 ?"])
if res == "yes":
# read the log
data = "No log."
try:
with open(globs.CNIRMainLog, 'r') as file:
data = file.read()
except:
logfile.printerr("Can't read the log file.")
# send it
success = github.reportBug(traceback.format_exc(), data, isVoluntary)
if not success:
logfile.printerr("Can't send to Github.")
res = askquestion(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Would you like to open the log file ?"])
if res == "yes":
webbrowser.open_new(globs.CNIRErrLog)
else:
showinfo(lang.all[globs.CNIRlang]["CNIRevelator Fatal Eror"], lang.all[globs.CNIRlang]["Bug reported successfully. Thanks."])
root.destroy()
# Quit ?
if not shutdown:
return
# Quit totally without remain in memory
for process in psutil.process_iter():
if process.pid == os.getpid():
process.terminate()
sys.exit(arg)
except:
traceback.print_exc()

View File

@ -1,3 +1,4 @@
# -*- coding: utf8 -*-
"""
********************************************************************************
* CNIRevelator *
@ -32,9 +33,11 @@ from Crypto.Cipher import AES
from requests import Session
from time import time
import critical # critical.py
import logger # logger.py
import globs # globs.py
import ihm # ihm.py
import lang # lang.py
class AESCipher(object):
@ -78,10 +81,11 @@ class newcredentials:
self.trying += 1
try:
sessionAnswer = session.get('https://www.google.com')
sessionAnswer = session.get('http://www.google.com')
except Exception as e:
logfile.printdbg('Network Error : ' + str(e))
sessionAnswer = ''
self.login = "nointernet"
return
logfile.printdbg("Session Answer : " + str(sessionAnswer))
@ -91,11 +95,6 @@ class newcredentials:
self.valid = True
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:
logfile.printerr('Invalid credentials : access denied, a maximum of 3 trials have been raised !')
return
@ -184,8 +183,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 +200,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

189
src/github.py Normal file
View File

@ -0,0 +1,189 @@
# -*- 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 <https:*www.gnu.org/licenses/>. *
********************************************************************************
"""
from requests.auth import HTTPProxyAuth
from pypac import PACSession
from Crypto import Random
from Crypto.Cipher import AES
from requests import Session
import json, hashlib, base64
import logger # logger.py
import globs # globs.py
credentials = False
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
if not credentials:
logfile.printerr("No credentials")
return False
session = credentials.sessionHandler
if not isVoluntary:
payload = {
'title':"CNIRevelator App Bug Report",
'body': (
"**An error has been reported by a CNIRevelator instance.**\n\n"
"**Global informations:**\n"
"verType = {}\n"
"version= {}\n"
"verstring_full = {}\n"
"CNIRTesserHash = {}\n"
"CNIRGitToken = {}\n"
"CNIRName = {}\n"
"CNIRCryptoKey = {}\n"
"CNIRlang = {}\n"
"CNIRVerStock = {}\n"
"CNIREnv = {}\n"
"CNIRBetaURL = {}\n"
"CNIRDefaultURL = {}\n"
"CNIRNewVersion = {}\n"
"CNIROpenFile = {}\n"
"debug = {}\n"
"\n\n"
"**Full reason of the crash:**\n{}\n\n"
"**Full log:** {}"
).format(
globs.verType,
globs.version,
globs.verstring_full,
globs.CNIRTesserHash,
globs.CNIRGitToken,
globs.CNIRName,
globs.CNIRCryptoKey,
globs.CNIRlang,
globs.CNIRVerStock,
globs.CNIREnv,
globs.CNIRBetaURL,
globs.CNIRDefaultURL,
globs.CNIRNewVersion,
globs.CNIROpenFile,
globs.debug,
reason,
log
),
"assignees":["neox95"], "labels":["bug", "AUTO"]
}
else:
payload = {
'title':"CNIRevelator User Bug Report",
'body': (
"**An error has been reported by a CNIRevelator user.**\n\n"
"**Global informations:**\n"
"verType = {}\n"
"version= {}\n"
"verstring_full = {}\n"
"CNIRTesserHash = {}\n"
"CNIRGitToken = {}\n"
"CNIRName = {}\n"
"CNIRCryptoKey = {}\n"
"CNIRlang = {}\n"
"CNIRVerStock = {}\n"
"CNIREnv = {}\n"
"CNIRBetaURL = {}\n"
"CNIRDefaultURL = {}\n"
"CNIRNewVersion = {}\n"
"CNIROpenFile = {}\n"
"debug = {}\n"
"\n\n"
"**Possible reason:**\n{}\n\n"
"**Full log:** {}"
).format(
globs.verType,
globs.version,
globs.verstring_full,
globs.CNIRTesserHash,
globs.CNIRGitToken,
globs.CNIRName,
globs.CNIRCryptoKey,
globs.CNIRlang,
globs.CNIRVerStock,
globs.CNIREnv,
globs.CNIRBetaURL,
globs.CNIRDefaultURL,
globs.CNIRNewVersion,
globs.CNIROpenFile,
globs.debug,
reason,
log
),
"assignees":["neox95"], "labels":["bug", "AUTO"]
}
handler = session.post('https://api.github.com/repos/neox95/cnirevelator/issues', headers={'Authorization': 'token %s' % decryptToken(globs.CNIRGitToken)}, data=json.dumps(payload))
logfile.printdbg("Issue is " + handler.reason)
if handler.reason == "Created":
return True
else:
return False
def encryptToken(token):
AESObj = AESCipher(globs.CNIRCryptoKey)
return AESObj.encrypt(token)
def decryptToken(token):
AESObj = AESCipher(globs.CNIRCryptoKey)
return AESObj.decrypt(token)

View File

@ -1,3 +1,4 @@
# -*- coding: utf8 -*-
"""
********************************************************************************
* CNIRevelator *
@ -25,33 +26,33 @@
import os
# CNIRevelator version
verType = "final release (hotfix)"
version = [3, 0, 8]
verType = "stable release"
version = [3, 1, 6]
verstring_full = "{}.{}.{} {}".format(version[0], version[1], version[2], verType)
verstring = "{}.{}".format(version[0], version[1])
debug = True
changelog = "Version 3.0.8 finale\nCorrectif : bug du système de mise-à-jour'\n\n" + \
"Version 3.0.6 \nMise-à-jour mineure avec les corrections suivantes :\n- Changement de l'apparence du launcher de l'application\n- Améliorations de l'interface, notamment de la stabilité\n- Ajout de la signature numérique de l'exécutable\n\n" + \
"Version 3.0.7 finale\nMise-à-jour majeure avec les corrections suivantes :\n- Refonte de l'interface utilisateur\n- Fonction OCR intégrée à l'application avec support des TIFF et JPEG\n- Corrections d'erreurs sur le traitement des VISA de type A et B, ainsi que les titres de séjour\n\n" + \
"Version 3.0.6 \nMise-à-jour mineure avec les corrections suivantes :\n- Changement de l'apparence du launcher de l'application\n- Améliorations de l'interface, notamment de la stabilité\n- Ajout de la signature numérique de l'exécutable\n\n" + \
"Version 3.0.5 \nMise-à-jour mineure avec les corrections suivantes :\n- Changement de l'icône de l'exécutable afin de refléter le changement de version majeur accompli en 3.0\n\n" + \
"Version 3.0.4 \nMise-à-jour mineure avec les corrections suivantes :\n- Correction d'un bug affectant le système de mise-à-jour\n\n" + \
"Version 3.0.3 \nMise-à-jour mineure avec les corrections suivantes :\n- Correction d'un bug affectant le changelog\n- Correction d'une erreur avec la touche Suppr Arrière et Suppr causant une perte de données\n\n" + \
"Version 3.0.2 \nMise-à-jour mineure avec les corrections suivantes :\n- Changement d'icône de l'exécutable\n- Correction d'un bug affectant le logging\n- Correction d'un bug affectant la détection de documents\n- Et autres modifications mineures\n\n" + \
"Version 3.0.1 \nMise-à-jour majeure avec les corrections suivantes :\n- Renouvellement de la signature numérique de l'exécutable\n- Amélioration de présentation du log en cas d'erreur\n- Refonte totale du code source et désobfuscation\n- Téléchargements en HTTPS fiables avec somme de contrôle\n- Nouveaux terminaux d'entrées : un rapide (731) et un complet\n- Détection des documents améliorée, possibilité de choix plus fin\nEt les regressions suivantes :\n- Suppression temporaire de la fonction de lecture OCR. Retour planifié pour une prochaine version"
CNIRTesserHash = '5b58db27f7bc08c58a2cb33d01533b034b067cf8'
CNIRFolder = os.getcwd()
CNIRTesserHash = "947224361ffab8c01f05c9394b44b1bd7c8c3d4d"
CNIRGitToken = "mJHKXqnazO/xZ9Fs18SDMqcGJ15A27OlZyd27cDe5dhHKklO2YShdWwUgEDUZQI02kpgYaLceMidTK37ZqakW+VYgPPuh0e9Ry2IH0KHc3o="
CNIRFolder = os.path.dirname(os.path.realpath(__file__))
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\\'
CNIRTesser = CNIRFolder + '\\Tesseract-OCR5\\'
CNIRErrLog = CNIRFolder + '\\logs\\error.log'
CNIRMainLog = CNIRFolder + '\\logs\\main.log'
CNIRUrlConfig = CNIRFolder + '\\config\\urlconf.ig'
CNIRLastUpdate = CNIRFolder + '\\config\\lastupdate.ig'
CNIRVerStock = CNIRFolder + '\\downloads\\versions.lst'
CNIREnv = CNIRFolder + '\\Data\\'
CNIRBetaURL = "https://raw.githubusercontent.com/neox95/CNIRevelator/v3.1/VERSIONS.LST"
CNIRDefaultURL = "https://raw.githubusercontent.com/neox95/CNIRevelator/master/VERSIONS.LST"
CNIRNewVersion = False
CNIROpenFile = False
debug = True

View File

@ -1,3 +1,4 @@
# -*- coding: utf8 -*-
"""
********************************************************************************
* CNIRevelator *
@ -23,29 +24,36 @@
********************************************************************************
"""
from tkinter import *
from tkinter.messagebox import *
from tkinter import *
from tkinter import filedialog
from tkinter import ttk
import cv2
import PIL.Image, PIL.ImageTk
import traceback
import cv2
import critical # critical.py
import logger # logger.py
import globs # globs.py
import lang # lang.py
import updater # updater.py
import critical # critical.py
controlKeys = ["Escape", "Right", "Left", "Up", "Down", "Home", "End", "BackSpace", "Delete", "Inser", "Shift_L", "Shift_R", "Control_R", "Control_L"]
class DocumentAsk(Toplevel):
def __init__(self, parent, choices):
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()
self.choice = 0
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.resizable(width=False, height=False)
@ -62,25 +70,26 @@ class DocumentAsk(Toplevel):
y = hs / 2 - h / 2
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
def register0(self):
self.choice = 0
def register1(self):
self.choice = 1
def createRegister(self, i):
def register():
self.choice = i
return register
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,33 +111,34 @@ 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')
Label(self, text='IPN : ').pack()
self.entry_login = Entry(self)
self.title(lang.all[globs.CNIRlang]["Connection"])
self["background"] = "white"
Label(self, text='IPN : ', bg="white").pack(fill=Y)
self.entry_login = ttk.Entry(self)
self.entry_login.insert(0, '')
self.entry_login.pack()
Label(self, text='Mot de passe : ').pack()
self.entry_pass = Entry(self, show='*')
Label(self, text='{} : '.format(lang.all[globs.CNIRlang]["Password"]), bg="white").pack(fill=Y)
self.entry_pass = ttk.Entry(self, show='*')
self.entry_pass.insert(0, '')
self.entry_pass.pack()
Button(self, text='Connexion', command=(self.connecti)).pack()
self.entry_pass.pack(fill=Y)
ttk.Button(self, text=lang.all[globs.CNIRlang]["Connection"], command=(self.connecti)).pack(fill=Y, pady=10)
self.update()
self.resizable(width=False, height=False)
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
w = hs / 10
h = ws / 18
self.update()
w = self.winfo_reqwidth() + 5
h = self.winfo_reqheight()
if getattr(sys, 'frozen', False):
self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
@ -143,6 +153,131 @@ class LoginDialog(Toplevel):
self.key = self.entry_pass.get().strip()
self.destroy()
class ChangelogDialog(Toplevel):
def __init__(self, parent, text):
super().__init__(parent)
self.title(lang.all[globs.CNIRlang]["Show Changelog"])
self["background"] = "white"
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.text = Text(self, wrap='word', width=55, height=15, borderwidth=0, font="TkDefaultFont", bg="white")
self.text.grid(column=0, row=0, sticky='EWNS', padx=5, pady=5)
ttk.Button(self, text="OK", command=(self.oki)).grid(column=0, row=1, pady=5)
self.scrollb = ttk.Scrollbar(self, command=(self.text.yview))
self.scrollb.grid(column=1, row=0, sticky='EWNS', padx=5, pady=5)
self.text['yscrollcommand'] = self.scrollb.set
self.text.insert('end', text)
self.text['state'] = 'disabled'
self.update()
self.resizable(width=False, height=False)
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
w = self.winfo_reqwidth() + 5
h = self.winfo_reqheight()
if getattr(sys, 'frozen', False):
self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
self.iconbitmap('id-card.ico')
x = ws / 2 - w / 2
y = hs / 2 - h / 2
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
self.bind("<Return>", self.oki)
def oki(self, event=None):
self.destroy()
class langDialog(Toplevel):
def __init__(self, parent, currentLang):
super().__init__(parent)
self.title(lang.all[globs.CNIRlang]["Language"])
Label(self, text=lang.all[globs.CNIRlang]["Please choose your language : "]).pack(fill=Y)
vals = [i for i in lang.all]
for i in range(len(lang.all)):
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)
self.update()
self.resizable(width=False, height=False)
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
w = self.winfo_reqwidth() + 5
h = self.winfo_reqheight()
if getattr(sys, 'frozen', False):
self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
self.iconbitmap('id-card.ico')
x = ws / 2 - w / 2
y = hs / 2 - h / 2
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
self.bind("<Return>", self.oki)
def oki(self, event=None):
self.destroy()
def createRegister(self, i):
def register():
lang.updateLang([j for j in lang.all][i])
return register
class updateSetDialog(Toplevel):
def __init__(self, parent, currentChannel):
super().__init__(parent)
self.title(lang.all[globs.CNIRlang]["Update options"])
Label(self, text=lang.all[globs.CNIRlang]["Please choose your update channel : "]).pack(fill=Y)
self.vals = ["Stable", "Beta"]
vals = self.vals
for i in range(len(vals)):
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)
self.update()
self.resizable(width=False, height=False)
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
w = self.winfo_reqwidth() + 5
h = self.winfo_reqheight()
if getattr(sys, 'frozen', False):
self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
self.iconbitmap('id-card.ico')
x = ws / 2 - w / 2
y = hs / 2 - h / 2
self.geometry('%dx%d+%d+%d' % (w, h, x, y))
self.bind("<Return>", self.oki)
def oki(self, event=None):
self.destroy()
def createRegister(self, i):
def register():
updater.setUpdateChannel(self.vals[i])
return register
class LauncherWindow(Tk):
def __init__(self):
@ -150,6 +285,12 @@ class LauncherWindow(Tk):
Tk.__init__(self)
self.resizable(width=False, height=False)
# icon
if getattr(sys, 'frozen', False):
self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
self.iconbitmap('id-card.ico')
# Setting up the geometry
ws = self.winfo_screenwidth()
hs = self.winfo_screenheight()
@ -165,8 +306,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))
@ -185,7 +324,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()
@ -198,15 +337,9 @@ class LauncherWindow(Tk):
self.update()
self.progressBar.grid(row=1, sticky='S')
if getattr(sys, 'frozen', False):
self.iconbitmap(sys._MEIPASS + '\\id-card.ico\\id-card.ico')
else:
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.update()
def printmsg(self, msg):
@ -230,7 +363,23 @@ class ResizeableCanvas(Canvas):
self.height = event.height
# rescale all the objects tagged with the "all" tag
self.scale("all",0,0,wscale,hscale)
class StatusBar(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.label = Label(self, bd=1, relief=SUNKEN, anchor=W)
self.label.pack(fill=X)
def set(self, text):
self.label.config(text="Document : " + text.lower())
self.label.update_idletasks()
def clear(self):
self.label.config(text="")
self.label.update_idletasks()
## Global Handler
launcherWindowCur = LauncherWindow()
# test ?

1513
src/lang.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
# -*- coding: utf8 -*-
"""
********************************************************************************
* CNIRevelator *
@ -26,12 +27,13 @@
import sys
import os
import threading
import traceback
import critical # critical.py
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 +46,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

@ -1,3 +1,4 @@
# -*- coding: utf8 -*-
"""
********************************************************************************
* CNIRevelator *
@ -26,6 +27,7 @@
import logging
import os
import critical # critical.py
import globs # globs.py
## The logging class

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,3 +1,4 @@
# -*- coding: utf8 -*-
"""
********************************************************************************
* CNIRevelator *
@ -23,7 +24,7 @@
* along with CNIRevelator. If not, see <https:*www.gnu.org/licenses/>. *
********************************************************************************
"""
import logger # logger.pu
try:
import Image
@ -247,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
"""
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)
else:
args = [
@ -316,7 +317,7 @@ def main():
sys.stderr.write('Usage: python pytesseract.py [-l lang] input_file\n')
exit(2)
try:
print(image_to_string((Image.open(filename)), lang=lang))
logfile.printdbg(image_to_string((Image.open(filename)), lang=lang))
except IOError:
sys.stderr.write('ERROR: Could not open file "%s"\n' % filename)
exit(1)

View File

@ -1,3 +1,4 @@
# -*- coding: utf8 -*-
"""
********************************************************************************
* CNIRevelator *
@ -24,7 +25,9 @@
"""
from win32com.client import Dispatch
import traceback
from tkinter.messagebox import *
from tkinter import *
import pythoncom
import sys
import time
import os
@ -33,11 +36,15 @@ import zipfile
import hashlib
import subprocess
import psutil
import datetime
import critical # critical.py
import github # github.py
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 = ' '
@ -80,52 +87,45 @@ def exitProcess(arg):
if process.pid == os.getpid():
process.terminate()
sys.exit(arg)
def runPowershell(scriptblock, cwd=os.getcwd()):
def setUpdateChannel(choice):
"""
Executes a powershell command
Sets the new update channel and forces new update at next launch
"""
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"):
if choice == "Beta":
with open(globs.CNIRUrlConfig, 'w') as (configFile):
configFile.write("{}\n0\n0".format(globs.CNIRBetaURL))
# Force new update
try:
os.remove(globs.CNIRLastUpdate)
except:
pass
elif choice == "Stable":
with open(globs.CNIRUrlConfig, 'w') as (configFile):
configFile.write("{}\n0\n0".format(globs.CNIRDefaultURL))
# Force new update
try:
os.remove(globs.CNIRLastUpdate)
except:
pass
def getUpdateChannel():
"""
Returns the json data of all installed certificates
Returns the current update channel
"""
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)
with open(globs.CNIRUrlConfig, 'r') as (configFile):
url = configFile.read()
if not "master" in url:
return "Beta"
else:
return "Stable"
def getLatestVersion(credentials):
"""
Returns the latest version of the software
"""
finalver, finalurl, finalchecksum = [None]*3
# Global Handlers
logfile = logger.logCur
@ -155,7 +155,7 @@ def getLatestVersion(credentials):
except:
pass
with open(globs.CNIRUrlConfig, 'w') as (configFile):
configFile.write("https://raw.githubusercontent.com/neox95/CNIRevelator/master/VERSIONS.LST\n0\n0")
configFile.write("{}\n0\n0".format(globs.CNIRDefaultURL))
# Getting the list of versions of the software
logfile.printdbg('Retrieving the software versions')
@ -188,29 +188,52 @@ def getLatestVersion(credentials):
else:
finalurl = url
finalchecksum = None
return (finalver, finalurl, finalchecksum)
# XXX Warning : when tesseracturl is not found, it seems to hang and freeze
def tessInstall(PATH, credentials):
# Global Handlers
logfile = logger.logCur
# Verifying that Tesseract is installed
if not os.path.exists(PATH + '\\Tesseract-OCR4\\'):
if not os.path.exists(PATH + '\\Tesseract-OCR5\\'):
finalver, finalurl, finalchecksum = getLatestVersion(credentials)
tesseracturl = finalurl.replace("CNIRevelator.zip", "tesseract_4.zip")
# WE ASSUME THAT THE MAIN FILE IS CNIRevelator.zip AND THAT THE TESSERACT PACKAGE IS tesseract_4.zip
if finalurl == None:
logfile.printerr('Unable to get the Tesseract url')
return False
tesseracturl = finalurl.replace("CNIRevelator.zip", "tesseract_5.zip")
# WE ASSUME THAT THE MAIN FILE IS CNIRevelator.zip AND THAT THE TESSERACT PACKAGE IS tesseract_5.zip
logfile.printdbg('Preparing download of Tesseract OCR 4...')
getTesseract = downloader.newdownload(credentials, tesseracturl, PATH + '\\downloads\\TsrtPackage.zip', "Tesseract 4 OCR Module").download()
getTesseract = downloader.newdownload(credentials, tesseracturl, PATH + '\\downloads\\TsrtPackage.zip', "Tesseract 5 OCR Module").download()
try:
# CHECKSUM
BUF_SIZE = 65536 # lets read stuff in 64kb chunks!
sha1 = hashlib.sha1()
with open(globs.CNIRFolder + '\\downloads\\TsrtPackage.zip', 'rb') as f:
while True:
data = f.read(BUF_SIZE)
if not data:
break
sha1.update(data)
check = sha1.hexdigest()
logfile.printdbg("SHA1: {0}".format(check))
if not check == globs.CNIRTesserHash:
logfile.printerr("Checksum error")
return False
# 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()
@ -243,7 +266,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!
@ -268,7 +291,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')
@ -280,7 +303,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()
@ -291,9 +314,16 @@ def batch(credentials):
logfile.printdbg('Extracted :' + UPATH + '\\CNIRevelator.exe')
# Make a shortcut
createShortcut("CNIRevelator.lnk", UPATH + '\\CNIRevelator.exe', UPATH)
# hide main window
pythoncom.CoInitialize()
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:
@ -301,7 +331,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
@ -311,77 +341,83 @@ def umain():
# Global Handlers
logfile = logger.logCur
# Cleaner for the old version if detected
if len(sys.argv) > 2 and str(sys.argv[1]) == "DELETE":
globs.CNIRNewVersion = True
launcherWindow.printmsg(lang.all[globs.CNIRlang]["Deleting old version"])
logfile.printdbg("Old install detected : {}".format(sys.argv[2]))
while os.path.exists(str(sys.argv[2])):
try:
shutil.rmtree(str(sys.argv[2]))
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[2]))
break
except Exception as e:
logfile.printerr(str(e))
launcherWindow.printmsg('Fail :{}'.format(e))
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
logfile.printdbg("Command line received : {}".format(sys.argv))
credentials = downloader.newcredentials()
if not credentials.valid:
logfile.printerr("Credentials Error. No effective update !")
launcherWindow.printmsg('Credentials Error. No effective update !')
if credentials.login == "nointernet":
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)
launcherWindow.exit()
return 0
github.credentials = credentials
# Cleaner for the old version if detected
if len(sys.argv) > 2:
globs.CNIRNewVersion = True
launcherWindow.printmsg('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]))
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()
os.remove(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...')
# Check if update is needed
currentDate = datetime.datetime.now()
if os.path.isfile(globs.CNIRLastUpdate):
with open(globs.CNIRLastUpdate, 'r') as (configFile):
try:
# Reading it
lastUpdate = datetime.datetime.strptime(configFile.read(),"%d/%m/%Y")
except Exception as e:
critical.crashCNIR(False)
time.sleep(3)
launcherWindow.exit()
return 1
else:
lastUpdate = datetime.datetime(1970,1,1)
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()
return 0
# Update batch
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()))
critical.crashCNIR(False)
launcherWindow.printmsg('ERROR : ' + str(e))
time.sleep(3)
launcherWindow.exit()
@ -390,20 +426,36 @@ def umain():
if success:
logfile.printdbg("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:
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
if UPDATE_IS_MADE:
launcherWindow.exit()
return 0
except:
logfile.printerr("A FATAL ERROR OCCURED : " + str(traceback.format_exc()))
critical.crashCNIR(False)
launcherWindow.exit()
sys.exit(2)
return 2
try:
@ -411,7 +463,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()))
critical.crashCNIR(False)
launcherWindow.printmsg('ERROR : ' + str(e))
time.sleep(3)
launcherWindow.exit()
@ -419,18 +471,17 @@ 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()))
critical.crashCNIR(False)
launcherWindow.exit()
sys.exit(2)
return 2
time.sleep(2)

43
src/version.res Normal file
View File

@ -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, 6, 0),
prodvers=(3, 1, 6, 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.6'),
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.1'),
StringStruct(u'ProductVersion', u'3.1.6')])
]),
VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
]
)