Greboca  

Suport technique et veille technologique

Aujourd’hui, les grandes entreprises et administrations publiques hésitent entre continuer à utiliser des logiciels propriétaires ou basculer vers les Logiciels Libres. Pourtant, la plupart des logiciels libres sont capables de bien traiter les données issues des logiciels propriétaire, et parfois avec une meilleur compatibilité.

C’est alors la barrière de la prise en main qui fait peur, et pourtant...

Les logiciels libres

L’aspect « Logiciel Libre » permet une évolution rapide et une plus grande participation des utilisateurs. Les aides et tutoriels foisonnent sur Internet ou sont directement inclus dans le logiciel lui-même.

Enfin, les concepteurs sont plus proches des utilisateurs, ce qui rend les logiciels libres plus agréable à utiliser et conviviaux.

Grâce à la disponibilité des logiciels libres, vous trouverez facilement des services de support techniques et la licence n’est plus un frein à l’utilisation de ces logiciels par votre personnel.

Notre support technique concerne essentiellement les logiciels libres, que ce soit sous forme de services ponctuels ou de tutoriels.

LinuxFr.org : les journaux  -  Avis et décisions CADA et génération d'un gros PDF

 -  Mai 2023 - 

Sommaire

En France, la CADA ou Commission d’accès aux documents administratifs est une autorité administrative indépendante qui a pour objectif de faciliter et contrôler l’accès des particuliers aux documents administratifs. Et Wikipédia ajoute : elle « émet des conseils quand elle est saisie par une administration, mais son activité principale est de fournir des avis aux particuliers qui se heurtent au refus d’une administration de communiquer un ou plusieurs documents qu’elle détient. »

Note 1: en Belgique aussi il existe une CADA, mais je serais bien en peine d’évoquer les similitudes ou différences. Ce travail est laissé aux commentaires :).

Note 2: ne pas confondre avec un autre CADA français qui n’a pas de rapport

Contexte (mi CADA su CADA)

On m’a récemment demandé un coup de main pour pouvoir faire des recherches dans les avis et conseils CADA publiés. Sur data.gouv.fr, on peut trouver tout cela en fichier CSV, et sinon il est possible d’utiliser l'API de la CADA pour faire des recherches. Mais bon ouvrir un fichier CSV de plusieurs centaines de MiB et des dizaines de milliers de lignes dont des cellules de plusieurs écrans, ça peut être compliqué ou peu lisible pour le commun des mortels. Et puis tout le monde ne sait pas utiliser une API (ou gérer l’Unicode dans les résultats ou les requêtes ou… n’a pas envie d’avoir besoin d’un accès Internet permanent pour cela).

Bref coup de téléphone, question « est-ce que c’est compliqué de produire un PDF à partir d’un CSV ? », évaluation mentale hyperprécise de développeur débutant en Python « tranquille, 5 min » et réponse « oui, j’essaie de te faire ça ce week-end ».

Yapuka (ou abraCADAbra)

Je vais sur le site data.gouv.fr, je vois 1 fichier principal, 49 mises à jour. Je télécharge donc 50 fichiers. Bon, première erreur, il faut comprendre « mises à jour » du même jeu de données, bref la dernière version contient tout.

Au final je vais pondre ce code Python qui lit un CSV et produit du Markdown, en validant un peu ce qui passe à tout hasard.

La fonction display indique ce qu’on trouve dans le CSV (selon l’entête de chaque CSV).
La fonction markdown sort de façon basique du Markdown à partir de ça (ma stratégie de saut de page n’a pas marché, mais je dirais tant mieux vu le nombre de pages en sortie…).
La fonction validate me donne une idée de ce que je traite et si jamais il y a des surprises sur une prochaine mise à jour des données. J’ai notamment été surpris par le nombre de champs pouvant être vides.
Et côté main de quoi gérer un offset/limit à la SQL, pour ne pas tout traiter en une fois (cf la suite de ce journal).

Anecdote : j’ouvre un CSV au pif pour avoir un exemple, et je tombe direct sur une décision concernant ma ville de naissance.

