PyVotons!
Documentation pour les développeurs - documentation technique
-
Présentation générale
PyVotons! est un logiciel libre (licence GPL) en phase alpha/beta de développement : il fonctionne
pour les cas simples qui ont été testés, mais il reste sans doute un certain
nombre de bugs.
Des fonctions supplémentaires doivent être implémentées, notamment l'enregistrement des votes par des serveurs externes pour limiter au
maximum le risque de fraude et une interface web pour permettre le vote par internet.
-
Choix technologiques
PyVotons! est un logiciel développé sous Linux dans le langage Python.
L'interface graphique et les fonctions réseaux sont implémentées grâce à la librairie Qt 4 et aux bindings Python de cette librairie (PyQt4),
ce qui devrait garantir la portabilité du code sur les trois principales plateformes cibles (Windows, Mac Os X et Linux).
PyQt permet un développement rapide et simple des interfaces graphiques
et c'est l'outil avec lequel je suis le plus familier pour les interfaces graphiques en Python.
-
Structure du code
La séparation entre les algos et l'interface elle-même n'est pas parfaite...
Le code est composé :
- de fichiers *.ui décrivant l'interface graphique (créés et éditables avec Qt Designer);
- d'un Makefile assurant leur traduction automatique en Python (fichiers *UI.py)
- de classes dérivées des classes *UI.py (les *Dialog.py) qui comportent des classes dérivées de QDialog
incluant les fonctions exécutées par l'interface graphique
- de quelques librairies de fonctions (entrées-sorties, calcul des résultats)
Trois logiciels composent PyVotons! : CreeScrutin.py (pour définir les paramètres d'un scrutin), Vote.py (pour
enregistrer les votes dans un bureau de vote) et CalculResultats.py (comme son nom l'indique).
Le code est très commenté donc je vous invite à le regarder directement (vous pouvez cliquer sur les noms de fichier ci-dessous).
Interfaces graphiques
- CreerScrutin.ui
- Interface pour créer un scrutin
- VoteAdmin.ui
- Interface pour lancer un vote
- VoteUnique.ui
- Interface pour le vote unique
- VoteUniqueTransferable.ui
- Interface pour le vote unique tranférable
- candidatNoteWidget.ui
- Widget contenant le nom du candidat et une SpinBox pour le noter
- VoteAssentiment.ui
- Interface pour le vote par assentiment
- calculResultats.ui
- Interface pour lancer le calcul des résultats d'un scrutin et afficher les résultats détaillés
Ces fichiers permettent de générer automatiquement des fichiers python qui contruisent ces interfaces
(les fichiers nommés *UI.py, comme CreerScrutinUI.py
Classes dérivées des interfaces graphiques
Les classes citées ici utilisent les programmes Python générés automatiquement par pyuic4 (PyQt4) pour
obtenir des interfaces fonctionnelles.
CreerScrutin.py : fonctions de création d'un scrutin et classe QDialog correspondante
VoteAdminDialog.py : fonctions de gestion d'un vote et classe QDialog correspondante
VoteUniqueDialog.py : fonctions pour effectuer un vote unique et classe QDialog correspondante
VoteUniqueTransferableDialog.py : fonctions pour effectuer un vote unique transférable et classe QDialog correspondante
VoteAssentimentDialog.py : fonctions pour effectuer un vote par assentiment et classe QDialog correspondante
CalculResultatsDialog.py : fonctions pour lancer le calcul des résultats d'un scrutin et classe QDialog correspondante
Logiciels
Ces fichiers sont les programmes lancés par l'utilisateur:
CreerScrutin.py : pour définir les paramètres d'un scrutin
Vote.py : pour lancer un vote et enregistrer les votes dans un bureau
CalculResultats.py: calcule les résultats et les affiche.
Libraries de fonctions
ScrutinIO.py : entrées-sorties (sauvegarde et lecture des trois formats de fichier)
ScrutinCalcul.py : fonctions de calcul des résultats pour chaque type de scrutin.
-
Format des fichiers
Les formats de fichiers ont été définis le plus simplement possible :
ce sont des représentations en texte des structures Python correspondantes.
Il existe trois formats : le format Scrutin (*.scrutin) définit le stockage des informations liées à un scrutin,
le format Votes (*.votes) permet de stocker les votes liés à un scrutin de façon anonyme, et le format Registre
(*.registre) stocke le registre des votants lié à un fichier Votes.
Pour comprendre les formats, allez voir le code source du fichier ScrutinIO.py.
Futur
Il est possible d'envisager des méthodes de stockage différentes (document XML, stockage en base de données SQL...).
Les formats actuels sont sans doute incomplets, il évolueront au fur et à mesure des besoins pour stocker d'autres informations.
-
Stratégies pour limiter les problèmes de fraude
Les idées ci-dessous n'existent pas dans le code mais présentent un idéal pour le futur...
- Le vote se passe sur une machine contrôlée et avec un accès uniquement au clavier et à l'écran
- Le vote est lancé par le président et deux assesseurs, chacun en possession d'un clef secrète différente.
Toutes les clefs sont nécessaires pour ouvrir et pour clore le scrutin
- A la connexion chaque serveur envoie un programme qui calcule la somme de contrôle MD5 et SHA-1 du logiciel de vote
pour contrôler que la version qui s'exécute est la même que celle présente sur le serveur
- Chaque électeur reçoit avant le vote un identifiant du type "Prenom-Nom-XXXXXXX" où XXXXX est un nombre aléatoire.
- Le bureau de vote se connecte en début de vote à plusieurs serveurs et leur envoie chaque vote anonymisé.
Un vote n'est confirmé que lorsque tous les serveurs ont confirmé la réception (connection sécurisée type
tunnel SSH)
- On dispose ainsi de plusieurs "centres de comptage" qui reçoivent l'intégralité des votes des bureaux en temps réel,
mais on conserve une copie locale des votes dans chaque bureau.
- A la fin du scrutin, les serveurs reçoivent une copie du registre des votants pour contrôler l'absence de
doubles votes entre bureaux.
- Chaque électeur entre son identifiant pour voter. Si ce dernier est invalide, l'électeur ne peut pas voter.
- Lorsqu'un électeur vote il reçoit une copie papier de son vote qu'il peut contrôler et déposer dans une urne.
Ceci permet de recompter les voix à la main en cas de litige.
Une interface de vote par internet : l'interface de vote (technologies type AJAX) devra se connecter à un
ensemble de serveurs pour valider le vote auprès de tous ces serveurs (le risque est l'absence d'anonymat).
La page de confirmation de l'utilisateur sera composée d'une frame par serveur avec la confirmation d'enregistrement
du vote par chaque serveur.
-
FAQ développeurs
- Si vous souhaitez réorganiser une interface sans changer le fonctionnement du logiciel, il vous suffit d'éditer le fichier .ui
avec Qt Designer sans changer le nom ou le type des widgets, puis de le compiler avec le Makefile (valable sous Linux).
- Si vous souhaitez ajouter un nouveau type de scrutin, c'est plus compliqué. Il faudra modifier CreeScrutin
(Interface .ui et code python), modifier VoteAdminDialog.py et peut-être créer une nouvelle interface pour votre type de vote, et
enfin ajouter dans ScrutinCalcul.py votre fonction de calcul des résultats (sans oublier de l'ajouter à la fonction getAllMethods du même fichier)
-
Perspectives et fonctionnalités
- Vote par internet : l'avantage, c'est la facilité logistique (rien à installer, chacun peut voter avec n'importe quel ordinateur)
Les options technologiques pour cela, c'est la génération par les serveurs de votes de pages interactives type AJAX. Pour cela,
on peut utiliser l'outil Pyjamas qui génère des pages AJAX à partir d'une description d'interface (mais pas du Qt...).
Un autre projet en développement est QWebClient :
il permet d'afficher une interface Qt dans un navigateur grâce à un petit serveur Web. Le stade expérimental de ce projet pose trois
problèmes : sa fiabilité n'est pas garantie, il ne supporte pas les connexions multiples à grande échelle pour l'instant (septembre 2009),
il est en C++ et n'a pas de bindings Python puisqu'il ne fait pas officiellement partie de Qt.
-
Implémentation du plus grand nombre possible de systèmes de votes : il faudra rendre le code plus modulaire (chargement auto de plugins ?)
Ces logiciels sont toujours en développement
N'hésitez pas à éditer le code et à m'envoyer vos modifications