---
title: SLM, School Library Manager
subtitle: Gestion de livres à la coopérative scolaire
author: "Georges Khaznadar <georgesk@debian.org>"
institute: "Lycée Jean Bart -- Dunkerque ; organisation Debian"
topic: "LB"
theme: "Frankfurt"
colortheme: "beaver"
fonttheme: "professionalfonts"
fontsize: 9pt
urlcolor: red
linkstyle: bold
aspectratio: 169
date: 21 octobre 2024
lang: fr-FR
section-titles: false
toc: true
---

# Paquets à installer

Il y a un paquet slm dans Debian, donc :

`apt install slm`

```python
Package: slm
Version: 1.26-1
Installed-Size: 57503
Maintainer: Georges Khaznadar <georgesk@debian.org>
Architecture: all
Depends: debconf (>= 0.5) | debconf-2.0, python3, python3-django, 
 gnome-colors-common, python3-reportlab, python3-lxml, 
 fonts-liberation, fonts-liberation2, python3-svglib, sound-icons, 
 pelican, python3-levenshtein, python3-termcolor, python3-pyqrcode, 
 python3-odf, libjs-jquery, libjs-jquery-ui, libjs-jquery-ui-touch-punch, 
 qrencode, python3-pandas, python3-pylabels, node-html5-qrcode, 
 python3-unidecode, python3-trml2pdf, python3-pypinyin, 
 libapache2-mod-wsgi-py3, python3-matplotlib, fonts-dejavu-extra, 
 pwgen, acl, gettext
Pre-Depends: apache2, systemd
...
```

## Pour découvrir SLM

Une base de donnée anonymisée est mise à disposition, pour faire des essais.
Les noms des élèves y ont été remplacés par ceux de divers personnages des
bandes dessinées créées par Gosciny & Uderzo, un seul numéro de téléphone
remplace les numéros personnels.

Voici comment faire un essai :

```shell
un_chemin:$ cp -Rd /var/lib/slm .
un_chemin:$ cp outils/db_test0.sqlite3 ./db.sqlite3
un_chemin:$ ./manage.py runserver
```

Le service web SLM sera alors basé sur la base anonymisée ; il existe un
utilisateur **`admin`**, qui a pour mot de passe **`slmslm1234`**.

# SLM, IRL

... ou SLM, dans la vraie vie !

