564 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			564 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!python3
 | 
						|
 | 
						|
# Written by Jordan ERNST Q1 2018.
 | 
						|
# Contact : pro.ernst@gmail.com
 | 
						|
 | 
						|
import configparser
 | 
						|
import sys
 | 
						|
import os
 | 
						|
import re
 | 
						|
from datetime import date, timedelta, datetime
 | 
						|
import csv
 | 
						|
import code128
 | 
						|
import cv2
 | 
						|
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, move
 | 
						|
from pyfiglet import Figlet
 | 
						|
from colorama import init
 | 
						|
from termcolor import colored
 | 
						|
 | 
						|
 | 
						|
version = '3.1-1'  # dev/devnocam
 | 
						|
 | 
						|
configdir = os.path.join(os.getenv('PROGRAMDATA'), 'IFPass')
 | 
						|
config = os.path.join(configdir, 'IFPass.conf')
 | 
						|
 | 
						|
 | 
						|
def initialisation():
 | 
						|
    conf = configparser.ConfigParser()
 | 
						|
    conf.optionxform = str                # For case sensitive config file
 | 
						|
 | 
						|
    if not os.path.exists(config):     # Check if config file exists
 | 
						|
        print('Fichier de configuration introuvable.')
 | 
						|
        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)
 | 
						|
        IFPassDBdir = conf['DEFAULT']['IFPassDBdir']
 | 
						|
        printername = conf['DEFAULT']['printername']
 | 
						|
        AcrobatReader = conf['DEFAULT']['AcrobatReader']
 | 
						|
 | 
						|
    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, 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"])
 | 
						|
    if not os.path.exists(templatesdir):
 | 
						|
        move('Templates', IFPassDBdir)
 | 
						|
 | 
						|
    return IFPassDBdir, printername, AcrobatReader, clientsfile, clientsbkpfile, imgdir, templatesdir, pdftemplate, pngtemplate, fonttemplate
 | 
						|
 | 
						|
 | 
						|
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("-")
 | 
						|
        firstname = firstname[:pos + 1] + firstname[pos + 1].upper() + \
 | 
						|
            firstname[pos + 2:]             # Check if compound name
 | 
						|
    if ' ' in firstname:
 | 
						|
        pos = firstname.find(" ")
 | 
						|
        firstname = firstname[:pos + 1] + firstname[pos + 1].upper() + \
 | 
						|
            firstname[pos + 2:]             # Check if compound name
 | 
						|
 | 
						|
    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.'
 | 
						|
        titrename = titre + ' ' + surname
 | 
						|
    else:
 | 
						|
        titre = ''
 | 
						|
        titrename = surname
 | 
						|
    return titre, firstname, surname, titrename
 | 
						|
 | 
						|
 | 
						|
def yes_or_no(question):
 | 
						|
    while "the answer is invalid":
 | 
						|
        reply = input(question + " O/N : ").lower().strip()
 | 
						|
        if reply[:1] in ['oui', 'ou', 'o']:
 | 
						|
            return True
 | 
						|
        if reply[:1] in ['non', 'no', 'n']:
 | 
						|
            return False
 | 
						|
 | 
						|
 | 
						|
def getclientID():
 | 
						|
    with open(clientsfile, 'r', newline='', encoding='utf-8') as csvfile:
 | 
						|
        lastline = csvfile.readlines()[-1]
 | 
						|
        lastID = lastline.split(';')[3]
 | 
						|
        if lastID == "Numéro de client":
 | 
						|
            clientID = "0000000001"
 | 
						|
        else:
 | 
						|
            clientID = str(int(lastID) + 1).zfill(10)
 | 
						|
 | 
						|
        return clientID
 | 
						|
 | 
						|
 | 
						|
def barcode_gen(clientID):
 | 
						|
    print("Génération du code barre...                  ", end='')
 | 
						|
    barcode = code128.image(clientID, thickness=4)    # .save(imgdir + clientID + '.png')
 | 
						|
    print(colored('[OK]', 'green'))
 | 
						|
    return barcode
 | 
						|
 | 
						|
 | 
						|
