From 3a3f94b7cf6cf6e9895b09a6d3d3c1ed222757cc Mon Sep 17 00:00:00 2001 From: Iziram Date: Tue, 16 Jan 2024 09:19:40 +0100 Subject: [PATCH] =?UTF-8?q?Assiduites=20:=20fin=20int=C3=A9gration=20pagin?= =?UTF-8?q?ation=20+=20cache=20tableau?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scodoc/sco_assiduites.py | 5 ++- app/scodoc/sco_cache.py | 43 ------------------ app/static/js/assiduites.js | 48 -------------------- app/tables/liste_assiduites.py | 49 +++++++++++++++++++-- app/templates/assiduites/widgets/tableau.j2 | 6 ++- app/views/assiduites.py | 10 ++--- 6 files changed, 56 insertions(+), 105 deletions(-) diff --git a/app/scodoc/sco_assiduites.py b/app/scodoc/sco_assiduites.py index c252b34ea..b31366350 100644 --- a/app/scodoc/sco_assiduites.py +++ b/app/scodoc/sco_assiduites.py @@ -758,4 +758,7 @@ def simple_invalidate_cache(obj: dict, etudid: str | int = None): invalidate_assiduites_etud_date(etudid, date_debut) invalidate_assiduites_etud_date(etudid, date_fin) - sco_cache.RequeteTableauAssiduiteCache.delete_with(f"tableau-etud-{etudid}") + # Invalide les caches des tableaux de l'étudiant + sco_cache.RequeteTableauAssiduiteCache.delete_pattern( + pattern=f"tableau-etud-{etudid}:*" + ) diff --git a/app/scodoc/sco_cache.py b/app/scodoc/sco_cache.py index 8d0a5da84..e6d3fa814 100644 --- a/app/scodoc/sco_cache.py +++ b/app/scodoc/sco_cache.py @@ -398,10 +398,6 @@ class ValidationsSemestreCache(ScoDocCache): timeout = 60 * 60 # ttl 1 heure (en phase de mise au point) -class SimpleIndexCache(ScoDocCache): - prefix = "INDEX" - - class RequeteTableauAssiduiteCache(ScoDocCache): """ clé : ":::>::" @@ -410,42 +406,3 @@ class RequeteTableauAssiduiteCache(ScoDocCache): prefix = "TABASSI" timeout = 60 * 60 # Une heure - - @classmethod - def set(cls, oid: str, value: object): - """Ajoute une entrée au cache. Ajoute la clé dans la liste des clés du cache""" - keys_index = cls.get_index() - - # On met à jour l'index - if oid not in keys_index: - keys_index.append(oid) - SimpleIndexCache.set(cls.prefix + "_index", keys_index) - - # On cache la valeur - return super().set(oid, value) - - @classmethod - def get_index(cls) -> list: - """récupère la liste des clés des entrées du cache""" - # on définie un index des clés pour faciliter l'invalidation - keys_index: list = SimpleIndexCache.get(cls.prefix + "_index") - if keys_index is None: - keys_index = [] - - return keys_index - - @classmethod - def delete_with(cls, start: str): - """Invalide toutes les entrées de cache commençant par """ - keys_index: list[str] = cls.get_index() - - key: str - filtered_keys_index: list = [key for key in keys_index if key.startswith(start)] - - for key in filtered_keys_index: - cls.delete(key) - - SimpleIndexCache.set( - cls.prefix + "_index", - [k for k in keys_index if k not in filtered_keys_index], - ) diff --git a/app/static/js/assiduites.js b/app/static/js/assiduites.js index 59aefad19..9f7e69e7a 100644 --- a/app/static/js/assiduites.js +++ b/app/static/js/assiduites.js @@ -1,51 +1,3 @@ -function loadAssi(count, deb) { - let c = 0; - let a = new Date(deb); - a.setHours(0, 0, 0, 0); - const etat = ["present", "absent", "retard"]; - const etudid = 17888; - const path = getUrl() + `/api/assiduite/${etudid}/create`; - const assiduites = []; - while (c < count) { - if (a.getDay() > 0 && a.getDay() < 6) { - c++; - const date = a.toISOString().split("T")[0]; - const assis = [ - { - date_debut: date + "T08:00", - date_fin: date + "T10:00", - etat: etat[Math.floor(Math.random() * 3)], - }, - { - date_debut: date + "T10:15", - date_fin: date + "T12:15", - etat: etat[Math.floor(Math.random() * 3)], - }, - { - date_debut: date + "T13:15", - date_fin: date + "T15:15", - etat: etat[Math.floor(Math.random() * 3)], - }, - { - date_debut: date + "T15:30", - date_fin: date + "T17:00", - etat: etat[Math.floor(Math.random() * 3)], - }, - ]; - - assiduites.push(...assis); - } - a = new Date(a.valueOf() + 24 * 3600 * 1000); - } - - async_post( - path, - assiduites, - () => {}, - () => {} - ); -} - // <=== CONSTANTS and GLOBALS ===> let url; diff --git a/app/tables/liste_assiduites.py b/app/tables/liste_assiduites.py index 1a2613765..8ad7992e3 100644 --- a/app/tables/liste_assiduites.py +++ b/app/tables/liste_assiduites.py @@ -13,20 +13,61 @@ from app.scodoc.sco_cache import RequeteTableauAssiduiteCache class Pagination: + """ + Pagination d'une collection de données + + On donne : + - une collection de données (de préférence une liste / tuple) + - le numéro de page à afficher + - le nombre d'éléments par page + + On peut ensuite récupérer les éléments de la page courante avec la méthode `items()` + + Cette classe ne permet pas de changer de page. + (Pour cela, il faut créer une nouvelle instance, avec la collection originelle et la nouvelle page) + + l'intéret est de ne pas garder en mémoire toute la collection, mais seulement la page courante + + """ + def __init__(self, collection: list, page: int = 1, per_page: int = -1): + """ + __init__ Instancie un nouvel objet Pagination + + Args: + collection (list): La collection à paginer. Il s'agit par exemple d'une requête + page (int, optional): le numéro de la page à voir. Defaults to 1. + per_page (int, optional): le nombre d'éléments par page. Defaults to -1. (-1 = pas de pagination/tout afficher) + """ + # par défaut le total des pages est 1 (même si la collection est vide) self.total_pages = 1 if per_page != -1: + # on récupère le nombre de page complète et le reste + # q => nombre de page + # r => le nombre d'éléments restants (dernière page si != 0) q, r = len(collection) // per_page, len(collection) % per_page - self.total_pages = q if r == 0 else q + 1 - current_page: int = min(self.total_pages, page) + self.total_pages = q if r == 0 else q + 1 # q + 1 s'il reste des éléments + + # On s'assure que la page demandée est dans les limites + current_page: int = min(self.total_pages, page if page > 0 else 1) + + # On récupère la collection de la page courante self.collection = ( - collection + collection # toute la collection si pas de pagination if per_page == -1 - else collection[per_page * (current_page - 1) : per_page * (current_page)] + else collection[ + per_page * (current_page - 1) : per_page * (current_page) + ] # sinon on récupère la page ) def items(self) -> list: + """ + items Renvoi la collection de la page courante + + Returns: + list: la collection de la page courante + """ return self.collection diff --git a/app/templates/assiduites/widgets/tableau.j2 b/app/templates/assiduites/widgets/tableau.j2 index 423458a0a..3691882d6 100644 --- a/app/templates/assiduites/widgets/tableau.j2 +++ b/app/templates/assiduites/widgets/tableau.j2 @@ -47,7 +47,8 @@ - {% if options.page > 2 %} + + {% if options.page > 2 and (options.page - 1) - 1 > 1 %}
  • ...
  • {% endif %} @@ -61,7 +62,8 @@ {% endfor %} - {% if options.page < total_pages - 1 %} + + {% if options.page < total_pages - 1 and total_pages - (options.page + 1 ) > 1 %}
  • ...
  • {% endif %} diff --git a/app/views/assiduites.py b/app/views/assiduites.py index fcca33d9d..f9f2887a7 100644 --- a/app/views/assiduites.py +++ b/app/views/assiduites.py @@ -525,11 +525,11 @@ def liste_assiduites_etud(): liste_assi.AssiJustifData.from_etudiants( etud, ), - filename=f"assiduites-justificatifs-{etudid}", + filename=f"assiduites-justificatifs-{etud.id}", afficher_etu=False, filtre=liste_assi.AssiFiltre(type_obj=0), options=liste_assi.AssiDisplayOptions(show_module=True), - cache_key=f"tableau-etud-{etudid}", + cache_key=f"tableau-etud-{etud.id}", ) if not tableau[0]: return tableau[1] @@ -1501,9 +1501,6 @@ def _prepare_tableau( show_etu=afficher_etu, order=ordre, ) - import time - - a = time.time() table: liste_assi.ListeAssiJusti = liste_assi.ListeAssiJusti( table_data=data, @@ -1512,8 +1509,7 @@ def _prepare_tableau( no_pagination=fmt.startswith("xls"), titre=cache_key, ) - b = time.time() - print(f"génération du tableau : {b-a:.6f}s") + if fmt.startswith("xls"): return False, scu.send_file( table.excel(),