WebIHM

Introduction au web et IHM en S2 Licence Informatique UNC

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

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 :

  1. que la page s’ouvre dans le navigateur
  2. qu’il y la trace des requêtes HTTP dans la console Python
  3. que la page principale permet de voter
  4. 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 :

diagramme de séquence

Pour la page principale, la séquence est comme suit :

  1. le serveur Flask reçoit une requête HTTP GET / quand le navigateur se connecte à http://localhost:5000/, il exécute la fonction index()
  2. le serveur Flask demande deux citations tirées aléatoirement à la base de données via get_two_random_quotes()
  3. le serveur Flask reçoit les deux citations et génère la page à partir du template index.jinja.html via render_template()
  4. le serveur Flask envoie la réponse HTTP au navigateur

Quand on clique sur une des citations, la séquence est comme suit :

  1. le serveur Flask reçoit une requête HTTP POST /vote, il exécute la fonction vote()
  2. 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 via add_match_update_elo()
  3. 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"
  • à 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().

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

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 dans templates/navbar.html comme indiqué dans la documentation Jinja Highlighting Active Menu Items

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