Bref, voici le code Python mi-anglais mi-français mi-sérable :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import csv
from datetime import datetime

numero_de_dossier = ''
administration = ''
type_donnee = ''
annee = ''
seance = ''
objet = ''
theme = ''
mots_cles = ''
sens_motivation = ''
partie = ''
avis = ''


def display(row):
    for i in ["Numéro de dossier", "Administration", "Type", "Année", "Séance",
              "Objet", "Thème et sous thème", "Mots clés",
              "Sens et motivation", "Partie", "Avis"]:
        print(f"{i} : {row[i]}")


def markdown(row):
    print(f"\n# Dossier {row['Numéro de dossier']}\n")
    for i in ["Administration", "Type", "Année", "Séance",
              "Objet", "Thème et sous thème", "Mots clés",
              "Sens et motivation", "Partie", "Avis"]:
        print(f"**{i} :** {row[i]}")
    print("\n\\newpage\n")


def validate(row):
    assert len(row['Numéro de dossier']) == 8
    annee_dossier = int(row['Numéro de dossier'][0:4])
    assert annee_dossier <= datetime.now().year and annee_dossier >= 1984
    assert int(row['Numéro de dossier'][4:8])
    # row['Administration'] can be empty
    assert row['Type'] in ['Avis', 'Conseil', 'Sanction']
    if row['Année'] != '':
        annee = int(row['Année'])
        assert annee <= datetime.now().year and annee >= 1984
    datetime.strptime(row['Séance'], '%d/%m/%Y').date()
    # row['Objet'] can be empty
    # row['Thème et sous thème'] can be empty
    # row['Mots clés'] can be empty
    # row['Sens et motivation'] can be empty
    # row['Partie'] can be empty
    # row['Avis'] can be empty


def main():
    parser = argparse.ArgumentParser(description="Avis et conseils CADA")
    parser.add_argument("--csv", type=str, required=True, help="export.csv")
    parser.add_argument("--limit", type=int, required=False,
                        help="nb de dossiers à traiter en partant de l'offset",
                        default=1000000)
    parser.add_argument("--offset", type=int, required=False,
                        help="position du premier dossier à traiter",
                        default=0)
    args = parser.parse_args()

    export = args.csv

    entries_input = 0
    entries_output = 0
    with open(export, newline='') as csvfile:
        reader = csv.DictReader(csvfile, delimiter=',')
        for row in reader:
            # display(row)
            validate(row)
            if entries_input >= args.offset:
                markdown(row)
                entries_output += 1
                if entries_output >= args.limit:
                    return
            entries_input += 1


if __name__ == '__main__':
    main()

et un bout de code bash pour lancer tout ça (la boucle for inutile date de mon erreur de traiter les 50 fichiers CSV au lieu d’un…) : on vérifie le code Python, et ensuite on produit des Markdown de 10000 enregistrements et les PDF associés.

#!/bin/bash

set -e
flake8 cada.py

mkdir -p markdown pdf
for csv in data.gouv.fr/cada-2023-04-12.csv
do
  base=$(basename "$csv" ".csv")
  limit=10000
  #TODO no check 50000+limit < real total
  for nb in $(seq 0 $limit 50000)
  do
    md="markdown/${base}_${nb}.md"
    ./cada.py --csv "$csv" --limit $limit --offset $nb > "$md"
    pdf="pdf/${base}_${nb}.pdf"
    pandoc "$md" -o "$pdf" --pdf-engine=weasyprint --metadata title="cada-2023-04-12 ($nb)"
  done
done

Entrées/sorties (petite CADAstrophe)

Le fichier cada-2023-04-12.csv contient 50639 enregistrements et fait déjà 156 MiB.
Chaque fichier Markdown de 10 000 enregistrements fait environ 30 MiB.
Chaque PDF fait de 40 à 50 MiB.
La découpe par 10 000 est due à une raison assez simple : la machine utilisée a saturé ses GiB de RAM (après prélèvement du noyau et autres), swappé, ramé sévèrement, et la génération du PDF a été tuée par le OutOfMemory-killer (oom-killer) du noyau.

