forked from ScoDoc/ScoDoc
Assiduites : fin intégration pagination + cache tableau
This commit is contained in:
parent
89a16489bc
commit
c0f26e952a
@ -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_debut)
|
||||||
invalidate_assiduites_etud_date(etudid, date_fin)
|
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}:*"
|
||||||
|
)
|
||||||
|
@ -398,10 +398,6 @@ class ValidationsSemestreCache(ScoDocCache):
|
|||||||
timeout = 60 * 60 # ttl 1 heure (en phase de mise au point)
|
timeout = 60 * 60 # ttl 1 heure (en phase de mise au point)
|
||||||
|
|
||||||
|
|
||||||
class SimpleIndexCache(ScoDocCache):
|
|
||||||
prefix = "INDEX"
|
|
||||||
|
|
||||||
|
|
||||||
class RequeteTableauAssiduiteCache(ScoDocCache):
|
class RequeteTableauAssiduiteCache(ScoDocCache):
|
||||||
"""
|
"""
|
||||||
clé : "<titre_tableau>:<type_obj>:<show_pres>:<show_retard>>:<order_col>:<order>"
|
clé : "<titre_tableau>:<type_obj>:<show_pres>:<show_retard>>:<order_col>:<order>"
|
||||||
@ -410,42 +406,3 @@ class RequeteTableauAssiduiteCache(ScoDocCache):
|
|||||||
|
|
||||||
prefix = "TABASSI"
|
prefix = "TABASSI"
|
||||||
timeout = 60 * 60 # Une heure
|
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 <start>"""
|
|
||||||
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],
|
|
||||||
)
|
|
||||||
|
@ -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 ===>
|
// <=== CONSTANTS and GLOBALS ===>
|
||||||
|
|
||||||
let url;
|
let url;
|
||||||
|
@ -13,20 +13,61 @@ from app.scodoc.sco_cache import RequeteTableauAssiduiteCache
|
|||||||
|
|
||||||
|
|
||||||
class Pagination:
|
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):
|
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
|
self.total_pages = 1
|
||||||
|
|
||||||
if per_page != -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
|
q, r = len(collection) // per_page, len(collection) % per_page
|
||||||
self.total_pages = q if r == 0 else q + 1
|
self.total_pages = q if r == 0 else q + 1 # q + 1 s'il reste des éléments
|
||||||
current_page: int = min(self.total_pages, page)
|
|
||||||
|
# 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 = (
|
self.collection = (
|
||||||
collection
|
collection # toute la collection si pas de pagination
|
||||||
if per_page == -1
|
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:
|
def items(self) -> list:
|
||||||
|
"""
|
||||||
|
items Renvoi la collection de la page courante
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: la collection de la page courante
|
||||||
|
"""
|
||||||
return self.collection
|
return self.collection
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- Afficher les ellipses si la page courante est supérieure à 2 -->
|
<!-- Afficher les ellipses si la page courante est supérieure à 2 -->
|
||||||
{% if options.page > 2 %}
|
<!-- et qu'il y a plus d'une page entre le 1 et la page courante-1 -->
|
||||||
|
{% if options.page > 2 and (options.page - 1) - 1 > 1 %}
|
||||||
<li class="disabled"><span>...</span></li>
|
<li class="disabled"><span>...</span></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -61,7 +62,8 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<!-- Afficher les ellipses si la page courante est inférieure à l'avant-dernière page -->
|
<!-- Afficher les ellipses si la page courante est inférieure à l'avant-dernière page -->
|
||||||
{% if options.page < total_pages - 1 %}
|
<!-- et qu'il y a plus d'une page entre le total_pages et la page courante+1 -->
|
||||||
|
{% if options.page < total_pages - 1 and total_pages - (options.page + 1 ) > 1 %}
|
||||||
<li class="disabled"><span>...</span></li>
|
<li class="disabled"><span>...</span></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -525,11 +525,11 @@ def liste_assiduites_etud():
|
|||||||
liste_assi.AssiJustifData.from_etudiants(
|
liste_assi.AssiJustifData.from_etudiants(
|
||||||
etud,
|
etud,
|
||||||
),
|
),
|
||||||
filename=f"assiduites-justificatifs-{etudid}",
|
filename=f"assiduites-justificatifs-{etud.id}",
|
||||||
afficher_etu=False,
|
afficher_etu=False,
|
||||||
filtre=liste_assi.AssiFiltre(type_obj=0),
|
filtre=liste_assi.AssiFiltre(type_obj=0),
|
||||||
options=liste_assi.AssiDisplayOptions(show_module=True),
|
options=liste_assi.AssiDisplayOptions(show_module=True),
|
||||||
cache_key=f"tableau-etud-{etudid}",
|
cache_key=f"tableau-etud-{etud.id}",
|
||||||
)
|
)
|
||||||
if not tableau[0]:
|
if not tableau[0]:
|
||||||
return tableau[1]
|
return tableau[1]
|
||||||
@ -1501,9 +1501,6 @@ def _prepare_tableau(
|
|||||||
show_etu=afficher_etu,
|
show_etu=afficher_etu,
|
||||||
order=ordre,
|
order=ordre,
|
||||||
)
|
)
|
||||||
import time
|
|
||||||
|
|
||||||
a = time.time()
|
|
||||||
|
|
||||||
table: liste_assi.ListeAssiJusti = liste_assi.ListeAssiJusti(
|
table: liste_assi.ListeAssiJusti = liste_assi.ListeAssiJusti(
|
||||||
table_data=data,
|
table_data=data,
|
||||||
@ -1512,8 +1509,7 @@ def _prepare_tableau(
|
|||||||
no_pagination=fmt.startswith("xls"),
|
no_pagination=fmt.startswith("xls"),
|
||||||
titre=cache_key,
|
titre=cache_key,
|
||||||
)
|
)
|
||||||
b = time.time()
|
|
||||||
print(f"génération du tableau : {b-a:.6f}s")
|
|
||||||
if fmt.startswith("xls"):
|
if fmt.startswith("xls"):
|
||||||
return False, scu.send_file(
|
return False, scu.send_file(
|
||||||
table.excel(),
|
table.excel(),
|
||||||
|
Loading…
Reference in New Issue
Block a user