Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
bb7d96e5e0 | |||
32300d81e4 | |||
cf625f5398 | |||
5cf50a04dd | |||
1dffdbeecd | |||
56ea8c83bc | |||
ad748edc81 | |||
66ae8f4196 | |||
bf1f125da1 | |||
da302a3cd5 | |||
6333ce531d | |||
7585d09f41 |
6
.gitignore
vendored
6
.gitignore
vendored
@ -5,4 +5,8 @@ Clients_IFPass_backup.csv
|
||||
IFPass.conf
|
||||
Templates/IFPass_PDF_Template.pdf
|
||||
Templates/IFPass_PNG_Template.png
|
||||
build
|
||||
build/x86/*
|
||||
build/x64/*
|
||||
# Except builds:
|
||||
!build/x86/*x86.exe
|
||||
!build/x64/*x64.exe
|
||||
|
49
IFPass.py
49
IFPass.py
@ -23,7 +23,7 @@ from colorama import init
|
||||
from termcolor import colored
|
||||
|
||||
|
||||
version = '3.1-1' # dev/devnocam
|
||||
version = '3.0' # dev/devnocam
|
||||
|
||||
configdir = os.path.join(os.getenv('PROGRAMDATA'), 'IFPass')
|
||||
config = os.path.join(configdir, 'IFPass.conf')
|
||||
@ -248,7 +248,7 @@ def bkpdb():
|
||||
|
||||
|
||||
def fillcard(clientID, titrename, firstname, dateexp, barcode, picture):
|
||||
print("Création du verso de la carte avec les informations...", end='')
|
||||
print("Création de la carte avec les informations...", end='')
|
||||
try:
|
||||
im = Image.open(pngtemplate)
|
||||
except FileNotFoundError:
|
||||
@ -287,7 +287,6 @@ def fillcard(clientID, titrename, firstname, dateexp, barcode, picture):
|
||||
|
||||
|
||||
def mergepdf(clientID):
|
||||
print("Fusion du recto et du verso de la carte...", end='')
|
||||
cartefilename = os.path.join(imgdir, clientID + '.pdf')
|
||||
output = PdfFileWriter()
|
||||
|
||||
@ -303,7 +302,6 @@ def mergepdf(clientID):
|
||||
output.write(f)
|
||||
|
||||
os.remove(imgdir + clientID + '_Front.pdf')
|
||||
print(colored('[OK]', 'green'))
|
||||
|
||||
return cartefilename
|
||||
|
||||
@ -313,17 +311,6 @@ def printcard(cartefilename):
|
||||
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')
|
||||
@ -335,7 +322,13 @@ def newmember():
|
||||
dateexp = dateexp.strftime('%d/%m/%Y')
|
||||
changeexp = yes_or_no("Voulez-vous choisir la date d'expiration ?")
|
||||
if changeexp:
|
||||
dateexp = 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')
|
||||
|
||||
os.system('cls')
|
||||
print("Titre : ", colored(titre, 'green'))
|
||||
@ -407,11 +400,11 @@ def membersearch():
|
||||
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
|
||||
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']))
|
||||
|
||||
print('\n1 - Modifier', "2 - Renouveller l'abonnement / Choisir un nouvelle date d'expiration", '3 - Imprimer la carte', '0 - Menu principal', sep='\n')
|
||||
print('\n1 - Modifier', "2 - Renouveller l'abonnement", '3 - Imprimer la carte', '0 - Menu principal', sep='\n')
|
||||
choix = input('Choix : ')
|
||||
if choix == '0':
|
||||
os.system('cls')
|
||||
@ -438,17 +431,13 @@ def memberdo(choix, 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')
|
||||
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
|
||||
@ -483,7 +472,6 @@ def memberdo(choix, member):
|
||||
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']))
|
||||
@ -544,7 +532,6 @@ def main():
|
||||
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 : ')
|
||||
|
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
|
11
README.md
11
README.md
@ -1,13 +1,4 @@
|
||||
# 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.
|
||||
|
||||
## 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
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.0-x64.exe
Normal file
BIN
build/x64/IFPass_3.0-x64.exe
Normal file
Binary file not shown.
BIN
build/x86/IFPass_3.0-x86.exe
Normal file
BIN
build/x86/IFPass_3.0-x86.exe
Normal file
Binary file not shown.
47
installer-x64.cfg
Normal file
47
installer-x64.cfg
Normal file
@ -0,0 +1,47 @@
|
||||
[Application]
|
||||
name=IFPass
|
||||
version=3.0
|
||||
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.2
|
||||
opencv-python==4.0.0.21
|
||||
Pillow==5.4.1
|
||||
pywin32==224
|
||||
six==1.12.0
|
||||
setuptools==40.8.0
|
||||
PyMuPDF==1.14.8
|
||||
pywinauto==0.6.6
|
||||
# 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
|
||||
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
|
47
installer-x86.cfg
Normal file
47
installer-x86.cfg
Normal file
@ -0,0 +1,47 @@
|
||||
[Application]
|
||||
name=IFPass
|
||||
version=3.0
|
||||
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.2
|
||||
opencv-python==4.0.0.21
|
||||
Pillow==5.4.1
|
||||
pywin32==224
|
||||
six==1.12.0
|
||||
setuptools==40.8.0
|
||||
PyMuPDF==1.14.8
|
||||
pywinauto==0.6.6
|
||||
# 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
|
||||
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
|
Reference in New Issue
Block a user