Bonjour la communauté,
j'ai remarqué qu'il était souvent fastidieux de remplir les attestations Covid :
1- remplir toujours les mêmes champs à la main ? long et fastidieux
2- passer par
le site du gouvernement depuis son smartphone ? pénible sur smartphone, je trouve
3- passer par une application tierce ? On ne sait pas ce que nos données deviennent !
Mon script s'appelle ainsi :
$ ./covid.py -u dm -m 3 -t "16h30"
Ceci va créer une attestation auto-rempli pour l'utilisateur "dm" avec le 3eme motif de déplacement avec comme heure de départ 16h30
Si on omet -u, l'utilisateur est dm
Si on omet -m, le motif est "promenade"
Si on omet -t, l'heure de départ est l'heure actuelle + 5 minutes
Les numéros de motif s'obtiennent via l'aide
$ ./covid.py -h
usage: covid.py [-h] [-u USER] [-m MOTIF] [-t HOUR]
Create a french Covid attestation
optional arguments:
-h, --help show this help message and exit
-u USER, --user USER select an user (default : dm)
-m MOTIF, --motif MOTIF
select a motif (default : 6)
-t HOUR, --time HOUR select a starting hours (e.g 14h07, default : current time + 5 minutes)
MOTIF can be :
1 -> travail
2 -> achats / retrait commande
3 -> consultations médicales, pharmacie
4 -> motif familial impérieux, garde d'enfants
5 -> handicap
6 -> promenade
7 -> convocation judiciaire
8 -> missions d'intérêt général
9 -> école enfants et activités périscolaires
That's all folks
Le script va :
1 - remplir les différents champs à renseigner
2 - cocher la bonne case
3 - ajouter une signature en bas à gauche si un fichier est spécifié, sinon on laisse vide (comme c'est le cas via le site du gouvernement)
4 - générer et placer les QR Code avec un contenu identique à ceux générés par le site du gouvernement
5 - générer le pdf final
Dépendances (hors librairie standard de python):
$ pip install pymupdf # manipulation de pdf
$ pip install qrcode # création de QR Code
Il faut aussi disposer d'une attestation vierge (par défaut stockée dans ./template/attestation.pdf)
Voici mon script ci-dessous. Je suis débutant en python, donc je suis preneur de toutes remarques constructives 😃
Idéalement, j'aurais aimer ajouter une dernière étape avec envoi par mail de l'attestation sur mon smartphone... mais ça a l'air un peu plus compliqué que prévu..
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import fitz
import datetime
from time import strftime
import qrcode
import re
## CONSTANTS DEFINITION
# file location
f_pdf = "./template/attestation.pdf"
f_qr = "./out/qr.png"
f_att = "./out/attestation.pdf"
# siganture position
h = 70; w = 80;
x0 = 130; y0 = 695; # Coin supérieur gauche
sig_pos = fitz.Rect(x0, y0, x0+w, y0+h)
# qr_code_1 position
h = 100; w = 100;
x0 = 430; y0 = 640; # Coin supérieur gauche
qr1_pos = fitz.Rect(x0, y0, x0+w, y0+h)
# qr_code_2 position
h = 350; w = 350;
x0 = 30; y0 = 30; # Coin supérieur gauche
qr2_pos = fitz.Rect(x0, y0, x0+w, y0+h)
# Position de la croix
x_croix = 83
y_croix_list = (265, 310, 366, 407, 448, 486, 549, 588, 633);
# y_croix_list = {
# "travail":265,
# "achats":310,
# "sante":366,
# "famille":407,
# "handicap":448,
# "sport_animaux":486,
# "convocation":549,
# "missions":588,
# "enfants":633}
# Position du texte
pos_text = {
"nom":(120, 146),
"naiss":(120, 168),
"lieu":(310, 168),
"addr":(135, 190),
"faita":(115, 666),
"date":(100, 689),
"heure":(260, 689)}
# Motif du qr code
qr_motif= (
'travail',
'achats',
'sante',
'famille',
'handicap',
'sport_animaux',
'convocation',
'missions',
'enfants')
# Base de données des utilisateurs
personnes = {
"dm":{
"prenom" : "Donut",
"nom" : "Man",
"date_naiss" : "01/01/1970",
"lieu_naiss" : "Donut City",
"adresse" : "1 rue du Donut, Donut City",
"faita" : "Donut City",
"signature" : "./template/dm_sig.png"
},
"dw":{
"prenom" : "Donut",
"nom" : "Woman",
"date_naiss" : "01/01/1975",
"lieu_naiss" : "Donut Town",
"adresse" : "1 rue du Donut, Donut City",
"faita" : "Donut City",
"signature" : None
},
}
## CODE PROPREMENT DIT
# Argparse
parser = argparse.ArgumentParser(
formatter_class=argparse.RawTextHelpFormatter, # multi-lines help
description='Create a french Covid attestation',
epilog="""
MOTIF can be :
1 -> travail
2 -> achats / retrait commande
3 -> consultations médicales, pharmacie
4 -> motif familial impérieux, garde d'enfants
5 -> handicap
6 -> promenade
7 -> convocation judiciaire
8 -> missions d'intérêt général
9 -> école enfants et activités périscolaires
That's all folks""")
parser.add_argument('-u', '--user', dest='user', action='store', default='dm',
metavar="USER", type=str,
help='select an user (default : dm)')
parser.add_argument('-m', '--motif', dest='motif', action='store', default=6,
metavar="MOTIF", type=int,
help='select a motif (default : 6)')
parser.add_argument('-t', '--time', dest='hour', action='store', default=None,
metavar="HOUR", type=str,
help='select a starting hours (e.g 14h07, default : current time + 5 minutes)')
# On parse les arguments
args = parser.parse_args()
user = args.user;
motif = args.motif;
if motif < 1 or motif > 9:
print("[Error] motif should be between 1 and 9 (got %d)" % motif)
exit(1)
if args.hour:
if not re.match('[0-9]{2}h[0-9]{2}', args.hour):
print("[Error] hour should match '[0-9]{2}h[0-9]{2}' (got %s)" % args.hour)
exit(1)
p = personnes.get(user)
if not p:
print("[Error] user %s does not exist..." % user)
exit(1)
# date de création
t = datetime.datetime.now()
# ajout d'une marge sur la datation du pdf
delta_t = datetime.timedelta(minutes=5)
# extraction des str liees au temps
t_day_create = t.strftime("%d/%m/%Y")
t_hour_create = t.strftime("%Hh%M")
t_day = (t + delta_t).strftime("%d/%m/%Y")
t_hour = (t + delta_t).strftime("%Hh%M")
if args.hour:
t_hour = args.hour
y_croix = y_croix_list[motif-1]
f_sig = p["signature"]
# Print what will be done...
print("Creating user %s with motif %d" % (user, motif) )
for clef, value in p.items():
print(' - %s \t: %s' % (clef, value))
print(' - Time \t: %s %s' % (t_day, t_hour))
print(' - Motif \t: %s' % qr_motif[motif-1])
# Création du QR Code
qr_text = '''
Cree le: %s a %s;
Nom: %s;
Prenom: %s;
Naissance: %s a %s;
Adresse: %s;
Sortie: %s a %s;
Motifs: %s''' % (t_day_create, t_hour_create, p["nom"], p["prenom"], p["date_naiss"], p["lieu_naiss"], p["adresse"], t_day, t_hour, qr_motif[motif-1])
img = qrcode.make(qr_text)
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(qr_text)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
img.save(f_qr)
# Ouverture du pdf
doc = fitz.open(f_pdf)
page2 = doc.newPage(pno=-1, width=595, height=842); # Seconde page avec le qrcode en gros
page = doc.loadPage(0)
# Champs texte haut
page.insertText(
point=(pos_text["nom"][0], pos_text["nom"][1]),
text=p["prenom"] + " " + p["nom"],
fontsize=12,
color=[0, 0, 0],
overlay=True)
page.insertText(
point=(pos_text["naiss"][0], pos_text["naiss"][1]),
text=p["date_naiss"],
fontsize=12,
color=[0, 0, 0],
overlay=True)
page.insertText(
point=(pos_text["lieu"][0], pos_text["lieu"][1]),
text=p["lieu_naiss"],
fontsize=12,
color=[0, 0, 0],
overlay=True)
page.insertText(
point=(pos_text["addr"][0], pos_text["addr"][1]),
text=p["adresse"],
fontsize=12,
color=[0, 0, 0],
overlay=True)
# Croix case a cocher
page.insertText(
point=(x_croix, y_croix),
text="X",
fontsize=16,
color=[0, 0, 0],
overlay=True)
# Champs texte bas
page.insertText(
point=(pos_text["faita"][0], pos_text["faita"][1]),
text=p["faita"],
fontsize=12,
color=[0, 0, 0],
overlay=True)
page.insertText(
point=(pos_text["date"][0], pos_text["date"][1]),
text=t_day,
fontsize=12,
color=[0, 0, 0],
overlay=True)
page.insertText(
point=(pos_text["heure"][0], pos_text["heure"][1]),
text=t_hour,
fontsize=12,
color=[0, 0, 0],
overlay=True)
# Signature (if any)
if f_sig:
page.insertImage(sig_pos, f_sig)
# QR Code page 1
page.insertImage(qr1_pos, f_qr)
# QR Code page 2
page2.insertImage(qr2_pos, f_qr)
# Sauvegarde du pdf
doc.save(f_att)