#!/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)