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 flask import g, url_for
|
||||||
|
|
||||||
|
from app.auth.models import User
|
||||||
from app.comp.res_cache import ResultatsCache
|
from app.comp.res_cache import ResultatsCache
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.moy_mod import ModuleImplResults
|
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 import sco_evaluation_db
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_users
|
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
|
|
||||||
# Il faut bien distinguer
|
# 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>
|
- les colonnes de modules (SAE ou res.) d'une UE ont la classe mod_ue_<ue_id>
|
||||||
_<column_id>_order : clé de tri
|
_<column_id>_order : clé de tri
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if convert_values:
|
if convert_values:
|
||||||
fmt_note = scu.fmt_note
|
fmt_note = scu.fmt_note
|
||||||
else:
|
else:
|
||||||
@ -430,6 +429,7 @@ class ResultatsSemestre(ResultatsCache):
|
|||||||
titles = {}
|
titles = {}
|
||||||
# les titres en footer: les mêmes, mais avec des bulles et liens:
|
# les titres en footer: les mêmes, mais avec des bulles et liens:
|
||||||
titles_bot = {}
|
titles_bot = {}
|
||||||
|
dict_nom_res = {} # cache uid : nomcomplet
|
||||||
|
|
||||||
def add_cell(
|
def add_cell(
|
||||||
row: dict,
|
row: dict,
|
||||||
@ -602,11 +602,14 @@ class ResultatsSemestre(ResultatsCache):
|
|||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
moduleimpl_id=modimpl.id,
|
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[
|
titles_bot[
|
||||||
f"_{col_id}_target_attrs"
|
f"_{col_id}_target_attrs"
|
||||||
] = f"""
|
] = f""" title="{modimpl.module.titre} ({nom_resp})" """
|
||||||
title="{modimpl.module.titre}
|
|
||||||
({sco_users.user_info(modimpl.responsable_id)['nomcomplet']})" """
|
|
||||||
modimpl_ids.add(modimpl.id)
|
modimpl_ids.add(modimpl.id)
|
||||||
ue_valid_txt = f"{nb_ues_validables}/{len(ues_sans_bonus)}"
|
ue_valid_txt = f"{nb_ues_validables}/{len(ues_sans_bonus)}"
|
||||||
if nb_ues_warning:
|
if nb_ues_warning:
|
||||||
|
@ -16,6 +16,7 @@ from app import models
|
|||||||
|
|
||||||
from app.scodoc import notesdb as ndb
|
from app.scodoc import notesdb as ndb
|
||||||
from app.scodoc.sco_bac import Baccalaureat
|
from app.scodoc.sco_bac import Baccalaureat
|
||||||
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
|
|
||||||
|
|
||||||
@ -354,7 +355,10 @@ def make_etud_args(
|
|||||||
"""
|
"""
|
||||||
args = None
|
args = None
|
||||||
if etudid:
|
if etudid:
|
||||||
args = {"etudid": etudid}
|
try:
|
||||||
|
args = {"etudid": int(etudid)}
|
||||||
|
except ValueError as exc:
|
||||||
|
raise ScoValueError("Adresse invalide") from exc
|
||||||
elif code_nip:
|
elif code_nip:
|
||||||
args = {"code_nip": code_nip}
|
args = {"code_nip": code_nip}
|
||||||
elif use_request: # use form from current request (Flask global)
|
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),
|
# sco_cache.EvaluationCache.get(evaluation_id), set(evaluation_id, value), delete(evaluation_id),
|
||||||
#
|
#
|
||||||
|
|
||||||
import time
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from flask import g
|
from flask import g
|
||||||
@ -198,6 +197,26 @@ class SemInscriptionsCache(ScoDocCache):
|
|||||||
duration = 12 * 60 * 60 # ttl 12h
|
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)
|
def invalidate_formsemestre( # was inval_cache(formsemestre_id=None, pdfonly=False)
|
||||||
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):
|
if getattr(g, "defer_cache_invalidation", False):
|
||||||
g.sem_to_invalidate.add(formsemestre_id)
|
g.sem_to_invalidate.add(formsemestre_id)
|
||||||
return
|
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:
|
if formsemestre_id is None:
|
||||||
# clear all caches
|
# clear all caches
|
||||||
log("----- invalidate_formsemestre: clearing 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)
|
SemInscriptionsCache.delete_many(formsemestre_ids)
|
||||||
ResultatsSemestreCache.delete_many(formsemestre_ids)
|
ResultatsSemestreCache.delete_many(formsemestre_ids)
|
||||||
ValidationsSemestreCache.delete_many(formsemestre_ids)
|
ValidationsSemestreCache.delete_many(formsemestre_ids)
|
||||||
|
TableRecapCache.delete_many(formsemestre_ids)
|
||||||
|
TableRecapWithEvalsCache.delete_many(formsemestre_ids)
|
||||||
|
|
||||||
SemBulletinsPDFCache.invalidate_sems(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_json
|
||||||
from app.scodoc import sco_bulletins_xml
|
from app.scodoc import sco_bulletins_xml
|
||||||
from app.scodoc import sco_bulletins, sco_excel
|
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_codes_parcours
|
||||||
from app.scodoc import sco_evaluations
|
from app.scodoc import sco_evaluations
|
||||||
from app.scodoc import sco_evaluation_db
|
from app.scodoc import sco_evaluation_db
|
||||||
@ -1031,8 +1032,35 @@ def gen_formsemestre_recapcomplet_html(
|
|||||||
formsemestre: FormSemestre, res: NotesTableCompat, include_evaluations=False
|
formsemestre: FormSemestre, res: NotesTableCompat, include_evaluations=False
|
||||||
):
|
):
|
||||||
"""Construit table recap pour le BUT
|
"""Construit table recap pour le BUT
|
||||||
|
Cache le résultat pour le semestre.
|
||||||
Return: data, filename
|
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(
|
rows, footer_rows, titles, column_ids = res.get_table_recap(
|
||||||
convert_values=True, include_evaluations=include_evaluations
|
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>',
|
'<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 = [
|
H = [
|
||||||
f"""<div class="table_recap"><table class="table_recap {
|
f"""<div class="table_recap"><table class="table_recap {
|
||||||
'apc' if formsemestre.formation.is_apc() else 'classic'}"
|
'apc' if formsemestre.formation.is_apc() else 'classic'}"
|
||||||
@ -1074,4 +1099,4 @@ def gen_formsemestre_recapcomplet_html(
|
|||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return ("".join(H), filename) # suffix ?
|
return "".join(H)
|
||||||
|
@ -227,7 +227,7 @@ def _user_list(user_name):
|
|||||||
|
|
||||||
|
|
||||||
@cache.memoize(timeout=50) # seconds
|
@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).
|
"""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
|
Si user_name est specifie (string ou id), interroge la BD. Sinon, user doit etre une instance
|
||||||
de User.
|
de User.
|
||||||
|
Loading…
Reference in New Issue
Block a user