mirror of
https://gitlab.os-k.eu/neox/CNIRevelator.git
synced 2023-08-25 14:03:10 +02:00
commit
bf508555da
Binary file not shown.
@ -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||
|
||||
3.1.3|https://github.com/neox95/CNIRevelator/releases/download/3.1.3e/CNIRevelator.zip|f42bb2cc8e72aa21caae4ea058ca1603e4153f48||
|
||||
|
4
make.bat
4
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
|
||||
|
@ -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 ?
|
||||
|
49
src/github.py
Normal file
49
src/github.py
Normal file
@ -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 <https:*www.gnu.org/licenses/>. *
|
||||
********************************************************************************
|
||||
"""
|
||||
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
|
||||
|
||||
|
@ -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])
|
||||
|
||||
|
@ -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))
|
||||
|
26
src/lang.py
26
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" + \
|
||||
|
35
src/main.py
35
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('<Key>', self.entryValidation)
|
||||
self.bind('<Key>', self.entryValidation)
|
||||
self.termtext.bind('<<Paste>>', self.pasteValidation)
|
||||
self.speed731text.bind('<Control_R>', self.speedValidation)
|
||||
self.imageViewer.ZONE.bind("<Button-1>", 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'),
|
||||
|
30
src/mrz.py
30
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]))
|
||||
|
@ -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:
|
||||
@ -326,6 +326,8 @@ def umain():
|
||||
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":
|
||||
globs.CNIRNewVersion = True
|
||||
|
43
src/version.res
Normal file
43
src/version.res
Normal 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, 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])])
|
||||
]
|
||||
)
|
Loading…
Reference in New Issue
Block a user