forked from ScoDoc/ScoDoc
Table recap: optimisation et cache
This commit is contained in:
parent
01c0328636
commit
3ab0e89c2f
@ -14,6 +14,7 @@ import pandas as pd
|
||||
|
||||
from flask import g, url_for
|
||||
|
||||
from app.auth.models import User
|
||||
from app.comp.res_cache import ResultatsCache
|
||||
from app.comp import res_sem
|
||||
from app.comp.moy_mod import ModuleImplResults
|
||||
@ -26,7 +27,6 @@ from app.scodoc.sco_codes_parcours import UE_SPORT, DEF, DEM
|
||||
from app.scodoc import sco_evaluation_db
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.scodoc import sco_groups
|
||||
from app.scodoc import sco_users
|
||||
from app.scodoc import sco_utils as scu
|
||||
|
||||
# Il faut bien distinguer
|
||||
@ -414,7 +414,6 @@ class ResultatsSemestre(ResultatsCache):
|
||||
- les colonnes de modules (SAE ou res.) d'une UE ont la classe mod_ue_<ue_id>
|
||||
_<column_id>_order : clé de tri
|
||||
"""
|
||||
|
||||
if convert_values:
|
||||
fmt_note = scu.fmt_note
|
||||
else:
|
||||
@ -430,6 +429,7 @@ class ResultatsSemestre(ResultatsCache):
|
||||
titles = {}
|
||||
# les titres en footer: les mêmes, mais avec des bulles et liens:
|
||||
titles_bot = {}
|
||||
dict_nom_res = {} # cache uid : nomcomplet
|
||||
|
||||
def add_cell(
|
||||
row: dict,
|
||||
@ -602,11 +602,14 @@ class ResultatsSemestre(ResultatsCache):
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
moduleimpl_id=modimpl.id,
|
||||
)
|
||||
nom_resp = dict_nom_res.get(modimpl.responsable_id)
|
||||
if nom_resp is None:
|
||||
user = User.query.get(modimpl.responsable_id)
|
||||
nom_resp = user.get_nomcomplet() if user else ""
|
||||
dict_nom_res[modimpl.responsable_id] = nom_resp
|
||||
titles_bot[
|
||||
f"_{col_id}_target_attrs"
|
||||
] = f"""
|
||||
title="{modimpl.module.titre}
|
||||
({sco_users.user_info(modimpl.responsable_id)['nomcomplet']})" """
|
||||
] = f""" title="{modimpl.module.titre} ({nom_resp})" """
|
||||
modimpl_ids.add(modimpl.id)
|
||||
ue_valid_txt = f"{nb_ues_validables}/{len(ues_sans_bonus)}"
|
||||
if nb_ues_warning:
|
||||
|
@ -16,6 +16,7 @@ from app import models
|
||||
|
||||
from app.scodoc import notesdb as ndb
|
||||
from app.scodoc.sco_bac import Baccalaureat
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
import app.scodoc.sco_utils as scu
|
||||
|
||||
|
||||
@ -354,7 +355,10 @@ def make_etud_args(
|
||||
"""
|
||||
args = None
|
||||
if etudid:
|
||||
args = {"etudid": etudid}
|
||||
try:
|
||||
args = {"etudid": int(etudid)}
|
||||
except ValueError as exc:
|
||||
raise ScoValueError("Adresse invalide") from exc
|
||||
elif code_nip:
|
||||
args = {"code_nip": code_nip}
|
||||
elif use_request: # use form from current request (Flask global)
|
||||
|
@ -49,7 +49,6 @@
|
||||
# sco_cache.EvaluationCache.get(evaluation_id), set(evaluation_id, value), delete(evaluation_id),
|
||||
#
|
||||
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from flask import g
|
||||
@ -198,6 +197,26 @@ class SemInscriptionsCache(ScoDocCache):
|
||||
duration = 12 * 60 * 60 # ttl 12h
|
||||
|
||||
|
||||
class TableRecapCache(ScoDocCache):
|
||||
"""Cache table recap (pour get_table_recap)
|
||||
Clé: formsemestre_id
|
||||
Valeur: le html (<div class="table_recap">...</div>)
|
||||
"""
|
||||
|
||||
prefix = "RECAP"
|
||||
duration = 12 * 60 * 60 # ttl 12h
|
||||
|
||||
|
||||
class TableRecapWithEvalsCache(ScoDocCache):
|
||||
"""Cache table recap (pour get_table_recap)
|
||||
Clé: formsemestre_id
|
||||
Valeur: le html (<div class="table_recap">...</div>)
|
||||
"""
|
||||
|
||||
prefix = "RECAPWITHEVALS"
|
||||
duration = 12 * 60 * 60 # ttl 12h
|
||||
|
||||
|
||||
def invalidate_formsemestre( # was inval_cache(formsemestre_id=None, pdfonly=False)
|
||||
formsemestre_id=None, pdfonly=False
|
||||
):
|
||||
@ -209,7 +228,7 @@ def invalidate_formsemestre( # was inval_cache(formsemestre_id=None, pdfonly=Fa
|
||||
if getattr(g, "defer_cache_invalidation", False):
|
||||
g.sem_to_invalidate.add(formsemestre_id)
|
||||
return
|
||||
log("inval_cache, formsemestre_id=%s pdfonly=%s" % (formsemestre_id, pdfonly))
|
||||
log("inval_cache, formsemestre_id={formsemestre_id} pdfonly={pdfonly}")
|
||||
if formsemestre_id is None:
|
||||
# clear all caches
|
||||
log("----- invalidate_formsemestre: clearing all caches -----")
|
||||
@ -247,6 +266,9 @@ def invalidate_formsemestre( # was inval_cache(formsemestre_id=None, pdfonly=Fa
|
||||
SemInscriptionsCache.delete_many(formsemestre_ids)
|
||||
ResultatsSemestreCache.delete_many(formsemestre_ids)
|
||||
ValidationsSemestreCache.delete_many(formsemestre_ids)
|
||||
TableRecapCache.delete_many(formsemestre_ids)
|
||||
TableRecapWithEvalsCache.delete_many(formsemestre_ids)
|
||||
|
||||
SemBulletinsPDFCache.invalidate_sems(formsemestre_ids)
|
||||
|
||||
|
||||
|
@ -48,6 +48,7 @@ from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_bulletins_json
|
||||
from app.scodoc import sco_bulletins_xml
|
||||
from app.scodoc import sco_bulletins, sco_excel
|
||||
from app.scodoc import sco_cache
|
||||
from app.scodoc import sco_codes_parcours
|
||||
from app.scodoc import sco_evaluations
|
||||
from app.scodoc import sco_evaluation_db
|
||||
@ -1031,8 +1032,35 @@ def gen_formsemestre_recapcomplet_html(
|
||||
formsemestre: FormSemestre, res: NotesTableCompat, include_evaluations=False
|
||||
):
|
||||
"""Construit table recap pour le BUT
|
||||
Cache le résultat pour le semestre.
|
||||
Return: data, filename
|
||||
"""
|
||||
filename = scu.sanitize_filename(
|
||||
f"""recap-{formsemestre.titre_num()}-{time.strftime("%Y-%m-%d")}"""
|
||||
)
|
||||
if include_evaluations:
|
||||
table_html = sco_cache.TableRecapWithEvalsCache.get(formsemestre.id)
|
||||
else:
|
||||
table_html = sco_cache.TableRecapCache.get(formsemestre.id)
|
||||
if table_html is None:
|
||||
table_html = _gen_formsemestre_recapcomplet_html(
|
||||
formsemestre, res, include_evaluations, filename
|
||||
)
|
||||
if include_evaluations:
|
||||
sco_cache.TableRecapWithEvalsCache.set(formsemestre.id, table_html)
|
||||
else:
|
||||
sco_cache.TableRecapCache.set(formsemestre.id, table_html)
|
||||
|
||||
return table_html, filename
|
||||
|
||||
|
||||
def _gen_formsemestre_recapcomplet_html(
|
||||
formsemestre: FormSemestre,
|
||||
res: NotesTableCompat,
|
||||
include_evaluations=False,
|
||||
filename: str = "",
|
||||
) -> str:
|
||||
"""Génère le html"""
|
||||
rows, footer_rows, titles, column_ids = res.get_table_recap(
|
||||
convert_values=True, include_evaluations=include_evaluations
|
||||
)
|
||||
@ -1041,9 +1069,6 @@ def gen_formsemestre_recapcomplet_html(
|
||||
'<div class="table_recap"><div class="message">aucun étudiant !</div></div>',
|
||||
"",
|
||||
)
|
||||
filename = scu.sanitize_filename(
|
||||
f"""recap-{formsemestre.titre_num()}-{time.strftime("%Y-%m-%d")}"""
|
||||
)
|
||||
H = [
|
||||
f"""<div class="table_recap"><table class="table_recap {
|
||||
'apc' if formsemestre.formation.is_apc() else 'classic'}"
|
||||
@ -1074,4 +1099,4 @@ def gen_formsemestre_recapcomplet_html(
|
||||
</div>
|
||||
"""
|
||||
)
|
||||
return ("".join(H), filename) # suffix ?
|
||||
return "".join(H)
|
||||
|
@ -227,7 +227,7 @@ def _user_list(user_name):
|
||||
|
||||
|
||||
@cache.memoize(timeout=50) # seconds
|
||||
def user_info(user_name_or_id=None, user=None):
|
||||
def user_info(user_name_or_id=None, user: User = None):
|
||||
"""Dict avec infos sur l'utilisateur (qui peut ne pas etre dans notre base).
|
||||
Si user_name est specifie (string ou id), interroge la BD. Sinon, user doit etre une instance
|
||||
de User.
|
||||
|
Loading…
Reference in New Issue
Block a user