Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 15/11/2020, à 17:02

DonutMan75

Un script python pour générer des attestation Covid automatiquement

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 big_smile
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)

Hors ligne

#2 Le 15/11/2020, à 18:18

gl38

Re : Un script python pour générer des attestation Covid automatiquement

Si tu as un smartphone, c'est bien plus simple de remplir l'attestation directement dessus. En cochant la case "le téléphone se souvient de moi", il n'y a qu'à remplir l'heure et le motif et à télécharger.
Cordialement,
Guy

Hors ligne

#3 Le 15/11/2020, à 19:38

bluc

Re : Un script python pour générer des attestation Covid automatiquement

+1


Clevo :  Ubuntu 23.10   ❖  Xubuntu 22.10  ❖  Kubuntu 23.10   
         avec partition data commune       Une fraction de seconde                    Multiboot

Hors ligne

#4 Le 16/11/2020, à 22:03

HP

Re : Un script python pour générer des attestation Covid automatiquement

Si on a un téléphone, le top c'est çà : https://github.com/AdrienPoupa/AttestationDeplacement
Même pas besoin de connexion internet pour remplir une attestation… tout en local.


cat /dev/urandom >/dev/null 2>&1 #github

Hors ligne