6 Commits
dev ... v2.5

Author SHA1 Message Date
ad748edc81 Merge branch 'dev' 2019-02-08 12:41:42 +01:00
66ae8f4196 updated installers version to 2.5 2019-02-08 11:50:23 +01:00
bf1f125da1 updated version to 2.5 2019-02-08 11:43:57 +01:00
da302a3cd5 Merge branch 'dev' 2019-02-08 11:40:33 +01:00
6333ce531d created build.sh to build x86 and x64 2019-02-07 18:04:48 +01:00
7585d09f41 add distribution files in master 2019-02-07 17:54:26 +01:00
7 changed files with 377 additions and 264 deletions

BIN
IF.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

346
IFPass.py
View File

@ -15,7 +15,6 @@ from pywinauto.findwindows import find_window
from pywinauto.win32functions import SetForegroundWindow from pywinauto.win32functions import SetForegroundWindow
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
from PyPDF2 import PdfFileReader, PdfFileWriter from PyPDF2 import PdfFileReader, PdfFileWriter
import fitz # = PyMuPDF : To convert pdf to png
import subprocess import subprocess
from shutil import copyfile, move from shutil import copyfile, move
from pyfiglet import Figlet from pyfiglet import Figlet
@ -23,7 +22,7 @@ from colorama import init
from termcolor import colored from termcolor import colored
version = '3.1-1' # dev/devnocam version = '2.5' # dev/devnocam
configdir = os.path.join(os.getenv('PROGRAMDATA'), 'IFPass') configdir = os.path.join(os.getenv('PROGRAMDATA'), 'IFPass')
config = os.path.join(configdir, 'IFPass.conf') config = os.path.join(configdir, 'IFPass.conf')
@ -86,20 +85,14 @@ def initialisation():
return IFPassDBdir, printername, AcrobatReader, clientsfile, clientsbkpfile, imgdir, templatesdir, pdftemplate, pngtemplate, fonttemplate return IFPassDBdir, printername, AcrobatReader, clientsfile, clientsbkpfile, imgdir, templatesdir, pdftemplate, pngtemplate, fonttemplate
def get_fullname(**kwargs): # **kwargs => Optionnal arguments def get_fullname():
if 'firstname' in kwargs: while "Empty firstname":
firstname = kwargs['firstname'] firstname = input("Prénom : ").strip()
newfirstname = input("Prénom (" + firstname + "): ").strip() if len(firstname) == 0:
if len(newfirstname) != 0: os.system('cls')
firstname = newfirstname print(colored("\nLe Prénom ne peut pas être vide.", 'red'))
else: else:
while "Empty firstname": break
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() firstname = firstname[0].upper() + firstname[1:].lower()
if '-' in firstname: if '-' in firstname:
pos = firstname.find("-") pos = firstname.find("-")
@ -109,29 +102,21 @@ def get_fullname(**kwargs): # **kwargs => Optionnal arguments
pos = firstname.find(" ") pos = firstname.find(" ")
firstname = firstname[:pos + 1] + firstname[pos + 1].upper() + \ firstname = firstname[:pos + 1] + firstname[pos + 1].upper() + \
firstname[pos + 2:] # Check if compound name firstname[pos + 2:] # Check if compound name
while "Empty surname":
if 'surname' in kwargs: surname = input("Nom : ").upper().strip()
surname = kwargs['surname'] if len(surname) == 0:
newsurname = input("Nom (" + surname + "): ").strip() os.system('cls')
if len(newsurname) != 0: print(colored("\nLe Nom ne peut pas être vide.", 'red'))
surname = newsurname else:
else: break
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 ?') docteur = yes_or_no('Est-ce un Docteur ?')
if docteur: if docteur:
titre = 'Dr.' titre = 'Dr.'
titrename = titre + ' ' + surname fullname = titre + ' ' + surname + ' ' + firstname
else: else:
titre = '' titre = ''
titrename = surname fullname = surname + ' ' + firstname
return titre, firstname, surname, titrename return titre, firstname, surname, fullname
def yes_or_no(question): def yes_or_no(question):
@ -152,6 +137,7 @@ def getclientID():
else: else:
clientID = str(int(lastID) + 1).zfill(10) clientID = str(int(lastID) + 1).zfill(10)
writeindb(clientID)
return clientID return clientID
@ -216,39 +202,20 @@ def getpic():
sys.exit() sys.exit()
def writeindb(titre, firstname, surname, clientID, dateinsc, dateexp, new): def writeindb(clientID):
if new is True: print("Ajout dans la base de données... ", end="")
print("Ajout dans la base de données... ", end="") with open(clientsfile, 'a', newline='', encoding='utf-8') as csvfile:
with open(clientsfile, 'a', newline='', encoding='utf-8') as csvfile: writer = csv.writer(csvfile, delimiter=';')
writer = csv.writer(csvfile, delimiter=';') writer.writerow([titre, firstname, surname, clientID, dateinsc, dateexp])
writer.writerow([titre, firstname, surname, clientID, dateinsc, dateexp]) print(colored('[OK]', 'green'))
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(): def bkpdb():
copyfile(clientsfile, clientsbkpfile) copyfile(clientsfile, clientsbkpfile)
def fillcard(clientID, titrename, firstname, dateexp, barcode, picture): def fillcard(barcode):
print("Création du verso de la carte avec les informations...", end='') print("Création de la carte avec les informations...", end='')
try: try:
im = Image.open(pngtemplate) im = Image.open(pngtemplate)
except FileNotFoundError: except FileNotFoundError:
@ -261,13 +228,12 @@ def fillcard(clientID, titrename, firstname, dateexp, barcode, picture):
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
# Name embedding : # Name embedding :
font = ImageFont.truetype(fonttemplate, 40) font = ImageFont.truetype(fonttemplate, 45)
draw.text((401, 296), titrename, fill=(0, 0, 0), font=font) draw.text((401, 310), fullname, fill=(0, 0, 0), font=font)
draw.text((401, 334), firstname, fill=(0, 0, 0), font=font)
# Date embedding : # Date embedding :
font = ImageFont.truetype(fonttemplate, 30) font = ImageFont.truetype(fonttemplate, 30)
draw.text((401, 400), dateexp, fill=(0, 0, 0), font=font) draw.text((401, 390), dateexp, fill=(0, 0, 0), font=font)
# ID embedding : # ID embedding :
font = ImageFont.truetype('arial.ttf', 30) font = ImageFont.truetype('arial.ttf', 30)
@ -286,8 +252,7 @@ def fillcard(clientID, titrename, firstname, dateexp, barcode, picture):
print(colored('[OK]', 'green')) print(colored('[OK]', 'green'))
def mergepdf(clientID): def mergepdf():
print("Fusion du recto et du verso de la carte...", end='')
cartefilename = os.path.join(imgdir, clientID + '.pdf') cartefilename = os.path.join(imgdir, clientID + '.pdf')
output = PdfFileWriter() output = PdfFileWriter()
@ -303,7 +268,6 @@ def mergepdf(clientID):
output.write(f) output.write(f)
os.remove(imgdir + clientID + '_Front.pdf') os.remove(imgdir + clientID + '_Front.pdf')
print(colored('[OK]', 'green'))
return cartefilename return cartefilename
@ -313,57 +277,10 @@ def printcard(cartefilename):
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(): def membersearch():
with open(clientsfile, 'r', newline='', encoding='utf-8') as csvfile: with open(clientsfile, 'r', newline='', encoding='utf-8') as csvfile:
reader = csv.reader(csvfile, delimiter=';') reader = csv.reader(csvfile, delimiter=';')
csvlist = list(map(list, reader)) csvlist = list(map(tuple, reader))
del csvlist[0] # We dele the first line (Prénom, Nom...) 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() research = input('Entrez une partie du nom, prénom, ou numéro de carte (ou flashez) : ').lower()
os.system('cls') os.system('cls')
@ -393,146 +310,29 @@ def membersearch():
break break
except (IndexError, ValueError): except (IndexError, ValueError):
print(colored('Choix invalide ! Veillez bien à sélectionner le numéro de la colonne "Choix"', 'red', attrs=['bold'])) print(colored('Choix invalide ! Veillez bien à sélectionner le numéro de la colonne "Choix"', 'red', attrs=['bold']))
os.system('cls') os.system('cls')
while 'Choix incorect': print("Titre : ", colored(member[0], 'green'))
print("Titre : ", colored(member[0], 'green')) print("Prénom : ", colored(member[1], 'green'))
print("Prénom : ", colored(member[1], 'green')) print("Nom : ", colored(member[2], 'green'))
print("Nom : ", colored(member[2], 'green')) print("Numéro de carte : ", colored(member[3], 'green'))
print("Numéro de carte : ", colored(member[3], 'green')) print("Date d'inscription :", member[4])
print("Date d'inscription :", member[4]) print("Date d'expiration : ", member[5])
print("Date d'expiration : ", member[5]) dateexp = datetime.strptime(member[5], '%d/%m/%Y').date()
dateexp = datetime.strptime(member[5], '%d/%m/%Y').date() diff = (dateexp - date.today()).days
diff = (dateexp - date.today()).days if diff > 0:
if diff > 0: print(colored(f"L'abonnement est encore valable {diff} jours.", 'green', attrs=['bold']))
print(colored(f"L'abonnement est encore valable {diff} jours.", 'green', attrs=['bold'])) elif diff < 0:
elif diff < 0: print(colored("L'abonnement est expiré depuis {abs(diff)} jours.", 'red', attrs=['bold'])) # abs() to remove minus sign
print(colored(f"L'abonnement est expiré depuis {abs(diff)} jours.", 'red', attrs=['bold'])) # abs() to remove minus sign elif diff == 0:
elif diff == 0: print(colored("Il s'agit du dernier jour de l'abonnement, il expirera demain.", 'yellow', attrs=['bold']))
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: else:
print(colored("Aucun membre n'a été trouvé.", 'red', attrs=['bold'])) print(colored("Aucun membre n'a été trouvé.", 'red', attrs=['bold']))
os.system("pause")
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')
if choix == '1': # Edit member
titre, firstname, surname, dateexp = memberedit(titre, firstname, surname, clientID, dateinsc, dateexp)
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')
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')
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))
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()
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))
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(): def main():
global IFPassDBdir, clientsfile, imgdir, clientsbkpfile, templatesdir, pngtemplate, fonttemplate, pdftemplate, printername, AcrobatReader global titre, firstname, surname, fullname, dateinsc, dateexp, clientID, clientsfile, IFPassDBdir, clientsfile, imgdir, clientsbkpfile, templatesdir, pngtemplate, fonttemplate, picture, pdftemplate, printername, AcrobatReader
while "The program is running": while "The program is running":
init() # Initialisation of colorama init() # Initialisation of colorama
IFPassDBdir, printername, AcrobatReader, clientsfile, clientsbkpfile, imgdir, templatesdir, pdftemplate, pngtemplate, fonttemplate = initialisation() IFPassDBdir, printername, AcrobatReader, clientsfile, clientsbkpfile, imgdir, templatesdir, pdftemplate, pngtemplate, fonttemplate = initialisation()
@ -543,19 +343,57 @@ def main():
print('Version : ', version) print('Version : ', version)
if version in ('dev', 'devnocam'): if version in ('dev', 'devnocam'):
print(colored("\nATTENTION : Il s'agit d'une version en cours de développement, potentiellement instable !", 'red')) 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("\nLe programme IFPass à été écrit par Jordan ERNST Q1 2018 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('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') print('1 - Nouveau membre', '2 - Rechercher un membre', '3 - Quitter', sep='\n')
choix = input('Choix : ') choix = input('Choix : ')
if choix == '1': if choix == '1':
newmember() while "the informations are incorrect": # Loop Filling informations
os.system('cls')
titre, firstname, surname, fullname = 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:
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')
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':
global picture
picture = getpic()
clientID = getclientID()
barcode = barcode_gen(clientID)
fillcard(barcode)
cartefilename = mergepdf()
if version not in ('dev', 'devnocam'):
bkpdb()
printcard(cartefilename)
break
elif choix == '2': elif choix == '2':
os.system('cls') os.system('cls')
membersearch() membersearch()
os.system("pause")
elif choix == '0': elif choix == '3':
sys.exit() sys.exit()
else: else:

189
Installer_Template.nsi Normal file
View 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

View File

@ -1,13 +1,4 @@
# IFPass # 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). IFPass is a python project developped for the "Institut Français en Hongrie" and published under MIT license.
It allows to manage a subscriber database and print member cards. 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`

3
build.sh Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/bash
pynsist installer-x86.cfg
pynsist installer-x64.cfg

46
installer-x64.cfg Normal file
View File

@ -0,0 +1,46 @@
[Application]
name=IFPass
version=2.5
entry_point=IFPass:main
icon=IF.ico
console=true
license_file=LICENSE
[Python]
version=3.7.1
bitness=64
[Include]
# Packages from PyPI that your application requires, one per line
# These must have wheels on PyPI:
pypi_wheels=code128==0.3
colorama==0.4.1
pyfiglet==0.8.post1
numpy==1.16.1
opencv-python==4.0.0.21
Pillow==5.4.1
pywin32==224
six==1.12.0
setuptools==40.7.3
# Must check if future updates of the following packages provide .whl files
# pywinauto needs to be downloaded manually and edit setup to match platform=win32
# Packages without wheels (Must be installed locally):
packages=PyPDF2
pywinauto
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

46
installer-x86.cfg Normal file
View File

@ -0,0 +1,46 @@
[Application]
name=IFPass
version=2.5
entry_point=IFPass:main
icon=IF.ico
console=true
license_file=LICENSE
[Python]
version=3.7.1
bitness=32
[Include]
# Packages from PyPI that your application requires, one per line
# These must have wheels on PyPI:
pypi_wheels=code128==0.3
colorama==0.4.1
pyfiglet==0.8.post1
numpy==1.16.1
opencv-python==4.0.0.21
Pillow==5.4.1
pywin32==224
six==1.12.0
setuptools==40.7.3
# Must check if future updates of the following packages provide .whl files
# pywinauto needs to be downloaded manually and edit setup to match platform=win32
# Packages without wheels (Must be installed locally):
packages=PyPDF2
pywinauto
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