kernel: [ 4699.210362] Out of memory: Killed process 6760 (pandoc) total-vm:1074132060kB, anon-rss:13290136kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:51572kB oom_score_adj:0

Bref ça donne :

$ ls -lnh markdown/
total 164M
-rw-r--r-- 1 1000 1000  29M 14 mai   18:31 cada-2023-04-12_0.md
-rw-r--r-- 1 1000 1000  29M 14 mai   18:41 cada-2023-04-12_10000.md
-rw-r--r-- 1 1000 1000  32M 14 mai   18:53 cada-2023-04-12_20000.md
-rw-r--r-- 1 1000 1000  34M 14 mai   19:06 cada-2023-04-12_30000.md
-rw-r--r-- 1 1000 1000  38M 14 mai   19:20 cada-2023-04-12_40000.md
-rw-r--r-- 1 1000 1000 3,4M 14 mai   19:35 cada-2023-04-12_50000.md

$ ls -lnh pdf/
total 442M
-rw-r--r-- 1 1000 1000  39M 14 mai   18:41 cada-2023-04-12_0.pdf
-rw-r--r-- 1 1000 1000  39M 14 mai   18:53 cada-2023-04-12_10000.pdf
-rw-r--r-- 1 1000 1000  43M 14 mai   19:06 cada-2023-04-12_20000.pdf
-rw-r--r-- 1 1000 1000  45M 14 mai   19:20 cada-2023-04-12_30000.pdf
-rw-r--r-- 1 1000 1000  50M 14 mai   19:35 cada-2023-04-12_40000.pdf
-rw-r--r-- 1 1000 1000 4,4M 14 mai   19:35 cada-2023-04-12_50000.pdf
-rw-r--r-- 1 1000 1000 224M 14 mai   19:41 cada-2023-04-12.pdf

Les personnes attentives auront noté le pdf obèse de 224 MiB. Il a été obtenu via

pdfunite cada-2023-04-12_0.pdf cada-2023-04-12_10000.pdf cada-2023-04-12_20000.pdf cada-2023-04-12_30000.pdf cada-2023-04-12_40000.pdf cada-2023-04-12_50000.pdf cada-2023-04-12.pdf

Tada! non CADA!

Le PDF final fait 52 019 pages (!) et evince (et probablement la plupart des lecteurs de PDF) arrive à l’ouvrir et à rechercher dedans. Mission accomplie.

Mais pas en 5min… il suffit de regarder les dates des fichiers plus haut d’ailleurs (et sans compter les essais multiples)…

Bref j’ai produit un gros PDF, et le résultat convenait, donc je vous partage ça. Rien d’extraordinaire mais bon ça représente quand même 5min de boulot quoi…

Commentaires : voir le flux Atom ouvrir dans le navigateur

par Benoît Sibaud

LinuxFr.org : les journaux

LinuxFr.org : Journaux

Téléphone sous Linux ?

 -  25 avril - 

Aujourd'hui, avoir un téléphone avec un Android libéré, c'est possible, on pense en particulier à Murena.Avoir un téléphone sous GNU/Linux, c'est (...)


Quand votre voiture vous espionne… et vous le fait payer

 -  23 avril - 

Ceci se passe aux États-Unis, pour l’instant, aucune preuve qu’une telle fuite existe en Europe. Mais… si votre assurance augmente brutalement, (...)


firefox, nouvelle fenêtre dans une session isolée

 -  15 avril - 

Les fenêtres de navigation privées de firefox partagent leurs cookies de session or je souhaitais avoir des fenêtres de navigation isolées, (qui ne (...)


Pretendo tente de déprogrammer l'obsolescence des consoles Nintendo

 -  9 avril - 

Ah Nal,Gros N vient de faire un gros doigt aux utilisateurs de ses consoles 3DS et Wii U en annonçant la fermeture des services en ligne pour (...)


[Trolldi] Vulgarisation sur l'IA pour décideur pressé

 -  5 avril - 

Cher 'Nal,Je fais un article-marque-page sur un post tout frais de Ploum où il est question d'un fantasme vieux comme le Talmud avec le Golem. (...)