Compare commits

..

40 Commits
v2.5 ... master

Author SHA1 Message Date
c18b49149f Add new builds 2019-06-20 16:39:50 +02:00
7016c2e665 Update version string 2019-06-20 16:32:26 +02:00
72d228de52 Update instructions in .cfg files 2019-06-20 16:31:44 +02:00
c31868d320 Update README to include build instructions 2019-06-20 16:30:58 +02:00
8a42245e4f Upgraded python and modules 2019-06-20 14:55:29 +02:00
655d61ea84 Merge branch 'dev' 2019-06-20 11:36:12 +02:00
b9561ef60f Del builds 2019-06-20 10:55:43 +02:00
962977774b Add licence information and link 2019-06-20 10:29:48 +02:00
0d94358f10 Print more informations about processing 2019-06-20 10:21:42 +02:00
461d969f92 Merge branch 'dev' 2019-04-02 17:22:49 +02:00
ff1a88c85b Fix print number of days since expired. 2019-04-02 17:22:06 +02:00
3e35e6fb05 New builds 2019-04-02 12:09:54 +02:00
48465446ec Increment version to 3.1-1 2019-04-02 12:05:21 +02:00
971bf846ab Merge branch 'dev' 2019-04-02 12:03:37 +02:00
d879cf389d Fixed bug change date 2019-04-02 12:03:07 +02:00
8138ebd95c Add builds 2019-03-25 09:49:35 +01:00
483d7e2f6f Fixed con files 2019-03-22 13:02:15 +01:00
e7f78e6e39 Increment version to 3.1 2019-03-22 12:51:33 +01:00
622ad63e0a Merge branch 'dev' 2019-03-22 12:27:09 +01:00
a93c05bcc3 Allow to choose date manually 2019-03-22 12:23:55 +01:00
029f0c1396 Update binaries to 3.0-1 2019-03-05 14:39:00 +01:00
e19a9b5820 Remove previous builds 2019-03-05 14:26:05 +01:00
7513a2d2fb Increment version to 3.0-1 2019-03-05 13:30:17 +01:00
dcb4caacc6 Correct bug print card 2019-03-05 13:29:37 +01:00
bb7d96e5e0 Include builds 2019-03-05 10:23:08 +01:00
32300d81e4 Updates depenencies 2019-03-05 10:16:37 +01:00
cf625f5398 Edit version 2019-03-05 09:42:57 +01:00
5cf50a04dd Merge branch 'dev' 2019-03-05 09:40:29 +01:00
ad2c7de563 Edit desc 2019-03-05 09:39:17 +01:00
9ab362fd29 Bugs corrections 2019-03-05 09:33:27 +01:00
5d76b1f584 Renew membership implementation + Multiple fixes. 2019-03-04 17:36:01 +01:00
a1beec5cd1 Fix various bugs 2019-03-01 15:19:40 +01:00
f3f86c43a6 Member edit implementation done. Recover previous picture added. 2019-03-01 14:52:13 +01:00
1dffdbeecd Added PyMuPDF dependency 2019-03-01 11:09:18 +01:00
a500e22678 Corrections 2019-02-28 16:31:11 +01:00
3dbb48d7fc Added modif line in writeindb() for member modification 2019-02-28 15:50:07 +01:00
d651a4973a Edit member ongoing 2019-02-28 09:25:06 +01:00
0ce5ed334c Code reformatting : function newmember() 2019-02-27 12:34:36 +01:00
d5c4ee5997 Name now on to lines. 2019-02-20 17:17:45 +01:00
56ea8c83bc Add exception .gitignore for builds 2019-02-20 15:04:06 +01:00
7 changed files with 310 additions and 110 deletions

6
.gitignore vendored
View File

