commit cab6fb644d4c81e5f4371da6b5fa4507ba7bdd47 Author: Jordan ERNST Date: Thu Apr 12 14:32:42 2018 +0200 IFPass v1.0 uploaded diff --git a/IFPass.py b/IFPass.py new file mode 100644 index 0000000..d39a16f --- /dev/null +++ b/IFPass.py @@ -0,0 +1,283 @@ +#!/usr/bin/python3 + +# Written by Jordan ERNST Q1 2018. +# Contact : pro.ernst@gmail.com +# v1.0 : 23/03/2018 + +# https://www.pyimagesearch.com/2015/12/21/increasing-webcam-fps-with-python-and-opencv/ + +import sys +import os +import re +from contextlib import contextmanager # To hide output +from datetime import date, timedelta +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 subprocess +from shutil import copyfile +from pyfiglet import Figlet +from colorama import init +from termcolor import colored + + +version = '1.0' + +computer = '' # 'test', 'mediatheque' or 'accueil' + +if computer == 'test': + IFPassdir = '\\\\192.168.1.1\SSIC\\04-Projets\IFPass\\' +elif computer == 'mediatheque': + IFPassdir = '\\\\192.168.1.1\IFPass\\' + printername = ' XPS Pink Card Printer' +elif computer == 'accueil': + IFPassdir = '\\\\192.168.1.1\IFPass\\' + printername = ' XPS Blue Card Printer' +else: + print('La variable "computer" est mal définie.') + sys.exit() + +clientsfile = IFPassdir + 'Clients_IFPass.csv' +clientsbkpfile = IFPassdir + 'Clients_IFPass_bakup.csv' +imgdir = IFPassdir + 'Cartes\\' +pdftemplate = IFPassdir + 'Templates\IFPass_PDF_Template.pdf' +pngtemplate = IFPassdir + 'Templates\IFPass_PNG_Template.png' +fonttemplate = IFPassdir + 'Templates\Roboto-Bold.ttf' + + +@contextmanager +def HideOutput(to=os.devnull): + fd = sys.stdout.fileno() + + def _redirect_stdout(to): + sys.stdout.close() # + implicit flush() + os.dup2(to.fileno(), fd) # fd writes to 'to' file + sys.stdout = os.fdopen(fd, 'w') # Python writes to fd + + with os.fdopen(os.dup(fd), 'w') as old_stdout: + with open(to, 'w') as file: + _redirect_stdout(to=file) + try: + yield # allow code to be run with the redirected stdout + finally: + _redirect_stdout(to=old_stdout) # restore stdout. # cv2.selectROI + + +def get_fullname(): + firstname = input("Prénom : ").strip() + 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 + surname = input("Nom : ").upper().strip() + docteur = yes_or_no('Est-ce un Docteur ?') + if docteur: + titre = 'Dr.' + fullname = titre + ' ' + surname + ' ' + firstname + else: + titre = '' + fullname = surname + ' ' + firstname + return titre, firstname, surname, fullname + + +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) + + writeindb(clientID) + return clientID + + +def barcode_gen(clientID): + print("Génération du code barre... ", end='') + barcode = code128.image(clientID, thickness=4) # .save(imgdir + clientID + '.png') + 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('\nLa webcam est débranchée. Branchez-la, puis relancez le programme.') + os.system("pause") + sys.exit(0) + 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 + print(colored('[OK]', 'green')) + cv2.destroyAllWindows() + defaultpicture = IFPassdir + 'Templates\default_avatar.jpg' + picture = Image.open(defaultpicture) + return picture + elif k & 0xFF == ord(' '): # Space + break + elif k & 0xFF == ord('q'): # Q or q to quit + cap.release() + cv2.destroyAllWindows() + sys.exit() + cap.release() + cv2.destroyAllWindows() + cropped = frame[75:405, 172:468] + cv2.imshow('IFCamera - Espace pour valider, Echap pour modifier, Q pour quitter', cropped) + while True: + 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(clientID): + print("Ajout dans la base de données... ", end="") + with open(clientsfile, 'a', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=';') + writer.writerow([titre, firstname, surname, clientID, dateinsc, dateexp]) + print(colored('[OK]', 'green')) + + +def bkpdb(): + copyfile(clientsfile, clientsbkpfile) + + +def fillcard(barcode): + print("Création de la carte avec les informations...", end='') + im = Image.open(pngtemplate) + draw = ImageDraw.Draw(im) + + # Name embedding : + font = ImageFont.truetype(fonttemplate, 45) + draw.text((401, 310), fullname, fill=(0,0,0), font=font) + + # Date embedding : + font = ImageFont.truetype(fonttemplate, 30) + draw.text((401, 390), 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)) + 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(): + cartefilename = 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') + + return cartefilename + + +def printcard(cartefilename): + # CMD : "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" /h /n /t Carte.pdf "XPS Pink Card Printer" + subprocess.Popen('"C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" /h /n /t ' + cartefilename + printername, shell=False) + print('test') + + +while "the informations are incorrect": # Loop Filling informations + os.system('cls') + init() + f = Figlet(font='big') + print(colored(f.renderText('IFPass'), 'cyan', attrs=['bold'])) + print('Version :', version) + print('\nLe programme IFPass à été écrit par Jordan ERNST Q1 2018.') + print('Pour toute question ou problème contactez-moi à pro.ernst@gmail.com.\n') + titre, firstname, surname, fullname = get_fullname() + dateinsc = date.today() + dateexp = dateinsc + timedelta(days=365) + + 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') + picture = getpic() + clientID = getclientID() + barcode = barcode_gen(clientID) + fillcard(barcode) + cartefilename = mergepdf() + bkpdb() + if computer == 'mediatheque' or computer == 'accueil': + printcard(cartefilename)