Compare commits
83 Commits
Author | SHA1 | Date | |
---|---|---|---|
c18b49149f | |||
7016c2e665 | |||
72d228de52 | |||
c31868d320 | |||
8a42245e4f | |||
655d61ea84 | |||
b9561ef60f | |||
962977774b | |||
0d94358f10 | |||
461d969f92 | |||
ff1a88c85b | |||
3e35e6fb05 | |||
48465446ec | |||
971bf846ab | |||
d879cf389d | |||
8138ebd95c | |||
483d7e2f6f | |||
e7f78e6e39 | |||
622ad63e0a | |||
a93c05bcc3 | |||
029f0c1396 | |||
e19a9b5820 | |||
7513a2d2fb | |||
dcb4caacc6 | |||
bb7d96e5e0 | |||
32300d81e4 | |||
cf625f5398 | |||
5cf50a04dd | |||
ad2c7de563 | |||
9ab362fd29 | |||
5d76b1f584 | |||
a1beec5cd1 | |||
f3f86c43a6 | |||
1dffdbeecd | |||
a500e22678 | |||
3dbb48d7fc | |||
d651a4973a | |||
0ce5ed334c | |||
d5c4ee5997 | |||
56ea8c83bc | |||
ad748edc81 | |||
831097aa75 | |||
07ec96d33a | |||
66ae8f4196 | |||
bf1f125da1 | |||
da302a3cd5 | |||
5db8255843 | |||
6333ce531d | |||
7585d09f41 | |||
bc0ccd1c93 | |||
bf143c0021 | |||
e57800daa2 | |||
d77465265c | |||
a758d36a08 | |||
9201326eab | |||
23b3543ba9 | |||
36a4339172 | |||
80d22ddcc1 | |||
e9db1fb9ee | |||
2c61943c9b | |||
c53190144a | |||
4767c6a872 | |||
0ae12b064f | |||
f8bd1e24df | |||
2b07399d7e | |||
9432c6b1ba | |||
a82cd9cdcc | |||
4ea4134f11 | |||
2de9729c1d | |||
773697be7b | |||
462e3179f1 | |||
ee8e741aaf | |||
bf95073c2e | |||
56d3b27ef9 | |||
437015589f | |||
6eadfa97df | |||
e1d09234e9 | |||
f53ede6c46 | |||
cbd21cf5fb | |||
ef0057c1b3 | |||
1332350e4b | |||
c7026ce9d3 | |||
f1bc7d4fae |
7
.gitignore
vendored
7
.gitignore
vendored
@ -3,3 +3,10 @@ Cartes
|
||||
Clients_IFPass.csv
|
||||
Clients_IFPass_backup.csv
|
||||
IFPass.conf
|
||||
Templates/IFPass_PDF_Template.pdf
|
||||
Templates/IFPass_PNG_Template.png
|
||||
build/x86/*
|
||||
build/x64/*
|
||||
# Except builds:
|
||||
!build/x86/*x86.exe
|
||||
!build/x64/*x64.exe
|
||||
|
@ -1,61 +0,0 @@
|
||||
Titre;Prénom;Nom;Numéro de client;Date d'inscripton;Date d'expiration
|
||||
;Jordan;ERNST;0000000001;21/03/2018;01/09/2019
|
||||
;Otto;MAJOROS;0000000002;21/03/2018;21/03/2019
|
||||
;Beata;LICSKO-TAKACS;0000000003;21/03/2018;21/03/2019
|
||||
;Timea;KLINCSEK;0000000004;22/03/2018;22/03/2019
|
||||
;Lili;PAMUK;0000000005;22/03/2018;22/03/2019
|
||||
;Petra;ZAJKÁS;0000000006;22/03/2018;22/03/2019
|
||||
;Corinne;GARDINI;0000000007;23/03/2018;23/03/2019
|
||||
;Nora;DIRAMERIAN;0000000008;23/03/2018;23/03/2050
|
||||
;Hedvig;ANTAL;0000000009;23/03/2018;23/03/2019
|
||||
;Hedvig;ANTAL;0000000010;23/03/2018;23/03/2019
|
||||
;Annabelle;LAGOA;0000000011;23/03/2018;23/03/2019
|
||||
;Erika;BALÁZS;0000000012;23/03/2018;23/03/2019
|
||||
;Krisztina;KIS;0000000013;23/03/2018;23/03/2019
|
||||
;Zsuzsanna;STIFFEL;0000000014;23/03/2018;23/03/2019
|
||||
;Martin;SANCHEZ;0000000015;23/03/2018;23/03/2019
|
||||
;Melinda;ERDŐHÁTI;0000000016;23/03/2018;23/03/2019
|
||||
;Zoltán;UZSÁK;0000000017;23/03/2018;23/03/2019
|
||||
;Péter;RÓZSA;0000000018;23/03/2018;23/03/2019
|
||||
;Ildikó;PUSZTAI;0000000019;23/03/2018;23/03/2019
|
||||
;Robert;KABA LOEMBA;0000000020;23/03/2018;23/03/2019
|
||||
;Ildikó;HORVÁTH;0000000021;24/03/2018;24/03/2019
|
||||
;Nora;MOHAMED-ELSAYED;0000000022;24/03/2018;24/03/2019
|
||||
;Dóra;MUNKÁS;0000000023;24/03/2018;24/03/2019
|
||||
;Nathalie;VAN PEE;0000000024;24/03/2018;24/03/2019
|
||||
;Gabriella;SZALAY;0000000025;24/03/2018;24/03/2019
|
||||
;Ambrus;GERGELY;0000000026;24/03/2018;24/03/2019
|
||||
;Mónika;GODA;0000000027;24/03/2018;24/03/2019
|
||||
;Laura;HOLLÓSI;0000000028;24/03/2018;24/03/2019
|
||||
;Magdolna;LEVAI;0000000029;24/03/2018;24/03/2019
|
||||
;Péter;LÔTE;0000000030;24/03/2018;24/03/2019
|
||||
;Judit;WEISZ;0000000031;24/03/2018;24/03/2019
|
||||
;Gergely;BABA;0000000032;24/03/2018;24/03/2019
|
||||
;Annamária;SINKOVICS;0000000033;24/03/2018;24/03/2019
|
||||
;Eszter;MALYATA;0000000034;27/03/2018;27/03/2019
|
||||
;Andrea;GORZO;0000000035;27/03/2018;27/03/2019
|
||||
;Béláné;POMOGÁTS;0000000036;27/03/2018;27/03/2019
|
||||
;Zsofia;HORVATH;0000000037;27/03/2018;27/03/2019
|
||||
;Adrienn;GULYÁS;0000000038;27/03/2018;27/03/2019
|
||||
;Rózsa;PERLAKI;0000000039;27/03/2018;27/03/2019
|
||||
;Gábor Dániel;ZAMARÓCZY;0000000040;27/03/2018;27/03/2019
|
||||
;Grégory;LUCAS;0000000041;28/03/2018;28/03/2019
|
||||
;Lajos;HORVÁTH;0000000042;28/03/2018;28/03/2019
|
||||
;Rachel;HIDAS;0000000043;28/03/2018;28/03/2019
|
||||
;Dominika;DUDÁS;0000000044;28/03/2018;28/03/2019
|
||||
;Tímea;MAZZAG;0000000045;28/03/2018;28/03/2019
|
||||
;Klára;NÉGYESI;0000000046;29/03/2018;29/03/2019
|
||||
;Xy;XY;0000000047;29/03/2018;29/03/2019
|
||||
Dr.;Aniko;RADVANSZKY;0000000048;29/03/2018;29/03/2019
|
||||
Dr.;Krisztina;KALMAN;0000000049;29/03/2018;29/03/2019
|
||||
;Janos;SZOKE;0000000050;29/03/2018;29/03/2019
|
||||
;Kata Lidia;HIDASI;0000000051;29/03/2018;29/03/2019
|
||||
;Dóra;HORVÁTH;0000000052;29/03/2018;29/03/2019
|
||||
;Olivier;CHIQUET;0000000053;29/03/2018;29/03/2019
|
||||
;Anne;LARNICOL;0000000054;29/03/2018;29/03/2019
|
||||
;Tamas;MEITNER;0000000055;03/04/2018;03/04/2019
|
||||
;Gyorgy;ONOZO;0000000056;03/04/2018;03/04/2019
|
||||
;Dorothee;MEENS;0000000057;03/04/2018;03/04/2019
|
||||
;Gergo;JANKOVICS;0000000058;03/04/2018;03/04/2019
|
||||
;Lenka;JAROLIMOVA;0000000059;03/04/2018;03/04/2019
|
||||
;Franck;LEFEBVRE;0000000060;03/04/2018;03/04/2019
|
|
436
IFPass.py
436
IFPass.py
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python3
|
||||
#!python3
|
||||
|
||||
# Written by Jordan ERNST Q1 2018.
|
||||
# Contact : pro.ernst@gmail.com
|
||||
@ -15,16 +15,18 @@ from pywinauto.findwindows import find_window
|
||||
from pywinauto.win32functions import SetForegroundWindow
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from PyPDF2 import PdfFileReader, PdfFileWriter
|
||||
import fitz # = PyMuPDF : To convert pdf to png
|
||||
import subprocess
|
||||
from shutil import copyfile
|
||||
from shutil import copyfile, move
|
||||
from pyfiglet import Figlet
|
||||
from colorama import init
|
||||
from termcolor import colored
|
||||
|
||||
|
||||
version = '2.0'
|
||||
version = '3.2' # dev/devnocam
|
||||
|
||||
config = 'IFPass.conf'
|
||||
configdir = os.path.join(os.getenv('PROGRAMDATA'), 'IFPass')
|
||||
config = os.path.join(configdir, 'IFPass.conf')
|
||||
|
||||
|
||||
def initialisation():
|
||||
@ -33,37 +35,71 @@ def initialisation():
|
||||
|
||||
if not os.path.exists(config): # Check if config file exists
|
||||
print('Fichier de configuration introuvable.')
|
||||
IFPassdir = input(r'Quel est le répertoire IFPass ? (Ex : \\192.168.1.1\IFPass) : ')
|
||||
printername = input("Quel est le nom de l'imprimante à cartes ? : " )
|
||||
AcrobatReader = input(r"Quel est le chemain vers Acrobat Reader ? ( Ex : C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe) : ")
|
||||
conf['DEFAULT'] = {'IFPassdir': IFPassdir, 'printername': printername, 'AcrobatReader': AcrobatReader}
|
||||
IFPassDBdir = input(r'Quel est le répertoire de la base de données IFPass ? (Ex : \\192.168.1.1\IFPass) : ')
|
||||
printername = input("Quel est le nom de l'imprimante à cartes ? : ")
|
||||
adobex86 = os.path.join(os.getenv('PROGRAMFILES(x86)'), 'Adobe', "Acrobat Reader DC", "Reader", "AcroRd32.exe")
|
||||
adobex64 = os.path.join(os.getenv('PROGRAMFILES'), 'Adobe', "Acrobat Reader DC", "Reader", "AcroRd32.exe")
|
||||
if os.path.exists(adobex86):
|
||||
AcrobatReader = adobex86
|
||||
elif os.path.exists(adobex64):
|
||||
AcrobatReader = adobex64
|
||||
else:
|
||||
acrinstalled = yes_or_no("Acrobat Reader est nécessaire pour imprimer les cartes. Est il installé ?")
|
||||
if acrinstalled:
|
||||
while "Wrong path":
|
||||
AcrobatReader = input(r"Quel est le chemin vers Acrobat Reader ? ( Ex : C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe) : ")
|
||||
if os.path.exists(AcrobatReader):
|
||||
break
|
||||
else:
|
||||
print(colored('\nChemin invalide !', 'red'))
|
||||
else:
|
||||
print(colored('\nInstallez Acrobat Reader, puis relancez IFPass.', 'red'))
|
||||
os.system("pause")
|
||||
sys.exit()
|
||||
conf['DEFAULT'] = {'IFPassDBdir': IFPassDBdir, 'printername': printername, 'AcrobatReader': AcrobatReader}
|
||||
os.makedirs(configdir, 0o777)
|
||||
with open(config, 'w') as configfile:
|
||||
conf.write(configfile)
|
||||
else:
|
||||
conf.read(config)
|
||||
IFPassdir = conf['DEFAULT']['IFPassdir']
|
||||
IFPassDBdir = conf['DEFAULT']['IFPassDBdir']
|
||||
printername = conf['DEFAULT']['printername']
|
||||
AcrobatReader = conf['DEFAULT']['AcrobatReader']
|
||||
|
||||
|
||||
clientsfile = os.path.join(IFPassdir, 'Clients_IFPass.csv')
|
||||
clientsbkpfile = os.path.join(IFPassdir, 'Clients_IFPass_backup.csv')
|
||||
imgdir = os.path.join(IFPassdir, 'Cartes')
|
||||
pdftemplate = os.path.join(IFPassdir, 'Templates', 'IFPass_PDF_Template.pdf')
|
||||
pngtemplate = os.path.join(IFPassdir, 'Templates', 'IFPass_PNG_Template.png')
|
||||
fonttemplate = os.path.join(IFPassdir, 'Templates', 'Roboto-Bold.ttf')
|
||||
clientsfile = os.path.join(IFPassDBdir, 'Clients_IFPass.csv')
|
||||
clientsbkpfile = os.path.join(IFPassDBdir, 'Clients_IFPass_backup.csv')
|
||||
imgdir = os.path.join(IFPassDBdir, 'Cartes')
|
||||
templatesdir = os.path.join(IFPassDBdir, 'Templates')
|
||||
pdftemplate = os.path.join(templatesdir, 'IFPass_PDF_Template.pdf')
|
||||
pngtemplate = os.path.join(templatesdir, 'IFPass_PNG_Template.png')
|
||||
fonttemplate = os.path.join(templatesdir, 'Roboto-Bold.ttf')
|
||||
|
||||
if not os.path.exists(imgdir): # Cartes dir creation if it doesn't exist
|
||||
os.makedirs(imgdir)
|
||||
os.makedirs(imgdir, 0o777)
|
||||
if not os.path.exists(clientsfile): # Creation Clients_File if it doesn't exist
|
||||
with open(clientsfile, 'w', newline='', encoding='utf-8') as csvfile:
|
||||
writer = csv.writer(csvfile, delimiter=';')
|
||||
writer.writerow(['Titre', 'Prénom', 'Nom', 'Numéro de client', "Date d'inscription", "Date d'expiration"])
|
||||
return IFPassdir, printername, AcrobatReader, clientsfile, clientsbkpfile, imgdir, pdftemplate, pngtemplate, fonttemplate
|
||||
if not os.path.exists(templatesdir):
|
||||
move('Templates', IFPassDBdir)
|
||||
|
||||
return IFPassDBdir, printername, AcrobatReader, clientsfile, clientsbkpfile, imgdir, templatesdir, pdftemplate, pngtemplate, fonttemplate
|
||||
|
||||
|
||||
def get_fullname():
|
||||
firstname = input("Prénom : ").strip()
|
||||
def get_fullname(**kwargs): # **kwargs => Optionnal arguments
|
||||
if 'firstname' in kwargs:
|
||||
firstname = kwargs['firstname']
|
||||
newfirstname = input("Prénom (" + firstname + "): ").strip()
|
||||
if len(newfirstname) != 0:
|
||||
firstname = newfirstname
|
||||
else:
|
||||
while "Empty firstname":
|
||||
firstname = input("Prénom : ").strip()
|
||||
if len(firstname) == 0:
|
||||
os.system('cls')
|
||||
print(colored("\nLe Prénom ne peut pas être vide.", 'red'))
|
||||
else:
|
||||
break
|
||||
firstname = firstname[0].upper() + firstname[1:].lower()
|
||||
if '-' in firstname:
|
||||
pos = firstname.find("-")
|
||||
@ -73,15 +109,29 @@ def get_fullname():
|
||||
pos = firstname.find(" ")
|
||||
firstname = firstname[:pos + 1] + firstname[pos + 1].upper() + \
|
||||
firstname[pos + 2:] # Check if compound name
|
||||
surname = input("Nom : ").upper().strip()
|
||||
|
||||
if 'surname' in kwargs:
|
||||
surname = kwargs['surname']
|
||||
newsurname = input("Nom (" + surname + "): ").strip()
|
||||
if len(newsurname) != 0:
|
||||
surname = newsurname
|
||||
else:
|
||||
while "Empty surname":
|
||||
surname = input("Nom : ").strip()
|
||||
if len(surname) == 0:
|
||||
os.system('cls')
|
||||
print(colored("\nLe Nom ne peut pas être vide.", 'red'))
|
||||
else:
|
||||
break
|
||||
surname = surname.upper()
|
||||
docteur = yes_or_no('Est-ce un Docteur ?')
|
||||
if docteur:
|
||||
titre = 'Dr.'
|
||||
fullname = titre + ' ' + surname + ' ' + firstname
|
||||
titrename = titre + ' ' + surname
|
||||
else:
|
||||
titre = ''
|
||||
fullname = surname + ' ' + firstname
|
||||
return titre, firstname, surname, fullname
|
||||
titrename = surname
|
||||
return titre, firstname, surname, titrename
|
||||
|
||||
|
||||
def yes_or_no(question):
|
||||
@ -102,13 +152,12 @@ def getclientID():
|
||||
else:
|
||||
clientID = str(int(lastID) + 1).zfill(10)
|
||||
|
||||
writeindb(clientID)
|
||||
return clientID
|
||||
|
||||
|
||||
def barcode_gen(clientID):
|
||||
print("Génération du code barre... ", end='')
|
||||
barcode = code128.image(clientID, thickness=4) # .save(imgdir + clientID + '.png')
|
||||
barcode = code128.image(clientID, thickness=4) # .save(imgdir + clientID + '.png')
|
||||
print(colored('[OK]', 'green'))
|
||||
return barcode
|
||||
|
||||
@ -131,19 +180,20 @@ def getpic():
|
||||
'pour prendre la photo, Echap pour une carte sans photo, Q pour quitter.'))
|
||||
k = cv2.waitKey(1)
|
||||
if k == 27: # Echap
|
||||
cap.release()
|
||||
print(colored('[OK]', 'green'))
|
||||
cv2.destroyAllWindows()
|
||||
defaultpicture = os.path.join(IFPassdir, 'Templates', 'default_avatar.jpg')
|
||||
defaultpicture = os.path.join(IFPassDBdir, 'Templates', 'default_avatar.jpg')
|
||||
picture = Image.open(defaultpicture)
|
||||
return picture
|
||||
elif k & 0xFF == ord(' '): # Space
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
break
|
||||
elif k & 0xFF == ord('q'): # Q or q to quit
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
sys.exit()
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
cropped = frame[75:405, 172:468]
|
||||
cv2.imshow('IFCamera - Espace pour valider, Echap pour modifier, Q pour quitter', cropped)
|
||||
while True:
|
||||
@ -161,46 +211,73 @@ def getpic():
|
||||
picture = Image.fromarray(cropped)
|
||||
return picture
|
||||
|
||||
|
||||
elif k & 0xFF == ord('q'): # Q or q to quit
|
||||
cv2.destroyAllWindows()
|
||||
sys.exit()
|
||||
|
||||
|
||||
def writeindb(clientID):
|
||||
print("Ajout dans la base de données... ", end="")
|
||||
with open(clientsfile, 'a', newline='', encoding='utf-8') as csvfile:
|
||||
writer = csv.writer(csvfile, delimiter=';')
|
||||
writer.writerow([titre, firstname, surname, clientID, dateinsc, dateexp])
|
||||
print(colored('[OK]', 'green'))
|
||||
def writeindb(titre, firstname, surname, clientID, dateinsc, dateexp, new):
|
||||
if new is True:
|
||||
print("Ajout dans la base de données... ", end="")
|
||||
with open(clientsfile, 'a', newline='', encoding='utf-8') as csvfile:
|
||||
writer = csv.writer(csvfile, delimiter=';')
|
||||
writer.writerow([titre, firstname, surname, clientID, dateinsc, dateexp])
|
||||
print(colored('[OK]', 'green'))
|
||||
elif new is False:
|
||||
print("Modification de la base de données... ", end="")
|
||||
with open(clientsfile, 'r+', newline='', encoding='utf-8') as csvfile:
|
||||
content = csvfile.readlines()
|
||||
for index, member in enumerate(content):
|
||||
member = member.split(';')
|
||||
if member[3] == clientID:
|
||||
tochange = index
|
||||
break
|
||||
content.pop(tochange)
|
||||
changewith = ";".join([titre, firstname, surname, clientID, dateinsc, dateexp]) + '\n'
|
||||
content.insert(tochange, changewith)
|
||||
content = "".join(content)
|
||||
csvfile.seek(0)
|
||||
csvfile.truncate(0)
|
||||
csvfile.write(content)
|
||||
|
||||
print(colored('[OK]', 'green'))
|
||||
|
||||
|
||||
def bkpdb():
|
||||
copyfile(clientsfile, clientsbkpfile)
|
||||
|
||||
|
||||
def fillcard(barcode):
|
||||
print("Création de la carte avec les informations...", end='')
|
||||
im = Image.open(pngtemplate)
|
||||
def fillcard(clientID, titrename, firstname, dateexp, barcode, picture):
|
||||
print("Création du verso de la carte avec les informations...", end='')
|
||||
try:
|
||||
im = Image.open(pngtemplate)
|
||||
except FileNotFoundError:
|
||||
os.system('cls')
|
||||
print(colored('Vous avez besoin de 2 fichiers dans le dossier Templates pour générer des cartes :', 'red'))
|
||||
print(templatesdir + '\\IFPass_PDF_Template.pdf : Modèle de la carte (recto et verso)')
|
||||
print(templatesdir + '\\IFPass_PNG_Template.png : La face avant de la carte (celle à remplir)')
|
||||
os.system("pause")
|
||||
sys.exit()
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
||||
# Name embedding :
|
||||
font = ImageFont.truetype(fonttemplate, 45)
|
||||
draw.text((401, 310), fullname, fill=(0,0,0), font=font)
|
||||
font = ImageFont.truetype(fonttemplate, 40)
|
||||
draw.text((401, 296), titrename, fill=(0, 0, 0), font=font)
|
||||
draw.text((401, 334), firstname, fill=(0, 0, 0), font=font)
|
||||
|
||||
# Date embedding :
|
||||
font = ImageFont.truetype(fonttemplate, 30)
|
||||
draw.text((401, 390), dateexp, fill=(0,0,0), font=font)
|
||||
draw.text((401, 400), dateexp, fill=(0, 0, 0), font=font)
|
||||
|
||||
# ID embedding :
|
||||
font = ImageFont.truetype('arial.ttf', 30)
|
||||
draw.text((693, 560), clientID, fill=(0,0,0), font=font)
|
||||
draw.text((693, 560), clientID, fill=(0, 0, 0), font=font)
|
||||
|
||||
# Barcode + picture embedding :
|
||||
im.paste(barcode,(556, 460))
|
||||
im.paste(barcode, (556, 460))
|
||||
|
||||
if version != 'devnocam':
|
||||
im.paste(picture,(47, 49))
|
||||
im.paste(picture, (47, 49))
|
||||
|
||||
# Create PDF :
|
||||
im = im.convert("RGB")
|
||||
@ -209,7 +286,8 @@ def fillcard(barcode):
|
||||
print(colored('[OK]', 'green'))
|
||||
|
||||
|
||||
def mergepdf():
|
||||
def mergepdf(clientID):
|
||||
print("Fusion du recto et du verso de la carte...", end='')
|
||||
cartefilename = os.path.join(imgdir, clientID + '.pdf')
|
||||
output = PdfFileWriter()
|
||||
|
||||
@ -225,19 +303,67 @@ def mergepdf():
|
||||
output.write(f)
|
||||
|
||||
os.remove(imgdir + clientID + '_Front.pdf')
|
||||
print(colored('[OK]', 'green'))
|
||||
|
||||
return cartefilename
|
||||
|
||||
|
||||
def printcard(cartefilename):
|
||||
# Working : subprocess.Popen('"C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" /h /n /t ' + cartefilename + ' '+ printername, shell=False)
|
||||
subprocess.Popen('"' + AcrobatReader + '"' + ' /h /n /t ' + cartefilename + ' '+ printername, shell=False)
|
||||
subprocess.Popen('"' + AcrobatReader + '"' + ' /h /n /t ' + cartefilename + ' ' + printername, shell=False)
|
||||
|
||||
|
||||
def getdateexp():
|
||||
while True:
|
||||
dateexp = input("Quelle date d'expiration voulez-vous mettre (Format : JJ/MM/AAAA)? : ")
|
||||
match = re.fullmatch(r'^(0[1-9]|1[0-9]|2[0-9]|3[0-1])/(0[1-9]|1[0-2])/([0-9]){4}$', dateexp)
|
||||
if match:
|
||||
break
|
||||
else:
|
||||
print('Mauvais format ! JJ/MM/AAAA, exemple : 01/08/2042')
|
||||
return dateexp
|
||||
|
||||
|
||||
def newmember():
|
||||
while "the informations are incorrect": # Loop Filling informations
|
||||
os.system('cls')
|
||||
titre, firstname, surname, titrename = get_fullname()
|
||||
dateinsc = date.today()
|
||||
dateexp = dateinsc + timedelta(days=365)
|
||||
|
||||
dateinsc = dateinsc.strftime('%d/%m/%Y')
|
||||
dateexp = dateexp.strftime('%d/%m/%Y')
|
||||
changeexp = yes_or_no("Voulez-vous choisir la date d'expiration ?")
|
||||
if changeexp:
|
||||
dateexp = getdateexp()
|
||||
|
||||
os.system('cls')
|
||||
print("Titre : ", colored(titre, 'green'))
|
||||
print("Prénom : ", colored(firstname, 'green'))
|
||||
print("Nom : ", colored(surname, 'green'))
|
||||
print("Date d'inscription :", colored(dateinsc, 'green'))
|
||||
print("Date d'expiration : ", colored(dateexp, 'green'))
|
||||
correct = yes_or_no("Ces informations sont elles correctes ?")
|
||||
|
||||
if correct:
|
||||
os.system('cls')
|
||||
if version != 'devnocam':
|
||||
picture = getpic()
|
||||
clientID = getclientID()
|
||||
barcode = barcode_gen(clientID)
|
||||
fillcard(clientID, titrename, firstname, dateexp, barcode, picture)
|
||||
cartefilename = mergepdf(clientID)
|
||||
if version not in ('dev', 'devnocam'):
|
||||
bkpdb()
|
||||
printcard(cartefilename)
|
||||
writeindb(titre, firstname, surname, clientID, dateinsc, dateexp, new=True)
|
||||
break
|
||||
|
||||
|
||||
def membersearch():
|
||||
with open(clientsfile, 'r', newline='', encoding='utf-8') as csvfile:
|
||||
reader = csv.reader(csvfile, delimiter=';')
|
||||
csvlist = list(map(tuple, reader))
|
||||
csvlist = list(map(list, reader))
|
||||
del csvlist[0] # We dele the first line (Prénom, Nom...)
|
||||
research = input('Entrez une partie du nom, prénom, ou numéro de carte (ou flashez) : ').lower()
|
||||
os.system('cls')
|
||||
@ -267,87 +393,171 @@ def membersearch():
|
||||
break
|
||||
except (IndexError, ValueError):
|
||||
print(colored('Choix invalide ! Veillez bien à sélectionner le numéro de la colonne "Choix"', 'red', attrs=['bold']))
|
||||
os.system('cls')
|
||||
os.system('cls')
|
||||
|
||||
print("Titre : ", colored(member[0], 'green'))
|
||||
print("Prénom : ", colored(member[1], 'green'))
|
||||
print("Nom : ", colored(member[2], 'green'))
|
||||
print("Numéro de carte : ", colored(member[3], 'green'))
|
||||
print("Date d'inscription :", member[4])
|
||||
print("Date d'expiration : ", member[5])
|
||||
dateexp = datetime.strptime(member[5], '%d/%m/%Y').date()
|
||||
diff = (dateexp - date.today()).days
|
||||
if diff > 0:
|
||||
print(colored(f"L'abonnement est encore valable {diff} jours.", 'green', attrs=['bold']))
|
||||
elif diff < 0:
|
||||
print(colored("L'abonnement est expiré depuis {abs(diff)} jours.", 'red', attrs=['bold'])) # abs() to remove minus sign
|
||||
elif diff == 0:
|
||||
print(colored("Il s'agit du dernier jour de l'abonnement, il expirera demain.", 'yellow', attrs=['bold']))
|
||||
while 'Choix incorect':
|
||||
print("Titre : ", colored(member[0], 'green'))
|
||||
print("Prénom : ", colored(member[1], 'green'))
|
||||
print("Nom : ", colored(member[2], 'green'))
|
||||
print("Numéro de carte : ", colored(member[3], 'green'))
|
||||
print("Date d'inscription :", member[4])
|
||||
print("Date d'expiration : ", member[5])
|
||||
dateexp = datetime.strptime(member[5], '%d/%m/%Y').date()
|
||||
diff = (dateexp - date.today()).days
|
||||
if diff > 0:
|
||||
print(colored(f"L'abonnement est encore valable {diff} jours.", 'green', attrs=['bold']))
|
||||
elif diff < 0:
|
||||
print(colored(f"L'abonnement est expiré depuis {abs(diff)} jours.", 'red', attrs=['bold'])) # abs() to remove minus sign
|
||||
elif diff == 0:
|
||||
print(colored("Il s'agit du dernier jour de l'abonnement, il expirera demain.", 'yellow', attrs=['bold']))
|
||||
|
||||
print('\n1 - Modifier', "2 - Renouveller l'abonnement / Choisir un nouvelle date d'expiration", '3 - Imprimer la carte', '0 - Menu principal', sep='\n')
|
||||
choix = input('Choix : ')
|
||||
if choix == '0':
|
||||
os.system('cls')
|
||||
return
|
||||
# We update values with new (edited) values :
|
||||
newtitre, newfirstname, newsurname, newdateexp = memberdo(choix, member)
|
||||
member[0], member[1], member[2], member[5] = newtitre, newfirstname, newsurname, newdateexp
|
||||
|
||||
else:
|
||||
print(colored("Aucun membre n'a été trouvé.", 'red', attrs=['bold']))
|
||||
os.system("pause")
|
||||
|
||||
|
||||
while "The program is running":
|
||||
init() # Initialisation of colorama
|
||||
IFPassdir, printername, AcrobatReader, clientsfile, clientsbkpfile, imgdir, pdftemplate, pngtemplate, fonttemplate = initialisation()
|
||||
def memberdo(choix, member):
|
||||
titre = member[0]
|
||||
firstname = member[1]
|
||||
surname = member[2]
|
||||
clientID = member[3]
|
||||
dateinsc = member[4]
|
||||
dateexp = member[5]
|
||||
|
||||
os.system('cls')
|
||||
print('1 - Nouveau membre', '2 - Rechercher un membre', '3 - Quitter', sep='\n')
|
||||
choix = input('Choix : ')
|
||||
if choix == '1':
|
||||
while "the informations are incorrect": # Loop Filling informations
|
||||
os.system('cls')
|
||||
f = Figlet(font='big')
|
||||
print(colored(f.renderText('IFPass'), 'cyan', attrs=['bold']))
|
||||
print('Version : ', version)
|
||||
if version in ('dev', 'devnocam'):
|
||||
print(colored("\nATTENTION : Il s'agit d'une version en cours de développement, potentiellement instable !", 'red'))
|
||||
print('\nLe programme IFPass à été écrit par Jordan ERNST Q1 2018.')
|
||||
print('Pour toute question ou problème contactez-moi à pro.ernst@gmail.com.\n')
|
||||
titre, firstname, surname, fullname = get_fullname()
|
||||
dateinsc = date.today()
|
||||
dateexp = dateinsc + timedelta(days=365)
|
||||
if choix == '1': # Edit member
|
||||
titre, firstname, surname, dateexp = memberedit(titre, firstname, surname, clientID, dateinsc, dateexp)
|
||||
|
||||
dateinsc = dateinsc.strftime('%d/%m/%Y')
|
||||
elif choix == '2': # Renew subscription
|
||||
changeexp = yes_or_no("Voulez-vous choisir la date d'expiration ?")
|
||||
if changeexp:
|
||||
dateexp = getdateexp()
|
||||
else:
|
||||
dateexp = datetime.strptime(dateexp, '%d/%m/%Y').date()
|
||||
diff = (dateexp - date.today()).days
|
||||
if diff >= 0:
|
||||
dateexp = dateexp + timedelta(days=365)
|
||||
elif diff < 0:
|
||||
dateexp = date.today() + timedelta(days=365)
|
||||
dateexp = dateexp.strftime('%d/%m/%Y')
|
||||
changeexp = yes_or_no("Voulez-vous choisir la date d'expiration ?")
|
||||
if changeexp:
|
||||
while True:
|
||||
dateexp = input("Quelle date d'expiration voulez-vous mettre (Format : JJ/MM/AAAA)? : ")
|
||||
match = re.fullmatch(r'^(0[1-9]|1[0-9]|2[0-9]|3[0-1])/(0[1-9]|1[0-2])/([0-9]){4}$', dateexp)
|
||||
if match:
|
||||
break
|
||||
else:
|
||||
print('Mauvais format ! JJ/MM/AAAA, exemple : 01/08/2042')
|
||||
|
||||
if titre == 'Dr.':
|
||||
titrename = titre + ' ' + surname
|
||||
else:
|
||||
titrename = surname
|
||||
|
||||
wantnewpic = yes_or_no("Voulez-vous prendre une nouvelle photo ?")
|
||||
os.system('cls')
|
||||
if wantnewpic:
|
||||
os.system('cls')
|
||||
print("Titre : ", colored(titre, 'green'))
|
||||
print("Prénom : ", colored(firstname, 'green'))
|
||||
print("Nom : ", colored(surname, 'green'))
|
||||
print("Date d'inscription :", colored(dateinsc, 'green'))
|
||||
print("Date d'expiration : ", colored(dateexp, 'green'))
|
||||
correct = yes_or_no("Ces informations sont elles correctes ?")
|
||||
if version != 'devnocam':
|
||||
picture = getpic()
|
||||
else:
|
||||
# We crop pic from the previous card
|
||||
cartefilename = os.path.join(imgdir, clientID + '.pdf')
|
||||
pdf = fitz.open(cartefilename)
|
||||
page = pdf.loadPage(0)
|
||||
mat = fitz.Matrix(4.165, 4.165) # To obtain good resolution
|
||||
pix = page.getPixmap(matrix=mat)
|
||||
pageimg = Image.frombytes("RGBA", [pix.width, pix.height], pix.samples)
|
||||
picture = pageimg.crop((47, 49, 343, 378))
|
||||
|
||||
if correct:
|
||||
barcode = barcode_gen(clientID)
|
||||
fillcard(clientID, titrename, firstname, dateexp, barcode, picture)
|
||||
cartefilename = mergepdf(clientID)
|
||||
|
||||
if version not in ('dev', 'devnocam'):
|
||||
bkpdb()
|
||||
printcard(cartefilename)
|
||||
writeindb(titre, firstname, surname, clientID, dateinsc, dateexp, new=False)
|
||||
os.system('cls')
|
||||
print(colored("La date d'expiration a bien été mise à jour !\n", 'blue', attrs=['bold']))
|
||||
|
||||
elif choix == '3': # Print card
|
||||
cartefilename = os.path.join(imgdir, clientID + '.pdf')
|
||||
printcard(cartefilename)
|
||||
else:
|
||||
print(colored('Choix incorrect !\n', 'red', attrs=['bold']))
|
||||
return titre, firstname, surname, dateexp
|
||||
|
||||
|
||||
def memberedit(titre, firstname, surname, clientID, dateinsc, dateexp):
|
||||
while "the informations are incorrect": # Loop Filling informations
|
||||
titre, firstname, surname, titrename = get_fullname(titre=titre, firstname=firstname, surname=surname)
|
||||
|
||||
print("Titre : ", colored(titre, 'green'))
|
||||
print("Prénom : ", colored(firstname, 'green'))
|
||||
print("Nom : ", colored(surname, 'green'))
|
||||
|
||||
correct = yes_or_no("Ces informations sont elles correctes ?")
|
||||
os.system('cls')
|
||||
|
||||
if correct:
|
||||
wantnewpic = yes_or_no("Voulez-vous prendre une nouvelle photo ?")
|
||||
os.system('cls')
|
||||
if wantnewpic:
|
||||
os.system('cls')
|
||||
if version != 'devnocam':
|
||||
picture = getpic()
|
||||
clientID = getclientID()
|
||||
barcode = barcode_gen(clientID)
|
||||
fillcard(barcode)
|
||||
cartefilename = mergepdf()
|
||||
if version not in ('dev', 'devnocam'):
|
||||
bkpdb()
|
||||
printcard(cartefilename)
|
||||
elif choix == '2':
|
||||
os.system('cls')
|
||||
membersearch()
|
||||
else:
|
||||
# We crop pic from the previous card
|
||||
cartefilename = os.path.join(imgdir, clientID + '.pdf')
|
||||
pdf = fitz.open(cartefilename)
|
||||
page = pdf.loadPage(0)
|
||||
mat = fitz.Matrix(4.165, 4.165) # To obtain good resolution
|
||||
pix = page.getPixmap(matrix=mat)
|
||||
|
||||
elif choix == '3':
|
||||
sys.exit()
|
||||
pageimg = Image.frombytes("RGBA", [pix.width, pix.height], pix.samples)
|
||||
picture = pageimg.crop((47, 49, 343, 378))
|
||||
|
||||
barcode = barcode_gen(clientID)
|
||||
fillcard(clientID, titrename, firstname, dateexp, barcode, picture)
|
||||
cartefilename = mergepdf(clientID)
|
||||
if version not in ('dev', 'devnocam'):
|
||||
bkpdb()
|
||||
printcard(cartefilename)
|
||||
writeindb(titre, firstname, surname, clientID, dateinsc, dateexp, new=False)
|
||||
os.system('cls')
|
||||
break
|
||||
return titre, firstname, surname, dateexp
|
||||
|
||||
|
||||
def main():
|
||||
global IFPassDBdir, clientsfile, imgdir, clientsbkpfile, templatesdir, pngtemplate, fonttemplate, pdftemplate, printername, AcrobatReader
|
||||
while "The program is running":
|
||||
init() # Initialisation of colorama
|
||||
IFPassDBdir, printername, AcrobatReader, clientsfile, clientsbkpfile, imgdir, templatesdir, pdftemplate, pngtemplate, fonttemplate = initialisation()
|
||||
|
||||
else:
|
||||
os.system('cls')
|
||||
print(colored('Choix incorrect !', 'red', attrs=['bold']))
|
||||
os.system("pause")
|
||||
f = Figlet(font='big')
|
||||
print(colored(f.renderText('IFPass'), 'cyan', attrs=['bold']))
|
||||
print('Version : ', version)
|
||||
if version in ('dev', 'devnocam'):
|
||||
print(colored("\nATTENTION : Il s'agit d'une version en cours de développement, potentiellement instable !", 'red'))
|
||||
print("\nCe programme est developpé par par Jordan ERNST pour l'Institut Français en Hongrie.")
|
||||
print("Il est disponible sou licence MIT à cette addresse : https://framagit.org/SecT0uch/IFPass\n")
|
||||
print('Pour toute question, problème ou requête contactez-moi à pro.ernst@gmail.com.\n')
|
||||
print('1 - Nouveau membre', '2 - Rechercher un membre', '0 - Quitter', sep='\n')
|
||||
choix = input('Choix : ')
|
||||
if choix == '1':
|
||||
newmember()
|
||||
|
||||
elif choix == '2':
|
||||
os.system('cls')
|
||||
membersearch()
|
||||
|
||||
elif choix == '0':
|
||||
sys.exit()
|
||||
|
||||
else:
|
||||
os.system('cls')
|
||||
print(colored('Choix incorrect !', 'red', attrs=['bold']))
|
||||
|
@ -1,5 +0,0 @@
|
||||
-Installer python 3.6 VERSION 64 bits : https://www.python.org/ftp/python/3.6.4/python-3.6.4-amd64-webinstall.exe
|
||||
-Téléchargez (cp36 pour Python 3.6) : https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv
|
||||
-Installer les modules python termcolor, colorama, pyfiglet, code128, Pillow, numpy, pywinauto, PyPDF2 et opencv:
|
||||
-Lancer cmd.exe en tant qu'admin
|
||||
-Exécuter : pip install termcolor colorama pyfiglet code128 Pillow pywinauto PyPDF2 numpy C:\path\to\opencv_python-3.4.0-cp36-cp36m-win_amd64.whl
|
189
Installer_Template.nsi
Normal file
189
Installer_Template.nsi
Normal file
@ -0,0 +1,189 @@
|
||||
!define PRODUCT_NAME "[[ib.appname]]"
|
||||
!define PRODUCT_VERSION "[[ib.version]]"
|
||||
!define PY_VERSION "[[ib.py_version]]"
|
||||
!define PY_MAJOR_VERSION "[[ib.py_major_version]]"
|
||||
!define BITNESS "[[ib.py_bitness]]"
|
||||
!define ARCH_TAG "[[arch_tag]]"
|
||||
!define INSTALLER_NAME "[[ib.installer_name]]"
|
||||
!define PRODUCT_ICON "[[icon]]"
|
||||
|
||||
; Marker file to tell the uninstaller that it's a user installation
|
||||
!define USER_INSTALL_MARKER _user_install_marker
|
||||
|
||||
Unicode true
|
||||
InstallDir "C:\IFPass"
|
||||
|
||||
SetCompressor lzma
|
||||
|
||||
[% block modernui %]
|
||||
; Modern UI installer stuff
|
||||
!include "MUI2.nsh"
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON "[[icon]]"
|
||||
!define MUI_UNICON "[[icon]]"
|
||||
|
||||
; UI pages
|
||||
[% block ui_pages %]
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
[% if license_file %]
|
||||
!insertmacro MUI_PAGE_LICENSE [[license_file]]
|
||||
[% endif %]
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
[% endblock ui_pages %]
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
[% endblock modernui %]
|
||||
|
||||
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
|
||||
OutFile "${INSTALLER_NAME}"
|
||||
ShowInstDetails show
|
||||
|
||||
Section -SETTINGS
|
||||
SetOutPath "$INSTDIR"
|
||||
SetOverwrite ifnewer
|
||||
SectionEnd
|
||||
|
||||
[% block sections %]
|
||||
|
||||
Section "!${PRODUCT_NAME}" sec_app
|
||||
SetRegView [[ib.py_bitness]]
|
||||
SetShellVarContext all
|
||||
SectionIn RO
|
||||
File ${PRODUCT_ICON}
|
||||
SetOutPath "$INSTDIR\pkgs"
|
||||
File /r "pkgs\*.*"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
[% block install_files %]
|
||||
; Install files
|
||||
[% for destination, group in grouped_files %]
|
||||
SetOutPath "[[destination]]"
|
||||
[% for file in group %]
|
||||
File "[[ file ]]"
|
||||
[% endfor %]
|
||||
[% endfor %]
|
||||
|
||||
; Install directories
|
||||
[% for dir, destination in ib.install_dirs %]
|
||||
SetOutPath "[[ pjoin(destination, dir) ]]"
|
||||
File /r "[[dir]]\*.*"
|
||||
[% endfor %]
|
||||
[% endblock install_files %]
|
||||
|
||||
[% block install_shortcuts %]
|
||||
; Install shortcuts
|
||||
; The output path becomes the working directory for shortcuts
|
||||
SetOutPath "$INSTDIR"
|
||||
[% if single_shortcut %]
|
||||
[% for scname, sc in ib.shortcuts.items() %]
|
||||
CreateShortCut "$SMPROGRAMS\[[scname]].lnk" "[[sc['target'] ]]" \
|
||||
'[[ sc['parameters'] ]]' "$INSTDIR\[[ sc['icon'] ]]"
|
||||
CreateShortCut "$DESKTOP\[[scname]].lnk" "[[sc['target'] ]]" \
|
||||
'[[ sc['parameters'] ]]' "$INSTDIR\[[ sc['icon'] ]]"
|
||||
[% endfor %]
|
||||
[% else %]
|
||||
[# Multiple shortcuts: create a directory for them #]
|
||||
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
[% for scname, sc in ib.shortcuts.items() %]
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\[[scname]].lnk" "[[sc['target'] ]]" \
|
||||
'[[ sc['parameters'] ]]' "$INSTDIR\[[ sc['icon'] ]]"
|
||||
[% endfor %]
|
||||
[% endif %]
|
||||
SetOutPath "$INSTDIR"
|
||||
[% endblock install_shortcuts %]
|
||||
|
||||
[% block install_commands %]
|
||||
[% if has_commands %]
|
||||
DetailPrint "Setting up command-line launchers..."
|
||||
nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_assemble_launchers.py" "$INSTDIR\bin"'
|
||||
[% endif %]
|
||||
[% endblock install_commands %]
|
||||
|
||||
; Byte-compile Python files.
|
||||
DetailPrint "Byte-compiling Python modules..."
|
||||
nsExec::ExecToLog '[[ python ]] -m compileall -q "$INSTDIR\pkgs"'
|
||||
WriteUninstaller $INSTDIR\uninstall.exe
|
||||
; Add ourselves to Add/remove programs
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"DisplayName" "${PRODUCT_NAME}"
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"UninstallString" '"$INSTDIR\uninstall.exe"'
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"InstallLocation" "$INSTDIR"
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"DisplayIcon" "$INSTDIR\${PRODUCT_ICON}"
|
||||
[% if ib.publisher is not none %]
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"Publisher" "[[ib.publisher]]"
|
||||
[% endif %]
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"DisplayVersion" "${PRODUCT_VERSION}"
|
||||
WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"NoModify" 1
|
||||
WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"NoRepair" 1
|
||||
|
||||
; Check if we need to reboot
|
||||
IfRebootFlag 0 noreboot
|
||||
MessageBox MB_YESNO "A reboot is required to finish the installation. Do you wish to reboot now?" \
|
||||
/SD IDNO IDNO noreboot
|
||||
Reboot
|
||||
noreboot:
|
||||
SectionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
SetRegView [[ib.py_bitness]]
|
||||
SetShellVarContext all
|
||||
|
||||
Delete $INSTDIR\uninstall.exe
|
||||
Delete "$INSTDIR\${PRODUCT_ICON}"
|
||||
RMDir /r "$INSTDIR\pkgs"
|
||||
|
||||
; Remove ourselves from %PATH%
|
||||
[% block uninstall_commands %]
|
||||
[% if has_commands %]
|
||||
nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_system_path.py" remove "$INSTDIR\bin"'
|
||||
[% endif %]
|
||||
[% endblock uninstall_commands %]
|
||||
|
||||
[% block uninstall_files %]
|
||||
; Uninstall files
|
||||
[% for file, destination in ib.install_files %]
|
||||
Delete "[[pjoin(destination, file)]]"
|
||||
[% endfor %]
|
||||
; Uninstall directories
|
||||
[% for dir, destination in ib.install_dirs %]
|
||||
RMDir /r "[[pjoin(destination, dir)]]"
|
||||
[% endfor %]
|
||||
[% endblock uninstall_files %]
|
||||
|
||||
[% block uninstall_shortcuts %]
|
||||
; Uninstall shortcuts
|
||||
[% if single_shortcut %]
|
||||
[% for scname in ib.shortcuts %]
|
||||
Delete "$SMPROGRAMS\[[scname]].lnk"
|
||||
Delete "$DESKTOP\[[scname]].lnk"
|
||||
[% endfor %]
|
||||
[% else %]
|
||||
RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
[% endif %]
|
||||
[% endblock uninstall_shortcuts %]
|
||||
RMDir $INSTDIR
|
||||
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
SectionEnd
|
||||
|
||||
[% endblock sections %]
|
||||
|
||||
; Functions
|
||||
|
||||
Function .onMouseOverSection
|
||||
; Find which section the mouse is over, and set the corresponding description.
|
||||
FindWindow $R0 "#32770" "" $HWNDPARENT
|
||||
GetDlgItem $R0 $R0 1043 ; description item (must be added to the UI)
|
||||
|
||||
[% block mouseover_messages %]
|
||||
StrCmp $0 ${sec_app} "" +2
|
||||
SendMessage $R0 ${WM_SETTEXT} 0 "STR:${PRODUCT_NAME}"
|
||||
|
||||
[% endblock mouseover_messages %]
|
||||
FunctionEnd
|
7
LICENSE
Normal file
7
LICENSE
Normal file
@ -0,0 +1,7 @@
|
||||
Copyright © 2018 "Institut Français en Hongrie"
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
12
README.md
Normal file
12
README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# IFPass
|
||||
|
||||
IFPass is a python project developped for the "Institut Français en Hongrie" and published under [MIT license](https://framagit.org/SecT0uch/IFPass/blob/master/LICENSE).
|
||||
It allows to manage a subscriber database and print member cards.
|
||||
|
||||
## Build
|
||||
|
||||
1. Install [NSIS](http://nsis.sourceforge.net/Download).
|
||||
2. Install python 3 and pip.
|
||||
3. Install the modules with `sudo -H pip install pynsist PyPDF2 termcolor`
|
||||
4. If pynsist version < 2.4, replace `/usr/lib/python3.*/site-packages/nsist/__init__.py` with https://raw.githubusercontent.com/takluyver/pynsist/master/nsist/__init__.py
|
||||
5. Run `./build.sh`
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
3
Templates/README.md
Normal file
3
Templates/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
Here you need two files :
|
||||
* IFPass_PDF_Template.pdf : Template of the card (both sides)
|
||||
* IFPass_PNG_Template.png : First side of the card (the one to fill up)
|
3
build.sh
Normal file
3
build.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/bash
|
||||
pynsist installer-x86.cfg
|
||||
pynsist installer-x64.cfg
|
BIN
build/x64/IFPass_3.2-x64.exe
Normal file
BIN
build/x64/IFPass_3.2-x64.exe
Normal file
Binary file not shown.
BIN
build/x86/IFPass_3.2-x86.exe
Normal file
BIN
build/x86/IFPass_3.2-x86.exe
Normal file
Binary file not shown.
59
installer-x64.cfg
Normal file
59
installer-x64.cfg
Normal file
@ -0,0 +1,59 @@
|
||||
[Application]
|
||||
name=IFPass
|
||||
version=3.2
|
||||
entry_point=IFPass:main
|
||||
icon=IF.ico
|
||||
console=true
|
||||
license_file=LICENSE
|
||||
|
||||
[Python]
|
||||
version=3.7.3
|
||||
bitness=64
|
||||
|
||||
[Include]
|
||||
# Packages from PyPI that your application requires, one per line
|
||||
# These must have wheels on PyPI:
|
||||
# https://pypi.org/project/code128/
|
||||
# https://pypi.org/project/colorama/
|
||||
# https://pypi.org/project/pyfiglet/
|
||||
# https://pypi.org/project/numpy/
|
||||
# https://pypi.org/project/opencv-python/
|
||||
# https://pypi.org/project/Pillow/
|
||||
# https://pypi.org/project/pywin32/
|
||||
# https://pypi.org/project/six/
|
||||
# https://pypi.org/project/setuptools/
|
||||
# https://pypi.org/project/PyMuPDF/
|
||||
# https://pypi.org/project/pywinauto/
|
||||
|
||||
pypi_wheels=code128==0.3
|
||||
colorama==0.4.1
|
||||
pyfiglet==0.8.post1
|
||||
numpy==1.16.4
|
||||
opencv-python==4.1.0.25
|
||||
Pillow==6.0.0
|
||||
pywin32==224
|
||||
six==1.12.0
|
||||
setuptools==41.0.1
|
||||
PyMuPDF==1.14.16
|
||||
pywinauto==0.6.6
|
||||
|
||||
# Must check if future updates of the following packages provide .whl files
|
||||
# Packages without wheels (Must be installed locally):
|
||||
packages=PyPDF2
|
||||
termcolor
|
||||
|
||||
# Other files and folders that should be installed
|
||||
files = LICENSE
|
||||
Templates
|
||||
|
||||
# This optional section adds a command which can be run from the Windows
|
||||
# command prompt.
|
||||
[Command IFPass]
|
||||
entry_point=IFPass:main
|
||||
|
||||
[Build]
|
||||
directory=build/x64
|
||||
installer_name=${PRODUCT_NAME}_${PRODUCT_VERSION}-x64.exe
|
||||
# Custom Installer :
|
||||
# Added Desktop shortcut, modified working directory, modified default install and utf-8...
|
||||
nsi_template=Installer_Template.nsi
|
59
installer-x86.cfg
Normal file
59
installer-x86.cfg
Normal file
@ -0,0 +1,59 @@
|
||||
[Application]
|
||||
name=IFPass
|
||||
version=3.2
|
||||
entry_point=IFPass:main
|
||||
icon=IF.ico
|
||||
console=true
|
||||
license_file=LICENSE
|
||||
|
||||
[Python]
|
||||
version=3.7.3
|
||||
bitness=32
|
||||
|
||||
[Include]
|
||||
# Packages from PyPI that your application requires, one per line
|
||||
# These must have wheels on PyPI:
|
||||
# https://pypi.org/project/code128/
|
||||
# https://pypi.org/project/colorama/
|
||||
# https://pypi.org/project/pyfiglet/
|
||||
# https://pypi.org/project/numpy/
|
||||
# https://pypi.org/project/opencv-python/
|
||||
# https://pypi.org/project/Pillow/
|
||||
# https://pypi.org/project/pywin32/
|
||||
# https://pypi.org/project/six/
|
||||
# https://pypi.org/project/setuptools/
|
||||
# https://pypi.org/project/PyMuPDF/
|
||||
# https://pypi.org/project/pywinauto/
|
||||
|
||||
pypi_wheels=code128==0.3
|
||||
colorama==0.4.1
|
||||
pyfiglet==0.8.post1
|
||||
numpy==1.16.4
|
||||
opencv-python==4.1.0.25
|
||||
Pillow==6.0.0
|
||||
pywin32==224
|
||||
six==1.12.0
|
||||
setuptools==41.0.1
|
||||
PyMuPDF==1.14.16
|
||||
pywinauto==0.6.6
|
||||
|
||||
# Must check if future updates of the following packages provide .whl files
|
||||
# Packages without wheels (Must be installed locally):
|
||||
packages=PyPDF2
|
||||
termcolor
|
||||
|
||||
# Other files and folders that should be installed
|
||||
files = LICENSE
|
||||
Templates
|
||||
|
||||
# This optional section adds a command which can be run from the Windows
|
||||
# command prompt.
|
||||
[Command IFPass]
|
||||
entry_point=IFPass:main
|
||||
|
||||
[Build]
|
||||
directory=build/x86
|
||||
installer_name=${PRODUCT_NAME}_${PRODUCT_VERSION}-x86.exe
|
||||
# Custom Installer :
|
||||
# Added Desktop shortcut, modified working directory, modified default install and utf-8...
|
||||
nsi_template=Installer_Template.nsi
|
Loading…
x
Reference in New Issue
Block a user