@ -5,4 +5,8 @@ Clients_IFPass_backup.csv
IFPass.conf IFPass.conf
Templates/IFPass_PDF_Template.pdf Templates/IFPass_PDF_Template.pdf
Templates/IFPass_PNG_Template.png Templates/IFPass_PNG_Template.png
build build/x86/*
build/x64/*
# Except builds:
!build/x86/*x86.exe
!build/x64/*x64.exe

346
IFPass.py
View File

@ -15,6 +15,7 @@ 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
@ -22,7 +23,7 @@ from colorama import init
from termcolor import colored from termcolor import colored
version = '2.5' # dev/devnocam version = '3.2' # 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')
@ -85,14 +86,20 @@ 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(): def get_fullname(**kwargs): # **kwargs => Optionnal arguments
while "Empty firstname": if 'firstname' in kwargs:
firstname = input("Prénom : ").strip() firstname = kwargs['firstname']
if len(firstname) == 0: newfirstname = input("Prénom (" + firstname + "): ").strip()
os.system('cls') if len(newfirstname) != 0:
print(colored("\nLe Prénom ne peut pas être vide.", 'red')) firstname = newfirstname
else: else:
break 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() firstname = firstname[0].upper() + firstname[1:].lower()
if '-' in firstname: if '-' in firstname:
pos = firstname.find("-") pos = firstname.find("-")
@ -102,21 +109,29 @@ def get_fullname():
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":
surname = input("Nom : ").upper().strip() if 'surname' in kwargs:
if len(surname) == 0: surname = kwargs['surname']
os.system('cls') newsurname = input("Nom (" + surname + "): ").strip()
print(colored("\nLe Nom ne peut pas être vide.", 'red')) if len(newsurname) != 0:
else: surname = newsurname
break 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 ?') docteur = yes_or_no('Est-ce un Docteur ?')
if docteur: if docteur:
titre = 'Dr.' titre = 'Dr.'
fullname = titre + ' ' + surname + ' ' + firstname titrename = titre + ' ' + surname
else: else:
titre = '' titre = ''
fullname = surname + ' ' + firstname titrename = surname
return titre, firstname, surname, fullname return titre, firstname, surname, titrename
def yes_or_no(question): def yes_or_no(question):
@ -137,7 +152,6 @@ def getclientID():
else: else:
clientID = str(int(lastID) + 1).zfill(10) clientID = str(int(lastID) + 1).zfill(10)
writeindb(clientID)
return clientID return clientID
@ -202,20 +216,39 @@ def getpic():
sys.exit() sys.exit()
def writeindb(clientID): def writeindb(titre, firstname, surname, clientID, dateinsc, dateexp, new):
print("Ajout dans la base de données... ", end="") if new is True:
with open(clientsfile, 'a', newline='', encoding='utf-8') as csvfile: print("Ajout dans la base de données... ", end="")
writer = csv.writer(csvfile, delimiter=';') with open(clientsfile, 'a', newline='', encoding='utf-8') as csvfile:
writer.writerow([titre, firstname, surname, clientID, dateinsc, dateexp]) writer = csv.writer(csvfile, delimiter=';')
print(colored('[OK]', 'green')) 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(): def bkpdb():
copyfile(clientsfile, clientsbkpfile) copyfile(clientsfile, clientsbkpfile)
def fillcard(barcode): def fillcard(clientID, titrename, firstname, dateexp, barcode, picture):
print("Création de la carte avec les informations...", end='') print("Création du verso de la carte avec les informations...", end='')
try: try:
im = Image.open(pngtemplate) im = Image.open(pngtemplate)
except FileNotFoundError: except FileNotFoundError:
@ -228,12 +261,13 @@ def fillcard(barcode):
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
# Name embedding : # Name embedding :
font = ImageFont.truetype(fonttemplate, 45) font = ImageFont.truetype(fonttemplate, 40)
draw.text((401, 310), fullname, fill=(0, 0, 0), font=font) draw.text((401, 296), titrename, 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, 390), dateexp, fill=(0, 0, 0), font=font) draw.text((401, 400), dateexp, fill=(0, 0, 0), font=font)
# ID embedding : # ID embedding :
font = ImageFont.truetype('arial.ttf', 30) font = ImageFont.truetype('arial.ttf', 30)
@ -252,7 +286,8 @@ def fillcard(barcode):
print(colored('[OK]', 'green')) 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') cartefilename = os.path.join(imgdir, clientID + '.pdf')
output = PdfFileWriter() output = PdfFileWriter()
@ -268,6 +303,7 @@ def mergepdf():
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
@ -277,10 +313,57 @@ 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(tuple, reader)) csvlist = list(map(list, 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')
@ -310,29 +393,146 @@ 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')
print("Titre : ", colored(member[0], 'green')) while 'Choix incorect':
print("Prénom : ", colored(member[1], 'green')) print("Titre : ", colored(member[0], 'green'))
print("Nom : ", colored(member[2], 'green')) print("Prénom : ", colored(member[1], 'green'))
print("Numéro de carte : ", colored(member[3], 'green')) print("Nom : ", colored(member[2], 'green'))
print("Date d'inscription :", member[4]) print("Numéro de carte : ", colored(member[3], 'green'))
print("Date d'expiration : ", member[5]) print("Date d'inscription :", member[4])
dateexp = datetime.strptime(member[5], '%d/%m/%Y').date() print("Date d'expiration : ", member[5])
diff = (dateexp - date.today()).days dateexp = datetime.strptime(member[5], '%d/%m/%Y').date()
if diff > 0: diff = (dateexp - date.today()).days
print(colored(f"L'abonnement est encore valable {diff} jours.", 'green', attrs=['bold'])) if diff > 0:
elif diff < 0: print(colored(f"L'abonnement est encore valable {diff} jours.", 'green', attrs=['bold']))
print(colored("L'abonnement est expiré depuis {abs(diff)} jours.", 'red', attrs=['bold'])) # abs() to remove minus sign elif diff < 0:
elif diff == 0: print(colored(f"L'abonnement est expiré depuis {abs(diff)} jours.", 'red', attrs=['bold'])) # abs() to remove minus sign
print(colored("Il s'agit du dernier jour de l'abonnement, il expirera demain.", 'yellow', attrs=['bold'])) 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: 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 titre, firstname, surname, fullname, dateinsc, dateexp, clientID, clientsfile, IFPassDBdir, clientsfile, imgdir, clientsbkpfile, templatesdir, pngtemplate, fonttemplate, picture, pdftemplate, printername, AcrobatReader global IFPassDBdir, clientsfile, imgdir, clientsbkpfile, templatesdir, pngtemplate, fonttemplate, 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()
@ -343,57 +543,19 @@ 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("\nLe programme IFPass à été écrit par Jordan ERNST Q1 2018 pour l'Institut Français en Hongrie.") 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('Pour toute question, problème ou requête contactez-moi à pro.ernst@gmail.com.\n')
print('1 - Nouveau membre', '2 - Rechercher un membre', '3 - Quitter', sep='\n') print('1 - Nouveau membre', '2 - Rechercher un membre', '0 - Quitter', sep='\n')
choix = input('Choix : ') choix = input('Choix : ')
if choix == '1': if choix == '1':
while "the informations are incorrect": # Loop Filling informations newmember()
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 == '3': elif choix == '0':
sys.exit() sys.exit()
else: else:

View File

@ -1,4 +1,12 @@
# IFPass # IFPass
IFPass is a python project developped for the "Institut Français en Hongrie" and published under MIT license. 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. 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.

View File

@ -1,32 +1,45 @@
[Application] [Application]
name=IFPass name=IFPass
version=2.5 version=3.2
entry_point=IFPass:main entry_point=IFPass:main
icon=IF.ico icon=IF.ico
console=true console=true
license_file=LICENSE license_file=LICENSE
[Python] [Python]
version=3.7.1 version=3.7.3
bitness=64 bitness=64
[Include] [Include]
# Packages from PyPI that your application requires, one per line # Packages from PyPI that your application requires, one per line
# These must have wheels on PyPI: # 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 pypi_wheels=code128==0.3
colorama==0.4.1 colorama==0.4.1
pyfiglet==0.8.post1 pyfiglet==0.8.post1
numpy==1.16.1 numpy==1.16.4
opencv-python==4.0.0.21 opencv-python==4.1.0.25
Pillow==5.4.1 Pillow==6.0.0
pywin32==224 pywin32==224
six==1.12.0 six==1.12.0
setuptools==40.7.3 setuptools==41.0.1
PyMuPDF==1.14.16
pywinauto==0.6.6
# Must check if future updates of the following packages provide .whl files # 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 without wheels (Must be installed locally):
packages=PyPDF2 packages=PyPDF2
pywinauto
termcolor termcolor
# Other files and folders that should be installed # Other files and folders that should be installed

View File

@ -1,32 +1,45 @@
[Application] [Application]
name=IFPass name=IFPass
version=2.5 version=3.2
entry_point=IFPass:main entry_point=IFPass:main
icon=IF.ico icon=IF.ico
console=true console=true
license_file=LICENSE license_file=LICENSE
[Python] [Python]
version=3.7.1 version=3.7.3
bitness=32 bitness=32
[Include] [Include]
# Packages from PyPI that your application requires, one per line # Packages from PyPI that your application requires, one per line
# These must have wheels on PyPI: # 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 pypi_wheels=code128==0.3
colorama==0.4.1 colorama==0.4.1
pyfiglet==0.8.post1 pyfiglet==0.8.post1
numpy==1.16.1 numpy==1.16.4
opencv-python==4.0.0.21 opencv-python==4.1.0.25
Pillow==5.4.1 Pillow==6.0.0
pywin32==224 pywin32==224
six==1.12.0 six==1.12.0
setuptools==40.7.3 setuptools==41.0.1
PyMuPDF==1.14.16
pywinauto==0.6.6
# Must check if future updates of the following packages provide .whl files # 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 without wheels (Must be installed locally):
packages=PyPDF2 packages=PyPDF2
pywinauto
termcolor termcolor
# Other files and folders that should be installed # Other files and folders that should be installed