def getpic():
 | 
						|
    while True:
 | 
						|
        print("Prendre la photo...                          ", end='')
 | 
						|
        sys.stdout.flush()
 | 
						|
        cap = cv2.VideoCapture(0)
 | 
						|
        while True:                                 # Loop stream webcam
 | 
						|
            try:
 | 
						|
                ret, frame = cap.read()
 | 
						|
                cv2.rectangle(frame, (170, 73), (470, 407), (0, 255, 0), 2)
 | 
						|
                cv2.imshow('IFCamera - Touche Espace pour prendre la photo, Echap pour une carte sans photo, Q pour quitter.', frame)
 | 
						|
            except cv2.error:
 | 
						|
                print(colored('\nLa webcam est débranchée. Branchez-la, puis relancez le programme.', 'red'))
 | 
						|
                os.system("pause")
 | 
						|
                sys.exit()
 | 
						|
            SetForegroundWindow(find_window(title='IFCamera - Touche Espace '
 | 
						|
                                            '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(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()
 | 
						|
        cropped = frame[75:405, 172:468]
 | 
						|
        cv2.imshow('IFCamera - Espace pour valider, Echap pour modifier, Q pour quitter', cropped)
 | 
						|
        while True:
 | 
						|
            k = cv2.waitKey(1)
 | 
						|
            if k == 27:                        # Echap
 | 
						|
                print(colored('[KO]', 'red'))
 | 
						|
                cv2.destroyAllWindows()
 | 
						|
                break
 | 
						|
 | 
						|
            elif k & 0xFF == ord(' '):         # Space
 | 
						|
                print(colored('[OK]', 'green'))
 | 
						|
                cv2.destroyAllWindows()
 | 
						|
                # Color conversion and cv2 img to Pillow img
 | 
						|
                cropped = cv2.cvtColor(cropped, cv2.COLOR_BGR2RGB)
 | 
						|
                picture = Image.fromarray(cropped)
 | 
						|
                return picture
 | 
						|
 | 
						|
            elif k & 0xFF == ord('q'):   # Q or q to quit
 | 
						|
                cv2.destroyAllWindows()
 | 
						|
                sys.exit()
 | 
						|
 | 
						|
 | 
						|
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(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, 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, 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)
 | 
						|
 | 
						|
    # Barcode + picture embedding :
 | 
						|
    im.paste(barcode, (556, 460))
 | 
						|
 | 
						|
    if version != 'devnocam':
 | 
						|
        im.paste(picture, (47, 49))
 | 
						|
 | 
						|
    # Create PDF :
 | 
						|
    im = im.convert("RGB")
 | 
						|
    im.save(imgdir + clientID + '_Front.pdf', 'PDF', resolution=299.0, quality=98)
 | 
						|
 | 
						|
    print(colored('[OK]', 'green'))
 | 
						|
 | 
						|
 | 
						|
def mergepdf(clientID):
 | 
						|
    print("Fusion du recto et du verso de la carte...", end='')
 | 
						|
    cartefilename = os.path.join(imgdir, clientID + '.pdf')
 | 
						|
    output = PdfFileWriter()
 | 
						|
 | 
						|
    pdf1 = PdfFileReader(imgdir + clientID + '_Front.pdf', 'rb')
 | 
						|
    recto = pdf1.getPage(0)
 | 
						|
    output.addPage(recto)
 | 
						|
 | 
						|
    pdf2 = PdfFileReader(pdftemplate, 'rb')
 | 
						|
    verso = pdf2.getPage(1)
 | 
						|
    output.addPage(verso)
 | 
						|
 | 
						|
    with open(cartefilename, 'wb') as f:
 | 
						|
        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)
 | 
						|
 | 
						|
 | 
						|
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(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')
 | 
						|
    results = []
 | 
						|
 | 
						|
    for member in csvlist:
 | 
						|
        resfirstname = member[1].lower()
 | 
						|
        ressurname = member[2].lower()
 | 
						|
        resnumber = member[3]
 | 
						|
        if any(research in data for data in [resfirstname, ressurname, resnumber]):
 | 
						|
            results.append(member)
 | 
						|
 | 
						|
    if results:
 | 
						|
        if len(results) == 1:
 | 
						|
            member = results[0]
 | 
						|
        else:
 | 
						|
            print('-' * 56)
 | 
						|
            print(f'{"Choix":8} {"Prénom":15} {"Nom":15} {"Numéro de carte":15}')
 | 
						|
            print('-' * 56)
 | 
						|
            for index, result in enumerate(results, start=1):
 | 
						|
                print(f'{index:^8} {result[1]:15} {result[2]:15} {result[3]:^15}')
 | 
						|
            del member
 | 
						|
            while 'The choice is not valid':
 | 
						|
                try:
 | 
						|
                    memberchoice = input("De quel membre s'agit il ? (Colonne Choix) : ")
 | 
						|
                    member = results[int(memberchoice) - 1]
 | 
						|
                    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')
 | 
						|
 | 
						|
        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")
 | 
						|
 | 
						|
 | 
						|
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():
 | 
						|
    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()
 | 
						|
 | 
						|
        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("\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']))
 |