SLM a été développé au 
[lycée Jean Bart de Dunkerque](https://www.lyceejeanbart.fr), à partir de 2022,
dans le cadre d'une numérisation des actions de la coopérative scolaire.

![Le hall du lycée](img/jeanbart-coupe.jpg){width=100%}

La coopérative distribue des livres, tous identifiés par une étiquette
à code-barre. Avant l'usage de SLM, une application basée sur
Microsoft® Access, nommée GemaSCO, a été utilisée.

## Le besoin

Il s'agit de gérer les livres scolaires prêtés aux étudiants du
second cycle (environ 20 000 livres en stock, pour 1 500 étudiants).

![Un livre à prêter, et son code-barre](img/bescherelle.jpg){height=50%}

Chaque élève a besoin de quelques dix livres, et la location des livres
est gérée au début du mois de septembre. Durant cette période, on doit
pouvoir servir une trentaine d'élèves par heure.

## Parcours typique

Un élève arrive, accompagné par toute sa classe, et écoute (attentivement,
bien sûr) les explications générales. Puis quand vient son tour, il 
échange des paiements : 10 € d'adhésion, 55 € de forfait de location, plus une
caution pour les « arrivants », contre une « entrée à la boutique ».

![L'étape du paiement](img/paiement-recadre.jpg){width=100%}

## La boutique

À l'entrée de la boutique, elle ou il pose son sac, prend
un panier et son joli-phone, et scanne un QR-code, ce qui
lui donne un jeton valide une heure durant...
Après quoi, l'application web SLM lui demande son nom et
prénom, lui montre la liste des options, spécialités et 
langues déjà connues à son inscription au lycée, avec une 
opportunité pour corriger des détails. 

Après confirmation, le mode « boutique » est enclenché.

![](img/b1.jpg){width=20%} 
![](img/b2.jpg){width=20%}
![](img/b3.jpg){width=20%}

## Le mode boutique

Rappel : l'élève tient un panier, dans le creux de son coude, a un téléphone
dans la main prêt à scanner des repères sous les piles de livres.

Si tout se passe bien, l'élève dispose aussi de son autre main pour 
prendre des livres, et de son cerveau, pour raisonner (optionnellement).

![](img/boutique4-recadre.jpg){width=100%} 


## Choix des livres

Face à un pile de livres, le QR-code scanné peut renvoyer un écran rouge
(pas bon, je prends pas), ou un écran vert (bon, je prends), avec un gros 
bouton « PRIS », juste sous le pouce. Si le bouton est là, il faut appuyer 
dessus, sans oublier de prendre le livre.

![](img/boutique5-recadre.jpg){width=100%} 

Quand tous les livres ont été pris, si le son n'est pas désactivé, une sonnerie
de trompette retentit : il est temps de revenir « aux caisses ».

## Enregistrement des locations

L'élève donne sa pile de livres au bénévole de la coopérative qui l'attendait,
la ou le bénévole identifie chacun des livres à l'aide d'un lecteur de
code-barre, valide la liste de prêts, imprime la « feuille de prêt » et la
fait signer à l'élève.

![Saisie des prêts](img/prets1.png){width=100%}

## Impression et signature de la fiche de prêts

![La fiche de prêts](img/prets2.png){width=100%}

# Django

Pourquoi développer une application avec Django, alors que l'application 
GemaSCO existe déjà, qu'elle est sous licence libre, et distribuée
gratuitement à qui sait la mettre en oeuvre ?

- Microsoft® Access n'est pas libre.
- Durant les premiers développements de SLM, des bugs irritants venaient
  avec GemaSCO, éliminés dès les premières versions de SLM.
- Le langage Python est beaucoup plus expressif que le langage des 
  scripts d'Access, et on hérite de bibliothèques libres puissantes.
- Django calcule sans faute les migrations à faire dans la base de données
  quand on décide de changements de structure, d'une version à l'autre :
  c'est très précieux.
- GemaSCO fonctionne sur une machine seule, ou sur un
  groupe de machines utilisant un partage Windows commun. Django ne connaît
  que les limites d'Internet : il devient possible de communiquer avec
  les téléphones des élèves, par exemple
  
![](img/banniere.png){width=100%}

## Structure de la base de données

La base de données est structurée par des classes héritières de 
`django.db.models.Model` ; les classes les plus importantes sont

- class Eleve
- class Materiel
- class Inventaire
- class Pret

La classe **Eleve** contient à peu de chose près ce qu'on peut 
importer des données
fournies par l'administration du lycée, pour identifier les élèves, 
leurs classes, option, langues et spécialités

La classe **Materiel** décrit chaque sorte d'objet prêtable, 
livre ou calculette ...

La classe **Inventaire** correspond à chaque objet concret prêtable, et précise
le code-barre qui l'identifie

La classe **Pret** contient les enregistrements de chaque objet prêté à un
étudiant, et précise la date du prêt, la date du retour.

## Django apporte une abstraction utile

Django permet d'utiliser divers moteurs de base de donnée. La définition 
des champs d'une table dans la base de données ne dépend pas du moteur choisi,
et les champs appartiennent à des classes plus riches que ne le sont les
structures de la base de données sous-jacente. Par exemple :

```python
class Pret(models.Model):
    ...
    eleve = models.ForeignKey('Eleve', on_delete=models.CASCADE)
    inventaire = models.ForeignKey('Inventaire', on_delete=models.CASCADE)
    date_pret = DateField(verbose_name = _("Date de prêt") )
    date_retour = DateField(verbose_name = _("Date de retour"),
	    blank = True, default = DATE111 )
    Date_Declaration_Perte = DateField(
        verbose_name = _("Date de déclaration de la perte"),
        blank = True, default = DATE111 )
    Etat_Initial = IntegerField(
        verbose_name = _("État Initial"), choices = ETAT_MATERIEL_CHOIX,
        blank = True, default = etat_AUTRE)
	...

```

## Les requêtes sont comme des itérateurs

... et les itérateurs c'est avantageux, car ils sont paresseux (*lazy*).

Par exemple, quand les livres ont été
distribués, un des visionneurs de la page `/inventaire` permet de voir les
« **Élèves avec au moins un livre prêté** » ; il y en a typiquement 1 200 
ou plus, mais l'utilisation d'un **QuerySet** de Django permet d'accéder
à la base de données de façon optimisée : on peu savoir tout de suite
*combien* il y a d'élèves dans ce cas, mais si on affiche les quarante
premiers, la base de données n'est fouillée que pour ces *quarante là*
(et peut-être un peu plus, qui sont réservés en cache pour une demande
ultérieure)

![Un des visionneurs, à l'URL `/inventaire`](img/un-livre-prete.png){width=100%}

## Économie de moyens, économie d'énergie

Pour le moment, la coopérative se contente d'exploiter un petit serveur
avec un processeur Intel Atom® N2800 : deux coeurs, à 1,8 GHz, puissance
de dissipation thermique (PDT) de 6,5 W.

![Initiative de durabilité (logo © Tomasz Kozlowski, CC-BY-SA)](img/Sustainability_Initiative_logo_simplified.svg){width=100%}

# Encore Python

Django est un module Python... mais SLM utilise plus que Django

![logo de SLM (© Berdea, CC-BY-SA)](img/Collaboration_logo_V2.svg){width=100%}

## L'aide contextuelle

La plupart des pages web visibles sont définies dans un fichier `views.py`
et sont rendues en tenant compte de quelques paramètres, dont un paramètre
**aide**. Ce paramètre, quand on le définit, permet de renvoyer 
automatiquement vers une page d'aide, en rapport avec le contexte courant.

**Toute l'aide** est servie sous forme de pages statiques, générées grâce
au logiciel [Pelican](https://getpelican.com/)

![Page d'aide pour l'URL `/inventaire`](img/snap-inventaire.png){width=100%}


## I18N, L10N

SLM, ainsi que les pages d'aide, sont **internationalisés** grâce au module
Python `gettext` ; des traductions en espagnol/castillan et en 
anglais/américain sont maintenues.

![Page d'aide traduite, pour l'URL `/inventaire`](img/snap-inventario.png){width=100%}

## Documents aux formats SVG, PDF, ODS

- Un module `pylabels` permet de générer, au format **PDF** des documents qui
  sont répétés au sein d'un page à imprimer, comme les étiquettes à code-barre,
  mais pas que...
- Les modules `pyx` et `cairosvg`, entre autres, sont utilisés pour pouvoir
  gérer l'I18N des copies d'écran sur lesquelles on ajoute des commentaires.
  Les copies d'écran annotées sont rendues au format **SVG**
- Les modules `reportlab` et `trml2pdf` permettent de générer des fichiers
  **PDF** à partir de modèles en langue **RML** (Reportlab Markup Language), qui
  sont bien sûr dynamiques, grâce au système de *templates* de Django
- Le module `odf` permet de produire des documents aux formats de LibreOffice :
  **ODS** est utilisé pour exporter des données à destination d'un tableur,
  comme par exemple des listes d'élèves que nos Conseillers Principaux
  d'Éducation (CPE) souhaitent convoquer.

## Des questions ?

On peut faire une démo, montrer des sources, ouvrir un shell Django, etc.

![Quelques bénévoles de la COOP](img/coop.png){width=100%}

Ce document, ainsi que les illustrations, sauf mention contraire : © 2024 Georges Khaznadar, 
[CC-BY-SA-4.0](https://fr.wikipedia.org/wiki/Licence_Creative_Commons)
