Application Web de vote Python/Flask
Introduction
Le projet consiste en la réalisation d’une application web de vote : sur la page principale, deux citations des Simpsons sont affichées, en cliquant sur sa préférées, l’application enregistre le vote et calcule un classement des meilleurs citations.
La réalisation du projet mobilisera les compétences suivantes :
- programmation serveur Python,
- utilisation de bibliothèques Python,
- programmation HTML, utilisation d’un moteur de templates,
- programmation CSS, utilisation d’une bibliothèque CSS.
Changelog
- 2022-09-13 : correction bug ranking
- 2022-09-08 : ajout barème
- 2022-09-06 : conseil + factorisation index
- 2022-09-02 : définition du sujet, projet de départ
- 2022-09-01 : version complète OK
- 2022-08-29 : reprise code
MCC et rendu
Le projet est à réaliser en monôme.
Le projet est à rendre pour au plus tard le vendredi 30 septembre 2022 23h59 sur https://foad.unc.nc/ dans un unique fichier au format zip.
Barème prévisionnel
- 20% citations complètes en vis-à-vis
- dont esthétique et bonne utilisation Bulma
- 20% tableau des matchs
- dont qualité HTML/Jinja, esthétique et utilisabilité (info-bulles) et bonne utilisation Bulma
- 20% tableau du classement
- dont qualité HTML/Jinja, esthétique et utilisabilité (info-bulles) et bonne utilisation Bulma
- 10% factorisation template index
- dont qualité du code Jinja
- 10% bouton de la page en cours en surbrillance
- dont bonne utilisation variable Jinja
- 10% calcul du score ELO
- 10% message flash
- dont utilisation Flask/flash et màj template Jinja
- +10% dates au format français dans le tableau des matchs
Références
- Doc officielle Python https://docs.python.org/3/index.html
- Framework Web Flask : https://flask.palletsprojects.com/
- Templating Jinja2 : https://jinja.palletsprojects.com/
- Framework CSS : https://bulma.io/documentation/
Prise en main
Une projet Flask de départ à compléter est fourni. Il comporte toute la mise en place de l’architecture (configuration Flask, accès base de données SQLite)
Lancement de l’application de départ
Après avoir téléchargé et décompréssé le projet Flask de départ, placez-vous dans le dossier de travail et exécuter les commandes suivantes, où python
est le nom de l’exécutable Python dans votre environnement :
# téléchargement des dépendances
python -m pip install -r requirements.txt
# création de la base de données de départ
python database.py
# exécution du programme principal et ouverture du serveur
python app.py
Enfin, ouvrez http://127.0.0.1:5000/ et vérifier :
- que la page s’ouvre dans le navigateur
- qu’il y la trace des requêtes HTTP dans la console Python
- que la page principale permet de voter
- que le menu fonctionne (mais renvoie vers des pages à compléter)
Architecture de l’application
Le principe général de l’application est illustré par le diagramme de séquences UML suivant :
Pour la page principale, la séquence est comme suit :
- le serveur Flask reçoit une requête HTTP
GET /
quand le navigateur se connecte à http://localhost:5000/, il exécute la fonctionindex()
- le serveur Flask demande deux citations tirées aléatoirement à la base de données via
get_two_random_quotes()
- le serveur Flask reçoit les deux citations et génère la page à partir du template
index.jinja.html
viarender_template()
- le serveur Flask envoie la réponse HTTP au navigateur
Quand on clique sur une des citations, la séquence est comme suit :
- le serveur Flask reçoit une requête HTTP
POST /vote
, il exécute la fonctionvote()
- le serveur Flask vérifie le contenu de la requête, calcule les nouveaux scores ELO avec
compute_elo()
et demande à la base de données d’ajouter le match et de mettre à jour les scores viaadd_match_update_elo()
- le serveur Flask reçoit la réponse de la base de données et redirige vers la racine du site s’il n’y a pas eu d’erreur pour pouvoir vote à nouveau.
Réalisation
A chaque page est associée une fonction Python qui est déclenchée lorsqu’on navige sur la page, voir le CM7
L’application est constituée de trois pages (/
, /matches
et /ranking
) plus une route /vote
pour soumettre les votes par la méthode HTTP POST
.
Le résumé des routes est ci-dessous.
Fonction Method Route
----------- ------- -------------
get_index GET /
get_matches GET /matches
get_ranking GET /ranking
post_vote POST /vote
L’essentiel du code serveur est fourni, votre travail va consister essentiellement en la réalisation des templates en utilisant https://bulma.io/. Il n’y a quasiment aucun CSS à produire, juste à utiliser les classes Bulma existantes.
La liste des fonctionnalités à réaliser sur le projet de départ sont listées page par page.
Une vidéo YouTube de démonstration de l’application une fois terminée est fournie à titre d’exemple.
Conseils
- les pages sont indépendantes, ne restez pas bloqués sur la première page où sur de la CSS, passez à la suite et revenez plus tard
- commencez par des templates simples, sans CSS et ensuite améliorez le rendu
- https://bulma.io/ utilise massivement les Flexbox et propose des classes utilitaires (helpers en anglais) pour les modifier, idem pour les couleurs, la typographie…
Accueil
La page d’accueil sur la route http://127.0.0.1:5000/ affiche deux images et permet de voter.
À faire :
- le template
templates/index.jinja2.html
a un contenu dupliqué (ce qui est mal), ce qui est déséagrable quand ont doit modifier la structure des cartes car il faut tout faire en double. Factoriser les informations avec une boucle Jinja.- attention aux champs
<input type="hidden">
qui sont symétriques entre les deux images - attention à la deuxième image qui doit avoir
class="reverse"
- attention aux champs
- à l’aide de la biliothèque CSS https://bulma.io/, améliorer le rendu des citations sur lesquelles voter du template
templates/index.jinja2.html
- utiliser un composant de type card
- ajouter l’auteur et le contenu de la citation dans les cartes
- faire en sorte que les cartes aient les mêmes dimensions hauteur/largeur (difficile, n’essayez pas de le faire au tout début).
Liste des matchs
La route http://127.0.0.1:5000/matches/ doit afficher un tableau des duels qui ont déjà eu lieu avec comme informations :
- le nom du personnage gagnant du duel,
- la citation gagnante du duel,
- le nom du personnage perdant du duel,
- la citation perdante du duel,
- la date du duel.
À faire :
- compléter le template
templates/matches.jinja2.html
pour générer un tableau avec la listes des matches avec les colonnes indiquées- utiliser pour cela la fonction
get_all_matches()
pour obtenir le contenu - (BONUS) gérer un affichage des dates des matchs au format français, par exemple jeu. 08 sept. 2022 08:11:15 et pas
2022-09-08T08:11:15
grâce à datetime.fromisoformat() et datetime.strftime().
- utiliser pour cela la fonction
Classement
La route http://127.0.0.1:5000/ranking/ doit afficher un classement des citations avec comme informations :
- l’id de la citation
- la citation elle même
- le personnage de la citation
- le score ELO de la citation
- le rang de la citation (son numéro dans le classement)
- la différence entre le nombre de duels gagnés et de duels perdus
À faire :
- compléter le template
templates/ranking.jinja2.html
pour générer le classement des citations par score ELO décroissant- utiliser pour cela la fonction
get_ranking()
pour obtenir le contenu
- utiliser pour cela la fonction
Menu commun
Toutes les pages incluent un menu commun via le fichier templates/navbar.html
.
Selon la largeur du navigateur (1024px
ou moins), le menu est remplacé par un bouton.
À faire :
- améliorer le menu pour que le bouton de la page sur laquelle on se trouve soit d’une couleur différente des autres
- modifier
templates/navbar.html
ajouter une classe au bouton de la page en cours - utiliser pour cela une variable
active_page
dans chaque template et utilisez la danstemplates/navbar.html
comme indiqué dans la documentation Jinja Highlighting Active Menu Items
- modifier
Route des votes
La route http://127.0.0.1:5000/vote permet de recevoir les requêtes HTTP POST
émises quand on clique sur les images de http://127.0.0.1:5000/
À faire :
- compléter la fonction
compute_elo()
qui calcule les scores mis-à-jour après un duel. Pour l’instant cette fonction renvoie les valeurs d’entrées, il faut qu’elle renvoie les nouveaux scores ELO calculés comme indiqué sur Wikipedia - ajouter un message flash après chaque vote pour informer l’utilisateur, voir Message Flashing. Vous aurez besoin pour cela de modifier le template
templates/layout.jinja2.html