nouvelle implementation des caches

This commit is contained in:
Emmanuel Viennet 2021-07-19 20:53:01 +03:00
parent e345561d43
commit 5b2d4e47ec
71 changed files with 840 additions and 970 deletions

View File

@ -4,11 +4,6 @@
import os import os
import sys import sys
# Un hack en attendant la migration vers Python3 #sco8
if sys.version_info.major < 3:
reload(sys)
sys.setdefaultencoding("UTF8")
import logging import logging
from logging.handlers import SMTPHandler, RotatingFileHandler from logging.handlers import SMTPHandler, RotatingFileHandler
@ -22,10 +17,12 @@ from flask_login import LoginManager
from flask_mail import Mail from flask_mail import Mail
from flask_bootstrap import Bootstrap from flask_bootstrap import Bootstrap
from flask_moment import Moment from flask_moment import Moment
from flask_caching import Cache
from config import Config from config import Config
from app.scodoc import notesdb as ndb from app.scodoc import notesdb as ndb
from app.scodoc import sco_cache
app = Flask(__name__) app = Flask(__name__)
app.config.from_object(Config) app.config.from_object(Config)
@ -39,6 +36,8 @@ mail = Mail()
bootstrap = Bootstrap(app) bootstrap = Bootstrap(app)
moment = Moment() moment = Moment()
cache = Cache(config={"CACHE_TYPE": "MemcachedCache"}) # XXX TODO: configuration file
@app.before_request @app.before_request
def open_dept_db_connection(): def open_dept_db_connection():
@ -64,6 +63,8 @@ def create_app(config_class=Config):
mail.init_app(app) mail.init_app(app)
bootstrap.init_app(app) bootstrap.init_app(app)
moment.init_app(app) moment.init_app(app)
cache.init_app(app)
sco_cache.CACHE = cache
from app.auth import bp as auth_bp from app.auth import bp as auth_bp

View File

@ -27,7 +27,7 @@ for sem in sems:
print sem['formsemestre_id'], sem['titre_num'] print sem['formsemestre_id'], sem['titre_num']
# Recupere la table de notes: # Recupere la table de notes:
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id) nt = sco_cache.NotesTableCache.get( formsemestre_id)
""" """
@ -46,9 +46,9 @@ from app.scodoc import html_sco_header
from app.scodoc import sco_archives from app.scodoc import sco_archives
from app.scodoc import sco_bulletins from app.scodoc import sco_bulletins
from app.scodoc import sco_bulletins_xml from app.scodoc import sco_bulletins_xml
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_compute_moy from app.scodoc import sco_compute_moy
from app.scodoc import sco_core
from app.scodoc import sco_edit_matiere from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue

View File

@ -46,7 +46,6 @@ from collections import OrderedDict
from xml.etree import ElementTree from xml.etree import ElementTree
import json import json
from xml.etree import ElementTree
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak
from reportlab.platypus import Table, TableStyle, Image, KeepInFrame from reportlab.platypus import Table, TableStyle, Image, KeepInFrame
from reportlab.lib.colors import Color from reportlab.lib.colors import Color

View File

@ -78,7 +78,7 @@ def sidebar_common(context, REQUEST=None):
def sidebar(context, REQUEST=None): def sidebar(context, REQUEST=None):
"Main HTML page sidebar" "Main HTML page sidebar"
# rewritten from legacy DTML code # rewritten from legacy DTML code
from app.scodoc.sco_abs import getAbsSemEtud from app.scodoc import sco_abs
from app.scodoc import sco_etud from app.scodoc import sco_etud
params = { params = {
@ -114,9 +114,9 @@ def sidebar(context, REQUEST=None):
% params % params
) )
if etud["cursem"]: if etud["cursem"]:
AbsEtudSem = getAbsSemEtud(context, etud["cursem"], etudid) params["nbabs"], params["nbabsjust"] = sco_abs.get_abs_count(
params["nbabs"] = AbsEtudSem.CountAbs() etudid, etud["cursem"]
params["nbabsjust"] = AbsEtudSem.CountAbsJust() )
params["nbabsnj"] = params["nbabs"] - params["nbabsjust"] params["nbabsnj"] = params["nbabs"] - params["nbabsjust"]
params["date_debut"] = etud["cursem"]["date_debut"] params["date_debut"] = etud["cursem"]["date_debut"]
params["date_fin"] = etud["cursem"]["date_fin"] params["date_fin"] = etud["cursem"]["date_fin"]

View File

@ -1,65 +0,0 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""Gestion rudimentaire de cache pour Notes
NOTA: inutilisable dans une instance Zope (can't pickle functions)
"""
from app.scodoc.notes_log import log
class CacheFunc(object):
"""gestion rudimentaire de cache pour une fonction
func doit etre sans effet de bord, et sans arguments nommés
"""
def __init__(self, func):
log("new CacheFunc for %s" % str(func))
self.func = func
self.cache = {} # { arguments : function result }
def __call__(self, *args):
if args in self.cache:
# log('cache hit %s' % str(args))
return self.cache[args]
else:
val = self.func(*args)
self.cache[args] = val
log("caching %s(%s)" % (str(self.func), str(args)))
return val
def inval_cache_entry(self, *args): # >
"expire cache for these args"
log("inval_cache_entry %s(%s)" % (str(self.func), str(args))) # >
del self.cache[args]
def inval_cache(self): # >
"clear whole cache"
log("inval_cache %s" % (str(self.func))) # >
self.cache = {}

View File

@ -36,7 +36,7 @@ from flask import g, url_for
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc.notes_log import log, logCallStack from app.scodoc.notes_log import log
from app.scodoc.sco_formulas import NoteVector from app.scodoc.sco_formulas import NoteVector
from app.scodoc.sco_exceptions import ( from app.scodoc.sco_exceptions import (
AccessDenied, AccessDenied,
@ -57,7 +57,7 @@ from app.scodoc.sco_codes_parcours import (
from app.scodoc.sco_parcours_dut import formsemestre_get_etud_capitalisation from app.scodoc.sco_parcours_dut import formsemestre_get_etud_capitalisation
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_compute_moy from app.scodoc import sco_compute_moy
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_matiere from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
@ -178,12 +178,12 @@ class NotesTable(object):
""" """
def __init__(self, context, formsemestre_id): def __init__(
self, context, formsemestre_id
): # context is not used in ScoDoc8 ! XXX
log("NotesTable( formsemestre_id=%s )" % formsemestre_id) log("NotesTable( formsemestre_id=%s )" % formsemestre_id)
# open('/tmp/cache.log','a').write('NotesTables(%s)\n' % formsemestre_id) # XXX DEBUG
if not formsemestre_id: if not formsemestre_id:
logCallStack() raise ValueError("invalid formsemestre_id (%s)" % formsemestre_id)
raise ScoValueError("invalid formsemestre_id (%s)" % formsemestre_id)
self.context = context self.context = context
self.formsemestre_id = formsemestre_id self.formsemestre_id = formsemestre_id
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
@ -1170,8 +1170,8 @@ class NotesTable(object):
"comp_ue_capitalisees: recomputing UE moy (etudid=%s, ue_id=%s formsemestre_id=%s)" "comp_ue_capitalisees: recomputing UE moy (etudid=%s, ue_id=%s formsemestre_id=%s)"
% (etudid, ue_cap["ue_id"], ue_cap["formsemestre_id"]) % (etudid, ue_cap["ue_id"], ue_cap["formsemestre_id"])
) )
nt_cap = sco_core.get_notes_cache(self.context).get_NotesTable( nt_cap = sco_cache.NotesTableCache.get(
self.context, ue_cap["formsemestre_id"] ue_cap["formsemestre_id"]
) # > UE capitalisees par un etud ) # > UE capitalisees par un etud
moy_ue_cap = nt_cap.get_etud_ue_status(etudid, ue_cap["ue_id"])[ moy_ue_cap = nt_cap.get_etud_ue_status(etudid, ue_cap["ue_id"])[
"moy" "moy"

View File

@ -35,13 +35,13 @@ def unquote(s):
def open_dept_connection(): def open_dept_connection():
"""Open a connection to the current dept db""" """Open a connection to the current dept db"""
# log("open_dept_connection to " + scu.get_db_cnx_string()) # XXX # log("open_dept_connection to " + scu.get_db_cnx_string())
return psycopg2.connect(scu.get_db_cnx_string()) return psycopg2.connect(scu.get_db_cnx_string())
def close_dept_connection(): def close_dept_connection():
"""Commit and close dept db.""" """Commit and close dept db."""
# log("close_dept_connection to " + scu.get_db_cnx_string()) # XXX # log("close_dept_connection to " + scu.get_db_cnx_string())
g.db_conn.commit() g.db_conn.commit()
g.db_conn.close() g.db_conn.close()

View File

@ -54,8 +54,8 @@ import pprint
from app.scodoc.gen_tables import GenTable, SeqGenTable from app.scodoc.gen_tables import GenTable, SeqGenTable
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc import sco_cache
from app.scodoc import sco_codes_parcours # sco_codes_parcours.NEXT -> sem suivant from app.scodoc import sco_codes_parcours # sco_codes_parcours.NEXT -> sem suivant
from app.scodoc import sco_core
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import pe_tagtable from app.scodoc import pe_tagtable
@ -331,7 +331,7 @@ class JuryPE(object):
nt = self.get_cache_notes_d_un_semestre( nt = self.get_cache_notes_d_un_semestre(
self.context, sem["formsemestre_id"] self.context, sem["formsemestre_id"]
) )
# sco_core.get_notes_cache(context).get_NotesTable(context, sem['formsemestre_id']) # sco_cache.NotesTableCache.get( sem['formsemestre_id'])
etudiantsDuSemestre = ( etudiantsDuSemestre = (
nt.get_etudids() nt.get_etudids()
) # nt.identdict.keys() # identification des etudiants du semestre ) # nt.identdict.keys() # identification des etudiants du semestre
@ -1139,9 +1139,7 @@ class JuryPE(object):
self, context, formsemestre_id self, context, formsemestre_id
): # inutile en realité ! ): # inutile en realité !
"""Charge la table des notes d'un formsemestre""" """Charge la table des notes d'un formsemestre"""
return sco_core.get_notes_cache(context).get_NotesTable( return sco_cache.NotesTableCache.get(formsemestre_id)
context, formsemestre_id
)
# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------

View File

@ -38,7 +38,7 @@ Created on Fri Sep 9 09:15:05 2016
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_tag_module from app.scodoc import sco_tag_module
from app.scodoc import pe_tagtable from app.scodoc import pe_tagtable
@ -270,8 +270,8 @@ class SemestreTag(pe_tagtable.TableTag):
# => le formsemestre_id du semestre dont vient la capitalisation # => le formsemestre_id du semestre dont vient la capitalisation
fid_prec = fids_prec[0] fid_prec = fids_prec[0]
# Lecture des notes de ce semestre # Lecture des notes de ce semestre
nt_prec = sco_core.get_notes_cache(self.context).get_NotesTable( nt_prec = sco_cache.NotesTableCache.get(
self.context, fid_prec fid_prec
) # le tableau de note du semestre considéré ) # le tableau de note du semestre considéré
# Y-a-t-il un module équivalent c'est à dire correspondant au même code (le module_id n'étant pas significatif en cas de changement de PPN) # Y-a-t-il un module équivalent c'est à dire correspondant au même code (le module_id n'étant pas significatif en cas de changement de PPN)

View File

@ -39,12 +39,14 @@ import cgi
from scodoc_manager import sco_mgr from scodoc_manager import sco_mgr
from app.scodoc import notesdb as ndb from app.scodoc import notesdb as ndb
from app.scodoc.notes_log import log
from app.scodoc.scolog import logdb from app.scodoc.scolog import logdb
from app.scodoc.sco_exceptions import ScoValueError, ScoInvalidDateError from app.scodoc.sco_exceptions import ScoValueError, ScoInvalidDateError
from app.scodoc import sco_abs_notification from app.scodoc import sco_abs_notification
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
# --- Misc tools.... ------------------ # --- Misc tools.... ------------------
@ -300,9 +302,7 @@ def YearTable(
return "\n".join(T) return "\n".join(T)
def list_abs_in_range( def list_abs_in_range(etudid, debut, fin, matin=None, moduleimpl_id=None, cursor=None):
context, etudid, debut, fin, matin=None, moduleimpl_id=None, cursor=None
):
"""Liste des absences entre deux dates. """Liste des absences entre deux dates.
Args: Args:
@ -347,7 +347,7 @@ WHERE A.ETUDID = %(etudid)s
return res return res
def CountAbs(context, etudid, debut, fin, matin=None, moduleimpl_id=None): def count_abs(etudid, debut, fin, matin=None, moduleimpl_id=None):
"""CountAbs """CountAbs
matin= 1 ou 0. matin= 1 ou 0.
@ -355,13 +355,11 @@ def CountAbs(context, etudid, debut, fin, matin=None, moduleimpl_id=None):
An integer. An integer.
""" """
return len( return len(
list_abs_in_range( list_abs_in_range(etudid, debut, fin, matin=matin, moduleimpl_id=moduleimpl_id)
context, etudid, debut, fin, matin=matin, moduleimpl_id=moduleimpl_id
)
) )
def CountAbsJust(context, etudid, debut, fin, matin=None, moduleimpl_id=None): def count_abs_just(etudid, debut, fin, matin=None, moduleimpl_id=None):
"Count just. abs" "Count just. abs"
if matin != None: if matin != None:
matin = _toboolean(matin) matin = _toboolean(matin)
@ -379,7 +377,7 @@ def CountAbsJust(context, etudid, debut, fin, matin=None, moduleimpl_id=None):
SELECT DISTINCT A.JOUR, A.MATIN SELECT DISTINCT A.JOUR, A.MATIN
FROM ABSENCES A, ABSENCES B FROM ABSENCES A, ABSENCES B
WHERE A.ETUDID = %(etudid)s WHERE A.ETUDID = %(etudid)s
AND A.ETUDID = B.ETUDID AND A.ETUDID = B.ETUDID
AND A.JOUR = B.JOUR AND A.MATIN = B.MATIN AND A.JOUR = B.JOUR AND A.MATIN = B.MATIN
AND A.JOUR BETWEEN %(debut)s AND %(fin)s AND A.JOUR BETWEEN %(debut)s AND %(fin)s
AND A.ESTABS AND (A.ESTJUST OR B.ESTJUST)""" AND A.ESTABS AND (A.ESTJUST OR B.ESTJUST)"""
@ -394,7 +392,7 @@ WHERE A.ETUDID = %(etudid)s
return res return res
def ListeAbsDate(context, etudid, beg_date, end_date): def list_abs_date(etudid, beg_date, end_date):
"""Liste des absences et justifs entre deux dates (inclues).""" """Liste des absences et justifs entre deux dates (inclues)."""
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -436,7 +434,7 @@ def ListeAbsDate(context, etudid, beg_date, end_date):
return R return R
def GetAbsDescription(context, a, cursor=None): def _get_abs_description(a, cursor=None):
"Description associee a l'absence" "Description associee a l'absence"
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
@ -462,7 +460,7 @@ def GetAbsDescription(context, a, cursor=None):
if a["moduleimpl_id"] and a["moduleimpl_id"] != "NULL": if a["moduleimpl_id"] and a["moduleimpl_id"] != "NULL":
# Trouver le nom du module # Trouver le nom du module
Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list( Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
context, moduleimpl_id=a["moduleimpl_id"] None, moduleimpl_id=a["moduleimpl_id"]
) )
if Mlist: if Mlist:
M = Mlist[0] M = Mlist[0]
@ -475,7 +473,7 @@ def GetAbsDescription(context, a, cursor=None):
return "" return ""
def ListeAbsJour(context, date, am=True, pm=True, is_abs=True, is_just=None): def list_abs_jour(date, am=True, pm=True, is_abs=True, is_just=None):
"""Liste des absences et/ou justificatifs ce jour. """Liste des absences et/ou justificatifs ce jour.
is_abs: None (peu importe), True, False is_abs: None (peu importe), True, False
is_just: idem is_just: idem
@ -497,11 +495,11 @@ WHERE A.jour = %(date)s
cursor.execute(req, {"date": date, "is_just": is_just, "is_abs": is_abs}) cursor.execute(req, {"date": date, "is_just": is_just, "is_abs": is_abs})
A = cursor.dictfetchall() A = cursor.dictfetchall()
for a in A: for a in A:
a["description"] = GetAbsDescription(context, a, cursor=cursor) a["description"] = _get_abs_description(a, cursor=cursor)
return A return A
def ListeAbsNonJustJour(context, date, am=True, pm=True): def list_abs_non_just_jour(date, am=True, pm=True):
"Liste des absences non justifiees ce jour" "Liste des absences non justifiees ce jour"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -524,11 +522,11 @@ WHERE B.estjust AND B.jour = %(date)s"""
cursor.execute(req, {"date": date}) cursor.execute(req, {"date": date})
A = cursor.dictfetchall() A = cursor.dictfetchall()
for a in A: for a in A:
a["description"] = GetAbsDescription(context, a, cursor=cursor) a["description"] = _get_abs_description(a, cursor=cursor)
return A return A
def ListeAbsNonJust(context, etudid, datedebut): def list_abs_non_just(etudid, datedebut):
"Liste des absences NON justifiees (par ordre chronologique)" "Liste des absences NON justifiees (par ordre chronologique)"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -546,11 +544,11 @@ ORDER BY JOUR
) )
A = cursor.dictfetchall() A = cursor.dictfetchall()
for a in A: for a in A:
a["description"] = GetAbsDescription(context, a, cursor=cursor) a["description"] = _get_abs_description(a, cursor=cursor)
return A return A
def ListeAbsJust(context, etudid, datedebut): def list_abs_just(etudid, datedebut):
"Liste des absences justifiees (par ordre chronologique)" "Liste des absences justifiees (par ordre chronologique)"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
@ -566,11 +564,11 @@ ORDER BY A.JOUR
) )
A = cursor.dictfetchall() A = cursor.dictfetchall()
for a in A: for a in A:
a["description"] = GetAbsDescription(context, a, cursor=cursor) a["description"] = _get_abs_description(a, cursor=cursor)
return A return A
def ListeJustifs(context, etudid, datedebut, datefin=None, only_no_abs=False): def list_abs_justifs(etudid, datedebut, datefin=None, only_no_abs=False):
"""Liste des justificatifs (sans absence relevée) à partir d'une date, """Liste des justificatifs (sans absence relevée) à partir d'une date,
ou, si datefin spécifié, entre deux dates. ou, si datefin spécifié, entre deux dates.
Si only_no_abs: seulement les justificatifs correspondant aux jours sans absences relevées. Si only_no_abs: seulement les justificatifs correspondant aux jours sans absences relevées.
@ -592,7 +590,7 @@ AND B.ETUDID = %(etudid)s
cursor.execute(req, vars()) cursor.execute(req, vars())
A = cursor.dictfetchall() A = cursor.dictfetchall()
for a in A: for a in A:
a["description"] = GetAbsDescription(context, a, cursor=cursor) a["description"] = _get_abs_description(a, cursor=cursor)
return A return A
@ -627,7 +625,7 @@ def add_absence(
% vars(), % vars(),
) )
cnx.commit() cnx.commit()
invalidateAbsEtudDate(context, etudid, jour) invalidate_abs_etud_date(etudid, jour)
sco_abs_notification.abs_notify(context, etudid, jour) sco_abs_notification.abs_notify(context, etudid, jour)
@ -651,7 +649,7 @@ def add_justif(context, etudid, jour, matin, REQUEST, description=None):
msg="JOUR=%(jour)s,MATIN=%(matin)s" % vars(), msg="JOUR=%(jour)s,MATIN=%(matin)s" % vars(),
) )
cnx.commit() cnx.commit()
invalidateAbsEtudDate(context, etudid, jour) invalidate_abs_etud_date(etudid, jour)
def _add_abslist(context, abslist, REQUEST, moduleimpl_id=None): def _add_abslist(context, abslist, REQUEST, moduleimpl_id=None):
@ -664,7 +662,7 @@ def _add_abslist(context, abslist, REQUEST, moduleimpl_id=None):
else: else:
raise ValueError("invalid ampm !") raise ValueError("invalid ampm !")
# ajoute abs si pas deja absent # ajoute abs si pas deja absent
if CountAbs(context, etudid, jour, jour, matin, moduleimpl_id) == 0: if count_abs(etudid, jour, jour, matin, moduleimpl_id) == 0:
add_absence(context, etudid, jour, matin, 0, REQUEST, "", moduleimpl_id) add_absence(context, etudid, jour, matin, 0, REQUEST, "", moduleimpl_id)
@ -688,7 +686,7 @@ def annule_absence(context, etudid, jour, matin, moduleimpl_id=None, REQUEST=Non
msg="JOUR=%(jour)s,MATIN=%(matin)s,moduleimpl_id=%(moduleimpl_id)s" % vars(), msg="JOUR=%(jour)s,MATIN=%(matin)s,moduleimpl_id=%(moduleimpl_id)s" % vars(),
) )
cnx.commit() cnx.commit()
invalidateAbsEtudDate(context, etudid, jour) invalidate_abs_etud_date(etudid, jour)
def annule_justif(context, etudid, jour, matin, REQUEST=None): def annule_justif(context, etudid, jour, matin, REQUEST=None):
@ -713,7 +711,7 @@ def annule_justif(context, etudid, jour, matin, REQUEST=None):
msg="JOUR=%(jour)s,MATIN=%(matin)s" % vars(), msg="JOUR=%(jour)s,MATIN=%(matin)s" % vars(),
) )
cnx.commit() cnx.commit()
invalidateAbsEtudDate(context, etudid, jour) invalidate_abs_etud_date(etudid, jour)
# ---- BILLETS # ---- BILLETS
@ -976,88 +974,66 @@ def MonthTableBody(
# #
# Cache absences # Cache absences
# #
# On cache simplement (à la demande) le nombre d'absences de chaque etudiant # On cache (via memcached ou autre, voir sco_cache.py) les _nombres_ d'absences
# dans un semestre donné. # (justifiées et non justifiées) de chaque etudiant dans un semestre donné.
# Toute modification du semestre (invalidation) invalide le cache # Le cache peut être invalidé soit par étudiant/semestre, soit pour tous
# (simple mécanisme de "listener" sur le cache de semestres) # les étudiant d'un semestre.
# Toute modification des absences d'un étudiant invalide les caches des semestres
# concernés à cette date (en général un seul semestre)
# #
# On ne cache pas la liste des absences car elle est rarement utilisée (calendrier, # On ne cache pas la liste des absences car elle est rarement utilisée (calendrier,
# absences à une date donnée). # absences à une date donnée).
# #
# -------------------------------------------------------------------- # --------------------------------------------------------------------
class CAbsSemEtud(object):
"""Comptes d'absences d'un etudiant dans un semestre"""
def __init__(self, context, sem, etudid):
self.context = context def get_abs_count(etudid, sem):
self.sem = sem """Les comptes d'absences de cet étudiant dans ce semestre:
self.etudid = etudid tuple (nb abs non justifiées, nb abs justifiées)
self._loaded = False Utilise un cache.
formsemestre_id = sem["formsemestre_id"] """
sco_core.get_notes_cache(context).add_listener( date_debut = sem["date_debut_iso"]
self.invalidate, formsemestre_id, (etudid, formsemestre_id) date_fin = sem["date_fin_iso"]
key = etudid + "_" + date_debut + "_" + date_fin
r = sco_cache.AbsSemEtudCache.get(key)
if not r:
nb_abs = count_abs( # was CountAbs XXX
etudid=etudid,
debut=date_debut,
fin=date_fin,
) )
nb_abs_just = count_abs_just( # XXX was CountAbsJust
def CountAbs(self): etudid=etudid,
if not self._loaded: debut=date_debut,
self.load() fin=date_fin,
return self._CountAbs
def CountAbsJust(self):
if not self._loaded:
self.load()
return self._CountAbsJust
def load(self):
"Load state from DB"
# log('loading CAbsEtudSem(%s,%s)' % (self.etudid, self.sem['formsemestre_id']))
# Reload sem, it may have changed
self.sem = sco_formsemestre.get_formsemestre(
self.context, self.sem["formsemestre_id"]
) )
debut_sem = ndb.DateDMYtoISO(self.sem["date_debut"]) r = (nb_abs, nb_abs_just)
fin_sem = ndb.DateDMYtoISO(self.sem["date_fin"]) ans = sco_cache.AbsSemEtudCache.set(key, r)
if not ans:
log("warning: get_abs_count failed to cache")
return r
self._CountAbs = CountAbs(
self.context, etudid=self.etudid, debut=debut_sem, fin=fin_sem def invalidate_abs_count(etudid, sem):
"""Invalidate (clear) cached counts"""
date_debut = sem["date_debut_iso"]
date_fin = sem["date_fin_iso"]
key = etudid + "_" + date_debut + "_" + date_fin
sco_cache.AbsSemEtudCache.delete(key)
def invalidate_abs_count_sem(sem):
"""Invalidate (clear) cached abs counts for all the students of this semestre"""
inscriptions = (
sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(
None, sem["formsemestre_id"]
) )
self._CountAbsJust = CountAbsJust( )
self.context, etudid=self.etudid, debut=debut_sem, fin=fin_sem for ins in inscriptions:
) invalidate_abs_count(ins["etudid"], sem)
self._loaded = True
def invalidate(self, args=None):
"Notify me that DB has been modified"
# log('invalidate CAbsEtudSem(%s,%s)' % (self.etudid, self.sem['formsemestre_id']))
self._loaded = False
# Accès au cache des absences def invalidate_abs_etud_date(etudid, date): # was invalidateAbsEtudDate
ABS_CACHE_INST = {} # { DeptId : { formsemestre_id : { etudid : CAbsEtudSem } } }
def getAbsSemEtud(context, sem, etudid):
AbsSemEtuds = getAbsSemEtuds(context, sem)
if not etudid in AbsSemEtuds:
AbsSemEtuds[etudid] = CAbsSemEtud(context, sem, etudid)
return AbsSemEtuds[etudid]
def getAbsSemEtuds(context, sem):
u = sco_mgr.get_db_uri() # identifie le dept de facon fiable
if not u in ABS_CACHE_INST:
ABS_CACHE_INST[u] = {}
C = ABS_CACHE_INST[u]
if sem["formsemestre_id"] not in C:
C[sem["formsemestre_id"]] = {}
return C[sem["formsemestre_id"]]
def invalidateAbsEtudDate(context, etudid, date):
"""Doit etre appelé à chaque modification des absences pour cet étudiant et cette date. """Doit etre appelé à chaque modification des absences pour cet étudiant et cette date.
Invalide cache absence et PDF bulletins si nécessaire. Invalide cache absence et caches semestre
date: date au format ISO date: date au format ISO
""" """
from app.scodoc import sco_compute_moy from app.scodoc import sco_compute_moy
@ -1070,23 +1046,21 @@ def invalidateAbsEtudDate(context, etudid, date):
if sem["date_debut_iso"] <= date and sem["date_fin_iso"] >= date if sem["date_debut_iso"] <= date and sem["date_fin_iso"] >= date
] ]
# Invalide les PDF et les abscences: # Invalide les PDF et les absences:
for sem in sems: for sem in sems:
# Inval cache bulletin et/ou note_table # Inval cache bulletin et/ou note_table
if sco_compute_moy.formsemestre_expressions_use_abscounts( if sco_compute_moy.formsemestre_expressions_use_abscounts(
context, sem["formsemestre_id"] None, sem["formsemestre_id"]
): ):
pdfonly = False # seules certaines formules utilisent les absences # certaines formules utilisent les absences
pdfonly = False
else: else:
pdfonly = ( # efface toujours le PDF car il affiche en général les absences
True # efface toujours le PDF car il affiche en général les absences pdfonly = True
)
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, pdfonly=pdfonly, formsemestre_id=sem["formsemestre_id"] formsemestre_id=sem["formsemestre_id"], pdfonly=pdfonly
) )
# Inval cache compteurs absences: # Inval cache compteurs absences:
AbsSemEtuds = getAbsSemEtuds(context, sem) invalidate_abs_count_sem(sem)
if etudid in AbsSemEtuds:
AbsSemEtuds[etudid].invalidate()

View File

@ -62,11 +62,7 @@ def abs_notify(context, etudid, date):
if not sem: if not sem:
return # non inscrit a la date, pas de notification return # non inscrit a la date, pas de notification
debut_sem = ndb.DateDMYtoISO(sem["date_debut"]) nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
fin_sem = ndb.DateDMYtoISO(sem["date_fin"])
nbabs = sco_abs.CountAbs(context, etudid, debut=debut_sem, fin=fin_sem)
nbabsjust = sco_abs.CountAbsJust(context, etudid, debut=debut_sem, fin=fin_sem)
do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust) do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust)

View File

@ -38,7 +38,7 @@ from app.scodoc.scolog import logdb
from app.scodoc.gen_tables import GenTable from app.scodoc.gen_tables import GenTable
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_find_etud from app.scodoc import sco_find_etud
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -123,7 +123,7 @@ def doSignaleAbsence(
if moduleimpl_id and moduleimpl_id != "NULL": if moduleimpl_id and moduleimpl_id != "NULL":
mod = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0] mod = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
formsemestre_id = mod["formsemestre_id"] formsemestre_id = mod["formsemestre_id"]
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id) nt = sco_cache.NotesTableCache.get(formsemestre_id)
ues = nt.get_ues(etudid=etudid) ues = nt.get_ues(etudid=etudid)
for ue in ues: for ue in ues:
modimpls = nt.get_modimpls(ue_id=ue["ue_id"]) modimpls = nt.get_modimpls(ue_id=ue["ue_id"])
@ -182,7 +182,7 @@ def SignaleAbsenceEtud(context, REQUEST=None): # etudid implied
require_module = sco_preferences.get_preference( require_module = sco_preferences.get_preference(
context, "abs_require_module", formsemestre_id context, "abs_require_module", formsemestre_id
) )
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id) nt = sco_cache.NotesTableCache.get(formsemestre_id)
ues = nt.get_ues(etudid=etudid) ues = nt.get_ues(etudid=etudid)
if require_module: if require_module:
menu_module = """ menu_module = """
@ -650,7 +650,7 @@ def AnnuleAbsencesDatesNoJust(context, etudid, dates, moduleimpl_id=None, REQUES
"delete from absences where etudid=%(etudid)s and (not estjust) and jour=%(date)s and moduleimpl_id=%(moduleimpl_id)s", "delete from absences where etudid=%(etudid)s and (not estjust) and jour=%(date)s and moduleimpl_id=%(moduleimpl_id)s",
vars(), vars(),
) )
sco_abs.invalidateAbsEtudDate(context, etudid, date) sco_abs.invalidate_abs_etud_date(etudid, date)
# s'assure que les justificatifs ne sont pas "absents" # s'assure que les justificatifs ne sont pas "absents"
for date in dates: for date in dates:
cursor.execute( cursor.execute(
@ -737,21 +737,19 @@ def CalAbs(context, REQUEST=None): # etud implied
anneescolaire = int(scu.AnneeScolaire(REQUEST)) anneescolaire = int(scu.AnneeScolaire(REQUEST))
datedebut = str(anneescolaire) + "-08-31" datedebut = str(anneescolaire) + "-08-31"
datefin = str(anneescolaire + 1) + "-07-31" datefin = str(anneescolaire + 1) + "-07-31"
nbabs = sco_abs.CountAbs(context, etudid=etudid, debut=datedebut, fin=datefin) nbabs = sco_abs.count_abs(etudid=etudid, debut=datedebut, fin=datefin)
nbabsjust = sco_abs.CountAbsJust( nbabsjust = sco_abs.count_abs_just(etudid=etudid, debut=datedebut, fin=datefin)
context, etudid=etudid, debut=datedebut, fin=datefin
)
events = [] events = []
for a in sco_abs.ListeAbsJust(context, etudid=etudid, datedebut=datedebut): for a in sco_abs.list_abs_just(etudid=etudid, datedebut=datedebut):
events.append( events.append(
(str(a["jour"]), "a", "#F8B7B0", "", a["matin"], a["description"]) (str(a["jour"]), "a", "#F8B7B0", "", a["matin"], a["description"])
) )
for a in sco_abs.ListeAbsNonJust(context, etudid=etudid, datedebut=datedebut): for a in sco_abs.list_abs_non_just(etudid=etudid, datedebut=datedebut):
events.append( events.append(
(str(a["jour"]), "A", "#EE0000", "", a["matin"], a["description"]) (str(a["jour"]), "A", "#EE0000", "", a["matin"], a["description"])
) )
justifs_noabs = sco_abs.ListeJustifs( justifs_noabs = sco_abs.list_abs_justifs(
context, etudid=etudid, datedebut=datedebut, only_no_abs=True etudid=etudid, datedebut=datedebut, only_no_abs=True
) )
for a in justifs_noabs: for a in justifs_noabs:
events.append( events.append(
@ -926,8 +924,8 @@ def _TablesAbsEtud(
REQUEST=None, REQUEST=None,
): ):
"""Tables des absences justifiees et non justifiees d'un étudiant sur l'année en cours""" """Tables des absences justifiees et non justifiees d'un étudiant sur l'année en cours"""
absjust = sco_abs.ListeAbsJust(context, etudid=etudid, datedebut=datedebut) absjust = sco_abs.list_abs_just(etudid=etudid, datedebut=datedebut)
absnonjust = sco_abs.ListeAbsNonJust(context, etudid=etudid, datedebut=datedebut) absnonjust = sco_abs.list_abs_non_just(etudid=etudid, datedebut=datedebut)
# examens ces jours là ? # examens ces jours là ?
if with_evals: if with_evals:
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()

View File

@ -95,10 +95,7 @@ import pprint
from functools import reduce from functools import reduce
# Pour la détection auto de l'encodage des fichiers Apogée: # Pour la détection auto de l'encodage des fichiers Apogée:
try: from chardet import detect as chardet_detect
from chardet import detect as chardet_detect
except:
chardet_detect = None
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
@ -120,8 +117,8 @@ from app.scodoc.sco_codes_parcours import (
NAR, NAR,
RAT, RAT,
) )
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_core
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_status from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_parcours_dut from app.scodoc import sco_parcours_dut
@ -168,11 +165,8 @@ def _apo_fmt_note(note):
def guess_data_encoding(text, threshold=0.6): def guess_data_encoding(text, threshold=0.6):
"""Guess string encoding, using chardet heuristics. """Guess string encoding, using chardet heuristics.
Returns encoding, or None if detection failed (confidence below threshold, Returns encoding, or None if detection failed (confidence below threshold)
or chardet not installed)
""" """
if not chardet_detect:
return None # package not installed
r = chardet_detect(text) r = chardet_detect(text)
if r["confidence"] < threshold: if r["confidence"] < threshold:
return None return None
@ -405,9 +399,7 @@ class ApoEtud(dict):
dict: with N, B, J, R keys, ou None si elt non trouvé dict: with N, B, J, R keys, ou None si elt non trouvé
""" """
etudid = self.etud["etudid"] etudid = self.etud["etudid"]
nt = sco_core.get_notes_cache( nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"])
context,
).get_NotesTable(context, sem["formsemestre_id"])
if etudid not in nt.identdict: if etudid not in nt.identdict:
return None # etudiant non inscrit dans ce semestre return None # etudiant non inscrit dans ce semestre
@ -515,9 +507,7 @@ class ApoEtud(dict):
# l'étudiant n'a pas de semestre courant ?! # l'étudiant n'a pas de semestre courant ?!
log("comp_elt_annuel: %s no cur_sem" % etudid) log("comp_elt_annuel: %s no cur_sem" % etudid)
return VOID_APO_RES return VOID_APO_RES
cur_nt = sco_core.get_notes_cache( cur_nt = sco_cache.NotesTableCache.get(cur_sem["formsemestre_id"])
context,
).get_NotesTable(context, cur_sem["formsemestre_id"])
cur_decision = cur_nt.get_etud_decision_sem(etudid) cur_decision = cur_nt.get_etud_decision_sem(etudid)
if not cur_decision: if not cur_decision:
# pas de decision => pas de résultat annuel # pas de decision => pas de résultat annuel
@ -534,9 +524,7 @@ class ApoEtud(dict):
decision_apo = code_scodoc_to_apo(cur_decision["code"]) decision_apo = code_scodoc_to_apo(cur_decision["code"])
autre_nt = sco_core.get_notes_cache( autre_nt = sco_cache.NotesTableCache.get(autre_sem["formsemestre_id"])
context,
).get_NotesTable(context, autre_sem["formsemestre_id"])
autre_decision = autre_nt.get_etud_decision_sem(etudid) autre_decision = autre_nt.get_etud_decision_sem(etudid)
if not autre_decision: if not autre_decision:
# pas de decision dans l'autre => pas de résultat annuel # pas de decision dans l'autre => pas de résultat annuel
@ -599,9 +587,7 @@ class ApoEtud(dict):
# prend le plus recent avec decision # prend le plus recent avec decision
cur_sem = None cur_sem = None
for sem in cur_sems: for sem in cur_sems:
nt = sco_core.get_notes_cache( nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"])
context,
).get_NotesTable(context, sem["formsemestre_id"])
decision = nt.get_etud_decision_sem(self.etud["etudid"]) decision = nt.get_etud_decision_sem(self.etud["etudid"])
if decision: if decision:
cur_sem = sem cur_sem = sem
@ -661,9 +647,7 @@ class ApoEtud(dict):
else: else:
autre_sem = None autre_sem = None
for sem in autres_sems: for sem in autres_sems:
nt = sco_core.get_notes_cache( nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"])
context,
).get_NotesTable(context, sem["formsemestre_id"])
decision = nt.get_etud_decision_sem(self.etud["etudid"]) decision = nt.get_etud_decision_sem(self.etud["etudid"])
if decision: if decision:
autre_sem = sem autre_sem = sem
@ -998,9 +982,7 @@ class ApoData(object):
s.add(code) s.add(code)
continue continue
# associé à une UE: # associé à une UE:
nt = sco_core.get_notes_cache(self.context).get_NotesTable( nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"])
self.context, sem["formsemestre_id"]
)
for ue in nt.get_ues(): for ue in nt.get_ues():
if code in ue["code_apogee"].split(","): if code in ue["code_apogee"].split(","):
s.add(code) s.add(code)

View File

@ -436,7 +436,7 @@ enregistrés et non modifiables, on peut les retrouver ultérieurement.
"Version intermédiaire", "Version intermédiaire",
"Version complète", "Version complète",
], ],
"allowed_values": ["short", "selectedevals", "long"], "allowed_values": scu.BULLETINS_VERSIONS,
"default": "long", "default": "long",
}, },
), ),

View File

@ -54,7 +54,7 @@ from app.scodoc import sco_bulletins_generator
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_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_formations from app.scodoc import sco_formations
@ -130,13 +130,11 @@ def formsemestre_bulletinetud_dict(
""" """
from app.scodoc import sco_abs from app.scodoc import sco_abs
if not version in ("short", "long", "selectedevals"): if not version in scu.BULLETINS_VERSIONS:
raise ValueError("invalid version code !") raise ValueError("invalid version code !")
prefs = sco_preferences.SemPreferences(context, formsemestre_id) prefs = sco_preferences.SemPreferences(context, formsemestre_id)
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > toutes notes
context, formsemestre_id
) # > toutes notes
I = scu.DictDefault(defaultvalue="") I = scu.DictDefault(defaultvalue="")
I["etudid"] = etudid I["etudid"] = etudid
@ -177,9 +175,7 @@ def formsemestre_bulletinetud_dict(
context, pid context, pid
) )
# --- Absences # --- Absences
AbsSemEtud = sco_abs.getAbsSemEtud(context, nt.sem, etudid) I["nbabs"], I["nbabsjust"] = sco_abs.get_abs_count(etudid, nt.sem)
I["nbabs"] = AbsSemEtud.CountAbs()
I["nbabsjust"] = AbsSemEtud.CountAbsJust()
# --- Decision Jury # --- Decision Jury
infos, dpv = etud_descr_situation_semestre( infos, dpv = etud_descr_situation_semestre(
@ -354,8 +350,8 @@ def formsemestre_bulletinetud_dict(
# log('cap details %s' % ue_status['moy']) # log('cap details %s' % ue_status['moy'])
if ue_status["moy"] != "NA" and ue_status["formsemestre_id"]: if ue_status["moy"] != "NA" and ue_status["formsemestre_id"]:
# detail des modules de l'UE capitalisee # detail des modules de l'UE capitalisee
nt_cap = sco_core.get_notes_cache(context).get_NotesTable( nt_cap = sco_cache.NotesTableCache.get(
context, ue_status["formsemestre_id"] ue_status["formsemestre_id"]
) # > toutes notes ) # > toutes notes
u["modules_capitalized"], _ = _ue_mod_bulletin( u["modules_capitalized"], _ = _ue_mod_bulletin(
@ -442,22 +438,8 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
) # peut etre 'NI' ) # peut etre 'NI'
is_malus = mod["module"]["module_type"] == scu.MODULE_MALUS is_malus = mod["module"]["module_type"] == scu.MODULE_MALUS
if bul_show_abs_modules: if bul_show_abs_modules:
mod_abs = [ nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
sco_abs.CountAbs( mod_abs = [nbabs, nbabsjust]
context,
etudid=etudid,
debut=debut_sem,
fin=fin_sem,
moduleimpl_id=modimpl["moduleimpl_id"],
),
sco_abs.CountAbsJust(
context,
etudid=etudid,
debut=debut_sem,
fin=fin_sem,
moduleimpl_id=modimpl["moduleimpl_id"],
),
]
mod["mod_abs_txt"] = scu.fmt_abs(mod_abs) mod["mod_abs_txt"] = scu.fmt_abs(mod_abs)
else: else:
mod["mod_abs_txt"] = "" mod["mod_abs_txt"] = ""

View File

@ -52,7 +52,7 @@ import reportlab
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak
from reportlab.platypus import Table, TableStyle, Image, KeepInFrame from reportlab.platypus import Table, TableStyle, Image, KeepInFrame
from app.scodoc import sco_utils from app.scodoc import sco_utils as scu
from app.scodoc import VERSION from app.scodoc import VERSION
from app.scodoc.sco_exceptions import NoteProcessError from app.scodoc.sco_exceptions import NoteProcessError
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
@ -117,7 +117,7 @@ class BulletinGenerator(object):
): ):
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
if not version in ("short", "long", "selectedevals"): if not version in scu.BULLETINS_VERSIONS:
raise ValueError("invalid version code !") raise ValueError("invalid version code !")
self.context = context self.context = context
self.infos = infos self.infos = infos
@ -161,7 +161,7 @@ class BulletinGenerator(object):
dt, dt,
self.infos["etud"]["nom"], self.infos["etud"]["nom"],
) )
filename = sco_utils.unescape_html(filename).replace(" ", "_").replace("&", "") filename = scu.unescape_html(filename).replace(" ", "_").replace("&", "")
return filename return filename
def generate(self, format="", stand_alone=True): def generate(self, format="", stand_alone=True):
@ -281,7 +281,7 @@ def make_formsemestre_bulletinetud(
""" """
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
if not version in ("short", "long", "selectedevals"): if not version in scu.BULLETINS_VERSIONS:
raise ValueError("invalid version code !") raise ValueError("invalid version code !")
formsemestre_id = infos["formsemestre_id"] formsemestre_id = infos["formsemestre_id"]

View File

@ -34,7 +34,7 @@ import json
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -151,9 +151,7 @@ def formsemestre_bulletinetud_published_dict(
context, pid context, pid
) )
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > toutes notes
context, formsemestre_id
) # > toutes notes
ues = nt.get_ues() ues = nt.get_ues()
modimpls = nt.get_modimpls() modimpls = nt.get_modimpls()
nbetuds = len(nt.rangs) nbetuds = len(nt.rangs)
@ -341,10 +339,7 @@ def formsemestre_bulletinetud_published_dict(
# --- Absences # --- Absences
if sco_preferences.get_preference(context, "bul_show_abs", formsemestre_id): if sco_preferences.get_preference(context, "bul_show_abs", formsemestre_id):
AbsEtudSem = sco_abs.getAbsSemEtud(context, sem, etudid) nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
nbabs = AbsEtudSem.CountAbs()
nbabsjust = AbsEtudSem.CountAbsJust()
d["absences"] = dict(nbabs=nbabs, nbabsjust=nbabsjust) d["absences"] = dict(nbabs=nbabs, nbabsjust=nbabsjust)
# --- Decision Jury # --- Decision Jury

View File

@ -64,7 +64,7 @@ from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from app.scodoc import VERSION from app.scodoc import VERSION
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_pdf from app.scodoc import sco_pdf
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
@ -170,17 +170,13 @@ def get_formsemestre_bulletins_pdf(
"document pdf et filename" "document pdf et filename"
from app.scodoc import sco_bulletins from app.scodoc import sco_bulletins
cached = sco_core.get_notes_cache( cached = sco_cache.SemBulletinsPDFCache.get(formsemestre_id + "_" + version)
context,
).get_bulletins_pdf(formsemestre_id, version)
if cached: if cached:
return cached[1], cached[0] return cached[1], cached[0]
fragments = [] fragments = []
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
# Make each bulletin # Make each bulletin
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etudids, get_sexnom
context, formsemestre_id
) # > get_etudids, get_sexnom
bookmarks = {} bookmarks = {}
filigrannes = {} filigrannes = {}
i = 1 i = 1
@ -224,9 +220,9 @@ def get_formsemestre_bulletins_pdf(
filename = "bul-%s-%s.pdf" % (sem["titre_num"], dt) filename = "bul-%s-%s.pdf" % (sem["titre_num"], dt)
filename = scu.unescape_html(filename).replace(" ", "_").replace("&", "") filename = scu.unescape_html(filename).replace(" ", "_").replace("&", "")
# fill cache # fill cache
sco_core.get_notes_cache( sco_cache.SemBulletinsPDFCache.set(
context, formsemestre_id + "_" + version, (filename, pdfdoc)
).store_bulletins_pdf(formsemestre_id, version, filename, pdfdoc) )
return pdfdoc, filename return pdfdoc, filename

View File

@ -49,7 +49,7 @@ import app.scodoc.notesdb as ndb
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -144,9 +144,7 @@ def make_xml_formsemestre_bulletinetud(
context, pid context, pid
) )
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > toutes notes
context, formsemestre_id
) # > toutes notes
ues = nt.get_ues() ues = nt.get_ues()
modimpls = nt.get_modimpls() modimpls = nt.get_modimpls()
nbetuds = len(nt.rangs) nbetuds = len(nt.rangs)
@ -352,9 +350,7 @@ def make_xml_formsemestre_bulletinetud(
# --- Absences # --- Absences
if sco_preferences.get_preference(context, "bul_show_abs", formsemestre_id): if sco_preferences.get_preference(context, "bul_show_abs", formsemestre_id):
abs_sem_etud = sco_abs.getAbsSemEtud(context, sem, etudid) nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
nbabs = abs_sem_etud.CountAbs()
nbabsjust = abs_sem_etud.CountAbsJust()
doc.append(Element("absences", nbabs=nbabs, nbabsjust=nbabsjust)) doc.append(Element("absences", nbabs=nbabs, nbabsjust=nbabsjust))
# --- Decision Jury # --- Decision Jury
if ( if (

View File

@ -34,11 +34,11 @@
# API ScoDoc8 pour les caches: # API ScoDoc8 pour les caches:
# sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id) # sco_cache.NotesTableCache.get( formsemestre_id)
# => sco_cache.NotesTableCache.get(formsemestre_id) # => sco_cache.NotesTableCache.get(formsemestre_id)
# #
# sco_core.inval_cache(context, formsemestre_id=None, pdfonly=False, formsemestre_id_list=None) # sco_core.inval_cache(context, formsemestre_id=None, pdfonly=False, formsemestre_id_list=None)
# => deprecated, sco_cache.inval_cache(formsemestre_id=None, pdfonly=False, formsemestre_id_list=None) # => deprecated, NotesTableCache.invalidate_formsemestre(formsemestre_id=None, pdfonly=False)
# #
# #
# Nouvelles fonctions: # Nouvelles fonctions:
@ -54,14 +54,15 @@
# 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),
# #
from collections import defaultdict import time
from flask import g from flask import g
from flask_caching import Cache
from app.scodoc import notesdb as ndb
from app.scodoc import sco_utils as scu
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
CACHE = Cache(config={"CACHE_TYPE": "MemcachedCache"}) # XXX TODO: configuration file CACHE = None # set in app.__init__.py
class ScoDocCache: class ScoDocCache:
@ -69,6 +70,7 @@ class ScoDocCache:
keys are prefixed by the current departement. keys are prefixed by the current departement.
""" """
timeout = None # ttl, infinite by default
prefix = "" prefix = ""
@classmethod @classmethod
@ -83,7 +85,7 @@ class ScoDocCache:
@classmethod @classmethod
def set(cls, oid, value): def set(cls, oid, value):
"""Store evaluation""" """Store evaluation"""
return CACHE.set(cls._get_key(oid), value) return CACHE.set(cls._get_key(oid), value, timeout=cls.timeout)
@classmethod @classmethod
def delete(cls, oid): def delete(cls, oid):
@ -93,86 +95,143 @@ class ScoDocCache:
@classmethod @classmethod
def delete_many(cls, oids): def delete_many(cls, oids):
"""Remove multiple keys at once""" """Remove multiple keys at once"""
CACHE.delete_many(oids) CACHE.delete_many([cls._get_key(oid) for oid in oids])
class EvaluationCache(ScoDocCache): class EvaluationCache(ScoDocCache):
"Cache for evaluations" "Cache for evaluations"
prefix = "EVAL" prefix = "EVAL"
class NotesTableCache(ScoDocCache):
prefix = "NT"
listeners = defaultdict(list) # oid : list of callback functions
@classmethod @classmethod
def add_listener(cls, func, oid): def invalidate_sem(cls, formsemestre_id):
"""Add a function which will be called each time and object is modified: "delete evaluations in this formsemestre from cache"
the function will be called as func(oid) req = """SELECT e.evaluation_id
FROM notes_formsemestre s, notes_evaluation e, notes_moduleimpl m
WHERE s.formsemestre_id = %(formsemestre_id)s and s.formsemestre_id=m.formsemestre_id and e.moduleimpl_id=m.moduleimpl_id;
""" """
cls.listeners[oid].append(func) evaluation_ids = [
x[0]
for x in ndb.SimpleQuery(None, req, {"formsemestre_id": formsemestre_id})
]
cls.delete_many(evaluation_ids)
@classmethod @classmethod
def delete(cls, oid): def invalidate_all_sems(cls):
for listener in cls.listeners[oid]: "delete all evaluations from cache"
listener(oid) evaluation_ids = [
super().delete(oid) x[0]
for x in ndb.SimpleQuery(
@classmethod None, "SELECT evaluation_id FROM notes_evaluation", ""
def delete_many(cls, oids): )
for oid in oids: ]
for listener in cls.listeners[oid]: cls.delete_many(evaluation_ids)
listener(oid)
super().delete_many(oids)
# XXX OBSOLETE A ENLEVER XXX class AbsSemEtudCache(ScoDocCache):
class simpleCache: """Cache pour les comptes d'absences d'un étudiant dans un semestre.
"""A simple cache wich cache data for a most "duration" seconds.""" Ce cache étant indépendant des semestre, le compte peut être faux lorsqu'on
change les dates début/fin d'un semestre.
def __init__(self): C'est pourquoi il expire après timeout secondes.
self.cache = {} Le timeout evite aussi d'éliminer explicitement ces éléments cachés lors
self.inval_cache() # > des suppressions d'étudiants ou de semestres.
def inval_cache(self, key=None): # >
if key:
if key in self.cache:
del self.cache[key]
else:
# clear all entries
self.cache = {} # key : data
def set(self, key, data):
self.cache[key] = data
def get(self, key):
"""returns None if not in cache"""
return self.cache.get(key, None)
class expiringCache(simpleCache):
"""A simple cache wich cache data for a most "duration" seconds.
This is used for users (which may be updated from external
information systems)
""" """
def __init__(self, max_validity=60): timeout = 60 * 60 # ttl 60 minutes
simpleCache.__init__(self)
self.max_validity = max_validity
def set(self, key, data):
simpleCache.set(self, key, (data, time.time()))
def get(self, key): class SemBulletinsPDFCache(ScoDocCache):
info = simpleCache.get(self, key) """Cache pour les classeurs de bulletins PDF d'un semestre.
if info: Document pdf assez volumineux. La clé inclut le type de bulletin (version).
data, t = info Clé: formsemestre_id_version
if time.time() - t < self.max_validity: Valeur: (filename, pdfdoc)
return data """
else:
# expired prefix = "SBPDF"
self.inval_cache(key) # > timeout = 12 * 60 * 60 # ttl 12h
return None
@classmethod
def invalidate_sems(cls, formsemestre_ids):
"""Clear cached pdf for all given formsemestres"""
for version in scu.BULLETINS_VERSIONS:
oids = [
formsemestre_id + "_" + version for formsemestre_id in formsemestre_ids
]
cls.delete_many(oids)
class SemInscriptionsCache(ScoDocCache):
"""Cache les inscriptions à un semestre.
Clé: formsemestre_id
Valeur: liste d'inscriptions
[ {'formsemestre_inscription_id': 'SI78677', 'etudid': '1234', 'formsemestre_id': 'SEM012', 'etat': 'I', 'etape': ''}, ... ]
"""
prefix = "SI"
duration = 12 * 60 * 60 # ttl 12h
class NotesTableCache(ScoDocCache):
"""Cache pour les NotesTable
Clé: formsemestre_id
Valeur: NotesTable instance
"""
prefix = "NT"
@classmethod
def get(cls, formsemestre_id):
"""Returns NotesTable for this formsemestre
If not in cache, build it and cache it.
"""
key = cls._get_key(formsemestre_id)
nt = CACHE.get(key)
if nt:
return nt
from app.scodoc import notes_table
t0 = time.time()
nt = notes_table.NotesTable(None, formsemestre_id)
dt = time.time() - t0
log("caching formsemestre_id=%s (%gs)" % (formsemestre_id, dt))
s = cls.set(formsemestre_id, nt)
if not s:
log("Warning: cache.set failed")
return nt
def invalidate_formsemestre( # was inval_cache( context, formsemestre_id=None, pdfonly=False)
formsemestre_id=None, pdfonly=False
):
"""expire cache pour un semestre (ou tous si formsemestre_id non spécifié).
Si pdfonly, n'expire que les bulletins pdf cachés.
"""
from app.scodoc import sco_parcours_dut
log("inval_cache, formsemestre_id=%s pdfonly=%s" % (formsemestre_id, pdfonly))
if formsemestre_id is None:
# clear all caches
log("----- invalidate_formsemestre: clearing all caches -----")
formsemestre_ids = [
x[0]
for x in ndb.SimpleQuery(
None, "SELECT formsemestre_id FROM notes_formsemestre", ""
)
]
else:
formsemestre_ids = [
formsemestre_id
] + sco_parcours_dut.list_formsemestre_utilisateurs_uecap(None, formsemestre_id)
log(f"----- invalidate_formsemestre: clearing {formsemestre_ids} -----")
if not pdfonly:
# Delete cached notes and evaluations
NotesTableCache.delete_many(formsemestre_ids)
if formsemestre_id:
for formsemestre_id in formsemestre_ids:
EvaluationCache.invalidate_sem(formsemestre_id)
else: else:
return None # not in cache # optimization when we invalidate all evaluations:
EvaluationCache.invalidate_all_sems()
SemInscriptionsCache.delete_many(formsemestre_ids)
SemBulletinsPDFCache.invalidate_sems(formsemestre_ids)

View File

@ -138,9 +138,7 @@ def compute_user_formula(
Retourne moy, et en cas d'erreur met à jour diag_info (msg) Retourne moy, et en cas d'erreur met à jour diag_info (msg)
""" """
if use_abs: if use_abs:
AbsSemEtud = sco_abs.getAbsSemEtud(context, sem, etudid) nbabs, nbabs_just = sco_abs.get_abs_count(etudid, sem)
nbabs = AbsSemEtud.CountAbs()
nbabs_just = AbsSemEtud.CountAbsJust()
else: else:
nbabs, nbabs_just = 0, 0 nbabs, nbabs_just = 0, 0
try: try:

View File

@ -67,7 +67,7 @@ CONFIG.compute_bonus = bonus_sport.bonus_iutv
# - règle "LMD": capitalisation uniquement des UE avec moy. > 10 # - règle "LMD": capitalisation uniquement des UE avec moy. > 10
# Si vrai, capitalise toutes les UE des semestres validés (règle "DUT"). # Si vrai, capitalise toutes les UE des semestres validés (règle "DUT").
# CONFIG.CAPITALIZE_ALL_UES = True CONFIG.CAPITALIZE_ALL_UES = True
# ----------------------------------------------------- # -----------------------------------------------------
# -------------- Personnalisation des pages # -------------- Personnalisation des pages

View File

@ -27,19 +27,6 @@ from app.scodoc import sco_cache
NOTES_CACHE_INST = {} # { db_cnx_string : CacheNotesTable instance } NOTES_CACHE_INST = {} # { db_cnx_string : CacheNotesTable instance }
# XXX OBSOLETE... XXX # XXX OBSOLETE... XXX
CACHE_formsemestre_inscription = {}
CACHE_evaluations = {}
# cache notes evaluations
def get_evaluations_cache(context):
"""returns cache for evaluations"""
u = sco_mgr.get_db_uri()
if u in CACHE_evaluations:
return CACHE_evaluations[u]
else:
log("get_evaluations_cache: new simpleCache")
CACHE_evaluations[u] = sco_cache.simpleCache()
return CACHE_evaluations[u]
class CacheNotesTable(object): class CacheNotesTable(object):
@ -112,67 +99,11 @@ class CacheNotesTable(object):
finally: finally:
self.release() self.release()
def get_cached_formsemestre_ids(self): # UNUSED
"List of currently cached formsemestre_id"
return list(self.cache.keys())
def inval_cache(self, context, formsemestre_id=None, pdfonly=False): # > def inval_cache(self, context, formsemestre_id=None, pdfonly=False): # >
"expire cache pour un semestre (ou tous si pas d'argument)" "expire cache pour un semestre (ou tous si pas d'argument)"
from app.scodoc import sco_parcours_dut from app.scodoc import sco_parcours_dut
log( XXX
"inval_cache, formsemestre_id=%s pdfonly=%s (id=%s)"
% (formsemestre_id, pdfonly, id(self)) # >
)
try:
self.acquire()
if formsemestre_id is None:
# clear all caches
log("----- inval_cache: clearing all caches -----")
# log('cache was containing ' + str(self.cache.keys()))
# logCallStack() # >>> DEBUG <<<
if not pdfonly:
self.cache = {}
self.pdfcache = {}
self._call_all_listeners()
get_evaluations_cache(
context,
).inval_cache()
else:
# formsemestre_id modifié:
# on doit virer formsemestre_id et tous les semestres
# susceptibles d'utiliser des UE capitalisées de ce semestre.
to_trash = [
formsemestre_id
] + sco_parcours_dut.list_formsemestre_utilisateurs_uecap(
context, formsemestre_id
)
if not pdfonly:
for formsemestre_id in to_trash:
if formsemestre_id in self.cache:
log(
"delete %s from cache (id=%s)"
% (formsemestre_id, id(self))
)
del self.cache[formsemestre_id]
self._call_listeners(formsemestre_id)
get_evaluations_cache(
context,
).inval_cache()
for formsemestre_id in to_trash:
for (
cached_formsemestre_id,
cached_version,
) in self.pdfcache.keys():
if cached_formsemestre_id == formsemestre_id:
log(
"delete pdfcache[(%s,%s)]"
% (formsemestre_id, cached_version)
)
del self.pdfcache[(formsemestre_id, cached_version)]
finally:
self.release()
def store_bulletins_pdf(self, formsemestre_id, version, filename, pdfdoc): def store_bulletins_pdf(self, formsemestre_id, version, filename, pdfdoc):
"cache pdf data" "cache pdf data"

View File

@ -40,7 +40,7 @@ from app.scodoc.scolog import logdb
from app.scodoc.gen_tables import GenTable from app.scodoc.gen_tables import GenTable
from app.scodoc import safehtml from app.scodoc import safehtml
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_permissions_check from app.scodoc import sco_permissions_check
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_tag_module from app.scodoc import sco_tag_module
@ -114,9 +114,7 @@ def table_debouche_etudids(context, etudids, keep_numeric=True):
es = [(s["date_fin_iso"], i) for i, s in enumerate(sems)] es = [(s["date_fin_iso"], i) for i, s in enumerate(sems)]
imax = max(es)[1] imax = max(es)[1]
last_sem = sems[imax] last_sem = sems[imax]
nt = sco_core.get_notes_cache( nt = sco_cache.NotesTableCache.get(last_sem["formsemestre_id"])
context,
).get_NotesTable(context, last_sem["formsemestre_id"])
row = { row = {
"etudid": etudid, "etudid": etudid,
"civilite": etud["civilite"], "civilite": etud["civilite"],

View File

@ -33,9 +33,10 @@ import app.scodoc.sco_utils as scu
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
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_core
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_formations from app.scodoc import sco_formations
@ -302,13 +303,16 @@ def do_formation_edit(context, args):
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
sco_formations._formationEditor.edit(cnx, args) sco_formations._formationEditor.edit(cnx, args)
invalidate_sems_in_formation(args["formation_id"])
# Invalide les semestres utilisant cette formation:
def invalidate_sems_in_formation(formation_id):
"Invalide les semestres utilisant cette formation"
for sem in sco_formsemestre.do_formsemestre_list( for sem in sco_formsemestre.do_formsemestre_list(
context, args={"formation_id": args["formation_id"]} None, args={"formation_id": formation_id}
): ):
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=sem["formsemestre_id"] formsemestre_id=sem["formsemestre_id"]
) # > formation modif. ) # > formation modif.

View File

@ -34,7 +34,6 @@ from app.scodoc.notes_log import log
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_core
_matiereEditor = ndb.EditableTable( _matiereEditor = ndb.EditableTable(
"notes_matieres", "notes_matieres",
@ -53,6 +52,9 @@ def do_matiere_list(context, *args, **kw):
def do_matiere_edit(context, *args, **kw): def do_matiere_edit(context, *args, **kw):
"edit a matiere" "edit a matiere"
from app.scodoc import sco_edit_ue
from app.scodoc import sco_edit_formation
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
# check # check
mat = do_matiere_list(context, {"matiere_id": args[0]["matiere_id"]})[0] mat = do_matiere_list(context, {"matiere_id": args[0]["matiere_id"]})[0]
@ -60,7 +62,10 @@ def do_matiere_edit(context, *args, **kw):
raise ScoLockedFormError() raise ScoLockedFormError()
# edit # edit
_matiereEditor.edit(cnx, *args, **kw) _matiereEditor.edit(cnx, *args, **kw)
sco_core.inval_cache(context) # > modif matiere formation_id = sco_edit_ue.do_ue_list(None, {"ue_id": mat["ue_id"]})[0][
"formation_id"
]
sco_edit_formation.invalidate_sems_in_formation(formation_id)
def do_matiere_create(context, args, REQUEST): def do_matiere_create(context, args, REQUEST):

View File

@ -36,9 +36,7 @@ from app.scodoc.sco_permissions import Permission
from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError, ScoGenError from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError, ScoGenError
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core
from app.scodoc import sco_edit_matiere from app.scodoc import sco_edit_matiere
from app.scodoc import sco_formsemestre
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
from app.scodoc import sco_news from app.scodoc import sco_news
@ -319,6 +317,8 @@ def module_delete(context, module_id=None, REQUEST=None):
def do_module_edit(context, val): def do_module_edit(context, val):
"edit a module" "edit a module"
from app.scodoc import sco_edit_formation
# check # check
mod = do_module_list(context, {"module_id": val["module_id"]})[0] mod = do_module_list(context, {"module_id": val["module_id"]})[0]
if module_is_locked(context, mod["module_id"]): if module_is_locked(context, mod["module_id"]):
@ -330,14 +330,7 @@ def do_module_edit(context, val):
# edit # edit
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
_moduleEditor.edit(cnx, val) _moduleEditor.edit(cnx, val)
sco_edit_formation.invalidate_sems_in_formation(mod["formation_id"])
sems = sco_formsemestre.do_formsemestre_list(
context, args={"formation_id": mod["formation_id"]}
)
if sems:
sco_core.inval_cache(
context, formsemestre_id_list=[s["formsemestre_id"] for s in sems]
) # > modif module
def check_module_code_unicity(code, field, formation_id, context, module_id=None): def check_module_code_unicity(code, field, formation_id, context, module_id=None):

View File

@ -37,10 +37,12 @@ from app.scodoc.sco_permissions import Permission
from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError from app.scodoc.sco_exceptions import ScoValueError, ScoLockedFormError
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
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_core from app.scodoc import sco_edit_formation
from app.scodoc import sco_edit_matiere from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_etud
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
@ -48,7 +50,6 @@ from app.scodoc import sco_news
from app.scodoc import sco_permissions from app.scodoc import sco_permissions
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_tag_module from app.scodoc import sco_tag_module
from app.scodoc import sco_etud
_ueEditor = ndb.EditableTable( _ueEditor = ndb.EditableTable(
"notes_ue", "notes_ue",
@ -164,7 +165,7 @@ def do_ue_delete(context, ue_id, delete_validations=False, REQUEST=None, force=F
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
_ueEditor.delete(cnx, ue_id) _ueEditor.delete(cnx, ue_id)
# > UE delete + supr. validations associées etudiants (cas compliqué, mais rarement utilisé: acceptable de tout invalider ?): # > UE delete + supr. validations associées etudiants (cas compliqué, mais rarement utilisé: acceptable de tout invalider ?):
sco_core.inval_cache(context) sco_cache.invalidate_formsemestre()
# news # news
F = sco_formations.formation_list( F = sco_formations.formation_list(
context, args={"formation_id": ue["formation_id"]} context, args={"formation_id": ue["formation_id"]}
@ -918,12 +919,7 @@ def do_ue_edit(context, args, bypass_lock=False, dont_invalidate_cache=False):
if not dont_invalidate_cache: if not dont_invalidate_cache:
# Invalide les semestres utilisant cette formation: # Invalide les semestres utilisant cette formation:
for sem in sco_formsemestre.do_formsemestre_list( sco_edit_formation.invalidate_sems_in_formation(ue["formation_id"])
context, args={"formation_id": ue["formation_id"]}
):
sco_core.inval_cache(
context, formsemestre_id=sem["formsemestre_id"]
) # > formation (ue) modif.
# essai edition en ligne: # essai edition en ligne:

View File

@ -389,7 +389,7 @@ apo_csv_store(context, csv_data, annee_scolaire, sem_id)
groups_infos = sco_groups_view.DisplayedGroupsInfos(context, [sco_groups.get_default_group(context, formsemestre_id)], formsemestre_id=formsemestre_id, REQUEST=REQUEST) groups_infos = sco_groups_view.DisplayedGroupsInfos(context, [sco_groups.get_default_group(context, formsemestre_id)], formsemestre_id=formsemestre_id, REQUEST=REQUEST)
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id) nt = sco_cache.NotesTableCache.get( formsemestre_id)
# #
s = SemSet(context, 'NSS29902') s = SemSet(context, 'NSS29902')

View File

@ -42,7 +42,7 @@ from app.scodoc.gen_tables import GenTable
from app.scodoc.TrivialFormulator import TrivialFormulator from app.scodoc.TrivialFormulator import TrivialFormulator
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -345,9 +345,7 @@ def do_evaluation_edit(context, REQUEST, args):
_evaluationEditor.edit(cnx, args) _evaluationEditor.edit(cnx, args)
# inval cache pour ce semestre # inval cache pour ce semestre
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
sco_core.inval_cache( sco_cache.invalidate_formsemestre(formsemestre_id=M["formsemestre_id"])
context, formsemestre_id=M["formsemestre_id"]
) # > evaluation_edit (coef, ...)
def do_evaluation_delete(context, REQUEST, evaluation_id): def do_evaluation_delete(context, REQUEST, evaluation_id):
@ -375,7 +373,7 @@ def do_evaluation_delete(context, REQUEST, evaluation_id):
_evaluationEditor.delete(cnx, evaluation_id) _evaluationEditor.delete(cnx, evaluation_id)
# inval cache pour ce semestre # inval cache pour ce semestre
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
sco_core.inval_cache(context, formsemestre_id=M["formsemestre_id"]) # > eval delete sco_cache.invalidate_formsemestre(formsemestre_id=M["formsemestre_id"])
# news # news
mod = sco_edit_module.do_module_list(context, args={"module_id": M["module_id"]})[0] mod = sco_edit_module.do_module_list(context, args={"module_id": M["module_id"]})[0]
mod["moduleimpl_id"] = M["moduleimpl_id"] mod["moduleimpl_id"] = M["moduleimpl_id"]
@ -643,8 +641,7 @@ def do_evaluation_get_all_notes(
filter_suppressed and table == "notes_notes" and (by_uid is None) filter_suppressed and table == "notes_notes" and (by_uid is None)
) # pas de cache pour (rares) appels via undo_notes ou specifiant un enseignant ) # pas de cache pour (rares) appels via undo_notes ou specifiant un enseignant
if do_cache: if do_cache:
cache = sco_core.get_evaluations_cache(context) r = sco_cache.EvaluationCache.get(evaluation_id)
r = cache.get(evaluation_id)
if r != None: if r != None:
return r return r
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
@ -667,7 +664,7 @@ def do_evaluation_get_all_notes(
for x in res: for x in res:
d[x["etudid"]] = x d[x["etudid"]] = x
if do_cache: if do_cache:
cache.set(evaluation_id, d) sco_cache.EvaluationCache.set(evaluation_id, d)
return d return d
@ -708,8 +705,8 @@ def _eval_etat(evals):
def do_evaluation_etat_in_sem(context, formsemestre_id, REQUEST=None): def do_evaluation_etat_in_sem(context, formsemestre_id, REQUEST=None):
"""-> nb_eval_completes, nb_evals_en_cours, nb_evals_vides, """-> nb_eval_completes, nb_evals_en_cours, nb_evals_vides,
date derniere modif, attente""" date derniere modif, attente"""
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, formsemestre_id formsemestre_id
) # > liste evaluations et moduleimpl en attente ) # > liste evaluations et moduleimpl en attente
evals = nt.get_sem_evaluation_etat_list() evals = nt.get_sem_evaluation_etat_list()
etat = _eval_etat(evals) etat = _eval_etat(evals)
@ -731,9 +728,7 @@ def do_evaluation_etat_in_mod(context, nt, moduleimpl_id):
def formsemestre_evaluations_cal(context, formsemestre_id, REQUEST=None): def formsemestre_evaluations_cal(context, formsemestre_id, REQUEST=None):
"""Page avec calendrier de toutes les evaluations de ce semestre""" """Page avec calendrier de toutes les evaluations de ce semestre"""
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > liste evaluations
context, formsemestre_id
) # > liste evaluations
evals = nt.get_sem_evaluation_etat_list() evals = nt.get_sem_evaluation_etat_list()
nb_evals = len(evals) nb_evals = len(evals)
@ -873,9 +868,7 @@ def formsemestre_evaluations_delai_correction(
N'indique pas les évaluations de ratrapage ni celles des modules de bonus/malus. N'indique pas les évaluations de ratrapage ni celles des modules de bonus/malus.
""" """
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > liste evaluations
context, formsemestre_id
) # > liste evaluations
evals = nt.get_sem_evaluation_etat_list() evals = nt.get_sem_evaluation_etat_list()
T = [] T = []

View File

@ -35,7 +35,7 @@ from app.scodoc.notes_log import log
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_bac from app.scodoc import sco_bac
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_formations from app.scodoc import sco_formations
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_pvjury from app.scodoc import sco_pvjury
@ -77,9 +77,7 @@ def _build_results_table(context, start_date=None, end_date=None, types_parcours
{} {}
) # etudid : { formsemestre_id d'inscription le plus recent dans les dates considérées, etud } ) # etudid : { formsemestre_id d'inscription le plus recent dans les dates considérées, etud }
for formsemestre_id in formsemestre_ids_parcours: for formsemestre_id in formsemestre_ids_parcours:
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etudids
context, formsemestre_id
) # > get_etudids
etudids = nt.get_etudids() etudids = nt.get_etudids()
for etudid in etudids: for etudid in etudids:
if etudid not in etuds_infos: # pas encore traité ? if etudid not in etuds_infos: # pas encore traité ?

View File

@ -32,7 +32,7 @@ from operator import itemgetter
from scodoc_manager import sco_mgr from scodoc_manager import sco_mgr
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_formations from app.scodoc import sco_formations
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_users from app.scodoc import sco_users
@ -131,7 +131,6 @@ def formsemestre_enrich(context, sem):
# imports ici pour eviter refs circulaires # imports ici pour eviter refs circulaires
from app.scodoc import sco_formsemestre_edit from app.scodoc import sco_formsemestre_edit
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.views import notes
F = sco_formations.formation_list( F = sco_formations.formation_list(
context, args={"formation_id": sem["formation_id"]} context, args={"formation_id": sem["formation_id"]}
@ -268,8 +267,8 @@ def do_formsemestre_edit(context, sem, cnx=None, **kw):
write_formsemestre_etapes(context, sem) write_formsemestre_etapes(context, sem)
write_formsemestre_responsables(context, sem) write_formsemestre_responsables(context, sem)
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=sem["formsemestre_id"] formsemestre_id=sem["formsemestre_id"]
) # > modif formsemestre ) # > modif formsemestre

View File

@ -32,7 +32,7 @@ from app.auth.models import User
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc.TrivialFormulator import TrivialFormulator, TF from app.scodoc.TrivialFormulator import TrivialFormulator, TF
@ -1375,6 +1375,8 @@ def do_formsemestre_delete(context, formsemestre_id, REQUEST):
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
sco_cache.EvaluationCache.invalidate_sem(formsemestre_id)
# --- Destruction des modules de ce semestre # --- Destruction des modules de ce semestre
mods = sco_moduleimpl.do_moduleimpl_list(context, formsemestre_id=formsemestre_id) mods = sco_moduleimpl.do_moduleimpl_list(context, formsemestre_id=formsemestre_id)
for mod in mods: for mod in mods:
@ -1398,9 +1400,6 @@ def do_formsemestre_delete(context, formsemestre_id, REQUEST):
"DELETE FROM notes_evaluation WHERE evaluation_id=%(evaluation_id)s", "DELETE FROM notes_evaluation WHERE evaluation_id=%(evaluation_id)s",
e, e,
) )
sco_core.get_evaluations_cache(
context,
).inval_cache(key=e["evaluation_id"])
sco_moduleimpl.do_moduleimpl_delete( sco_moduleimpl.do_moduleimpl_delete(
context, mod["moduleimpl_id"], formsemestre_id=formsemestre_id context, mod["moduleimpl_id"], formsemestre_id=formsemestre_id
@ -1706,8 +1705,8 @@ def formsemestre_edit_uecoefs(context, formsemestre_id, err_ue_id=None, REQUEST=
z.append("</ul>") z.append("</ul>")
else: else:
z = ["""<h3>Aucune modification</h3>"""] z = ["""<h3>Aucune modification</h3>"""]
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > modif coef UE cap (modifs notes de _certains_ etudiants) ) # > modif coef UE cap (modifs notes de _certains_ etudiants)
header = html_sco_header.html_sem_header( header = html_sco_header.html_sem_header(

View File

@ -40,7 +40,7 @@ import app.scodoc.notesdb as ndb
from app.scodoc.sco_utils import log from app.scodoc.sco_utils import log
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_formations from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -267,9 +267,7 @@ def formsemestre_ext_edit_ue_validations(
def _make_page(context, etud, sem, tf, message="", REQUEST=None): def _make_page(context, etud, sem, tf, message="", REQUEST=None):
nt = sco_core.get_notes_cache( nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"])
context,
).get_NotesTable(context, sem["formsemestre_id"])
moy_gen = nt.get_etud_moy_gen(etud["etudid"]) moy_gen = nt.get_etud_moy_gen(etud["etudid"])
H = [ H = [
html_sco_header.sco_header( html_sco_header.sco_header(

View File

@ -44,7 +44,7 @@ from app.scodoc import sco_formsemestre
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
@ -65,14 +65,13 @@ def do_formsemestre_inscription_list(context, *args, **kw):
def do_formsemestre_inscription_listinscrits(context, formsemestre_id): def do_formsemestre_inscription_listinscrits(context, formsemestre_id):
"""Liste les inscrits (état I) à ce semestre et cache le résultat""" """Liste les inscrits (état I) à ce semestre et cache le résultat"""
cache = sco_core.get_formsemestre_inscription_cache(context) r = sco_cache.SemInscriptionsCache.get(formsemestre_id)
r = cache.get(formsemestre_id)
if r is None: if r is None:
# retreive list # retreive list
r = do_formsemestre_inscription_list( r = do_formsemestre_inscription_list(
context, args={"formsemestre_id": formsemestre_id, "etat": "I"} context, args={"formsemestre_id": formsemestre_id, "etat": "I"}
) )
cache.set(formsemestre_id, r) sco_cache.SemInscriptionsCache.set(formsemestre_id, r)
return r return r
@ -111,8 +110,8 @@ def do_formsemestre_inscription_create(context, args, REQUEST, method=None):
commit=False, commit=False,
) )
# #
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=args["formsemestre_id"] formsemestre_id=args["formsemestre_id"]
) # > inscription au semestre ) # > inscription au semestre
return r return r
@ -122,8 +121,8 @@ def do_formsemestre_inscription_delete(context, oid, formsemestre_id=None):
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
_formsemestre_inscriptionEditor.delete(cnx, oid) _formsemestre_inscriptionEditor.delete(cnx, oid)
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > desinscription du semestre ) # > desinscription du semestre
@ -131,8 +130,8 @@ def do_formsemestre_inscription_edit(context, args=None, formsemestre_id=None):
"edit a formsemestre_inscription" "edit a formsemestre_inscription"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
_formsemestre_inscriptionEditor.edit(cnx, args) _formsemestre_inscriptionEditor.edit(cnx, args)
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > modif inscription semestre (demission ?) ) # > modif inscription semestre (demission ?)
@ -148,7 +147,7 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non
raise ScoValueError("desinscription impossible: semestre verrouille") raise ScoValueError("desinscription impossible: semestre verrouille")
# -- Si decisions de jury, desinscription interdite # -- Si decisions de jury, desinscription interdite
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id) nt = sco_cache.NotesTableCache.get(formsemestre_id)
if nt.etud_has_decision(etudid): if nt.etud_has_decision(etudid):
raise ScoValueError( raise ScoValueError(
"desinscription impossible: l'étudiant a une décision de jury (la supprimer avant si nécessaire)" "desinscription impossible: l'étudiant a une décision de jury (la supprimer avant si nécessaire)"
@ -452,9 +451,7 @@ def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=No
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etud_ue_status
context, formsemestre_id
) # > get_etud_ue_status
F = html_sco_header.sco_footer(context, REQUEST) F = html_sco_header.sco_footer(context, REQUEST)
H = [ H = [
@ -763,9 +760,7 @@ def list_inscrits_ailleurs(context, formsemestre_id):
Pour chacun, donne la liste des semestres. Pour chacun, donne la liste des semestres.
{ etudid : [ liste de sems ] } { etudid : [ liste de sems ] }
""" """
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etudids
context, formsemestre_id
) # > get_etudids
etudids = nt.get_etudids() etudids = nt.get_etudids()
d = {} d = {}
for etudid in etudids: for etudid in etudids:

View File

@ -48,7 +48,7 @@ from app.scodoc import sco_archives
from app.scodoc import sco_bulletins from app.scodoc import sco_bulletins
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_compute_moy from app.scodoc import sco_compute_moy
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_formations from app.scodoc import sco_formations
@ -617,9 +617,7 @@ def formsemestre_description_table(
Liste des modules et de leurs coefficients Liste des modules et de leurs coefficients
""" """
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > liste evaluations
context, formsemestre_id
) # > liste evaluations
use_ue_coefs = sco_preferences.get_preference( use_ue_coefs = sco_preferences.get_preference(
context, "use_ue_coefs", formsemestre_id context, "use_ue_coefs", formsemestre_id
) )
@ -778,7 +776,8 @@ def _make_listes_sem(context, sem, REQUEST=None, with_absences=True):
r = scu.ScoURL() # root url r = scu.ScoURL() # root url
# construit l'URL "destination" # construit l'URL "destination"
# (a laquelle on revient apres saisie absences) # (a laquelle on revient apres saisie absences)
query_args = cgi.parse_qs(REQUEST.QUERY_STRING) query_args = cgi.parse_qs(REQUEST.QUERY_STRING) # XXX TODO a revoir #py3
# soit via flask soit via https://docs.python.org/3/library/urllib.parse.html#module-urllib.parse
if "head_message" in query_args: if "head_message" in query_args:
del query_args["head_message"] del query_args["head_message"]
destination = "%s?%s" % ( destination = "%s?%s" % (
@ -1026,9 +1025,7 @@ def formsemestre_status(context, formsemestre_id=None, REQUEST=None):
), ),
"""<p><b style="font-size: 130%">Tableau de bord: </b><span class="help">cliquez sur un module pour saisir des notes</span></p>""", """<p><b style="font-size: 130%">Tableau de bord: </b><span class="help">cliquez sur un module pour saisir des notes</span></p>""",
] ]
nt = sco_core.get_notes_cache( nt = sco_cache.NotesTableCache.get(formsemestre_id)
context,
).get_NotesTable(context, formsemestre_id)
if nt.expr_diagnostics: if nt.expr_diagnostics:
H.append(html_expr_diagnostic(context, nt.expr_diagnostics)) H.append(html_expr_diagnostic(context, nt.expr_diagnostics))
H.append( H.append(

View File

@ -37,12 +37,12 @@ from app.scodoc.notes_log import log
from app.scodoc.scolog import logdb from app.scodoc.scolog import logdb
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc.sco_abs import getAbsSemEtud
from app.scodoc.sco_codes_parcours import * from app.scodoc.sco_codes_parcours import *
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_abs
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -66,8 +66,8 @@ def formsemestre_validation_etud_form(
readonly=True, readonly=True,
REQUEST=None, REQUEST=None,
): ):
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, formsemestre_id formsemestre_id
) # > get_table_moyennes_triees, get_etud_decision_sem ) # > get_table_moyennes_triees, get_etud_decision_sem
T = nt.get_table_moyennes_triees() T = nt.get_table_moyennes_triees()
if not etudid and not etud_index: if not etudid and not etud_index:
@ -532,8 +532,8 @@ def formsemestre_recap_parcours_table(
else: else:
ass = "" ass = ""
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, sem["formsemestre_id"] sem["formsemestre_id"]
) # > get_ues, get_etud_moy_gen, get_etud_ue_status ) # > get_ues, get_etud_moy_gen, get_etud_ue_status
if is_cur: if is_cur:
type_sem = "*" # now unused type_sem = "*" # now unused
@ -614,9 +614,7 @@ def formsemestre_recap_parcours_table(
'<td class="rcp_moy">%s</td>' % scu.fmt_note(nt.get_etud_moy_gen(etudid)) '<td class="rcp_moy">%s</td>' % scu.fmt_note(nt.get_etud_moy_gen(etudid))
) )
# Absences (nb d'abs non just. dans ce semestre) # Absences (nb d'abs non just. dans ce semestre)
AbsEtudSem = getAbsSemEtud(context, sem, etudid) nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
nbabs = AbsEtudSem.CountAbs()
nbabsjust = AbsEtudSem.CountAbsJust()
H.append('<td class="rcp_abs">%d</td>' % (nbabs - nbabsjust)) H.append('<td class="rcp_abs">%d</td>' % (nbabs - nbabsjust))
# UEs # UEs
@ -864,8 +862,8 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
"Saisie automatisee des decisions d'un semestre" "Saisie automatisee des decisions d'un semestre"
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
next_semestre_id = sem["semestre_id"] + 1 next_semestre_id = sem["semestre_id"] + 1
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, formsemestre_id formsemestre_id
) # > get_etudids, get_etud_decision_sem, ) # > get_etudids, get_etud_decision_sem,
etudids = nt.get_etudids() etudids = nt.get_etudids()
nb_valid = 0 nb_valid = 0
@ -1137,9 +1135,7 @@ def do_formsemestre_validate_previous_ue(
""" """
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
cnx = ndb.GetDBConnexion(autocommit=False) cnx = ndb.GetDBConnexion(autocommit=False)
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etud_ue_status
context, formsemestre_id
) # > get_etud_ue_status
if ue_coefficient != None: if ue_coefficient != None:
sco_formsemestre.do_formsemestre_uecoef_edit_or_create( sco_formsemestre.do_formsemestre_uecoef_edit_or_create(
context, cnx, formsemestre_id, ue_id, ue_coefficient context, cnx, formsemestre_id, ue_id, ue_coefficient
@ -1186,8 +1182,8 @@ def _invalidate_etud_formation_caches(context, etudid, formation_id):
{"etudid": etudid, "formation_id": formation_id}, {"etudid": etudid, "formation_id": formation_id},
) )
for fsid in [s["formsemestre_id"] for s in r]: for fsid in [s["formsemestre_id"] for s in r]:
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=fsid formsemestre_id=fsid
) # > modif decision UE (inval tous semestres avec cet etudiant, ok mais conservatif) ) # > modif decision UE (inval tous semestres avec cet etudiant, ok mais conservatif)

View File

@ -48,7 +48,7 @@ from app.scodoc.notes_log import log
from app.scodoc.scolog import logdb from app.scodoc.scolog import logdb
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_permissions_check from app.scodoc import sco_permissions_check
from app.scodoc import sco_xml from app.scodoc import sco_xml
@ -446,9 +446,7 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG
formsemestre_id = partition["formsemestre_id"] formsemestre_id = partition["formsemestre_id"]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
groups = get_partition_groups(context, partition) groups = get_partition_groups(context, partition)
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > inscrdict
context, formsemestre_id
) # > inscrdict
etuds_set = set(nt.inscrdict) etuds_set = set(nt.inscrdict)
# XML response: # XML response:
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE) REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
@ -598,8 +596,8 @@ def change_etud_group_in_partition(
) )
cnx.commit() cnx.commit()
# 4- invalidate cache # 4- invalidate cache
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > change etud group ) # > change etud group
@ -955,8 +953,8 @@ def partition_set_attr(context, partition_id, attr, value, REQUEST=None):
partition[attr] = value partition[attr] = value
partitionEditor.edit(cnx, partition) partitionEditor.edit(cnx, partition)
# invalid bulletin cache # invalid bulletin cache
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, pdfonly=True, formsemestre_id=partition["formsemestre_id"] pdfonly=True, formsemestre_id=partition["formsemestre_id"]
) )
return "enregistré" return "enregistré"
@ -1268,9 +1266,7 @@ def groups_auto_repartition(context, partition_id=None, REQUEST=None):
createGroup(context, partition_id, group_name, REQUEST=REQUEST) createGroup(context, partition_id, group_name, REQUEST=REQUEST)
) )
# #
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > identdict
context, formsemestre_id
) # > identdict
identdict = nt.identdict identdict = nt.identdict
# build: { civilite : liste etudids trie par niveau croissant } # build: { civilite : liste etudids trie par niveau croissant }
civilites = set([x["civilite"] for x in identdict.values()]) civilites = set([x["civilite"] for x in identdict.values()])
@ -1313,8 +1309,8 @@ def get_prev_moy(context, etudid, formsemestre_id):
etud = info[0] etud = info[0]
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
if Se.prev: if Se.prev:
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, Se.prev["formsemestre_id"] Se.prev["formsemestre_id"]
) # > get_etud_moy_gen ) # > get_etud_moy_gen
return nt.get_etud_moy_gen(etudid) return nt.get_etud_moy_gen(etudid)
else: else:

View File

@ -514,7 +514,7 @@ def groups_table(
if with_paiement or with_codes: if with_paiement or with_codes:
sco_portal_apogee.check_paiement_etuds(context, groups_infos.members) sco_portal_apogee.check_paiement_etuds(context, groups_infos.members)
if with_archives: if with_archives:
import sco_archives_etud from app.scodoc import sco_archives_etud
sco_archives_etud.add_archives_info_to_etud_list(context, groups_infos.members) sco_archives_etud.add_archives_info_to_etud_list(context, groups_infos.members)
columns_ids += ["etudarchive"] columns_ids += ["etudarchive"]

View File

@ -28,12 +28,9 @@
""" Importation des etudiants à partir de fichiers CSV """ Importation des etudiants à partir de fichiers CSV
""" """
import os
import sys
import time import time
import pdb
import collections import collections
import types
import re import re
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
@ -53,7 +50,7 @@ from app.scodoc.sco_exceptions import (
ScoGenError, ScoGenError,
) )
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_groups from app.scodoc import sco_groups
@ -490,7 +487,8 @@ def scolars_import_excel_file(
cnx.commit() cnx.commit()
# Invalide les caches des semestres dans lesquels on a inscrit des etudiants: # Invalide les caches des semestres dans lesquels on a inscrit des etudiants:
sco_core.inval_cache(context, formsemestre_id_list=formsemestre_to_invalidate) for formsemestre_id in formsemestre_to_invalidate:
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id)
return diag return diag
@ -731,7 +729,7 @@ def scolars_import_admission(
nline += 1 nline += 1
diag.append("%d lignes importées" % n_import) diag.append("%d lignes importées" % n_import)
if n_import > 0: if n_import > 0:
sco_core.inval_cache(context, formsemestre_id=formsemestre_id) sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id)
return diag return diag

View File

@ -27,6 +27,8 @@
"""Import d'utilisateurs via fichier Excel """Import d'utilisateurs via fichier Excel
""" """
import random, time
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.header import Header from email.header import Header
@ -149,7 +151,6 @@ def import_users(U, auth_dept="", context=None):
# Adapté de http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440564 # Adapté de http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440564
# Alphabet tres simple pour des mots de passe simples... # Alphabet tres simple pour des mots de passe simples...
import getpass, random, sha, string, md5, time, base64
ALPHABET = r"""ABCDEFGHIJKLMNPQRSTUVWXYZ123456789123456789AEIOU""" ALPHABET = r"""ABCDEFGHIJKLMNPQRSTUVWXYZ123456789123456789AEIOU"""
PASSLEN = 6 PASSLEN = 6

View File

@ -39,7 +39,7 @@ from app.scodoc.TrivialFormulator import TrivialFormulator
from app.scodoc import htmlutils from app.scodoc import htmlutils
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_excel from app.scodoc import sco_excel
@ -658,9 +658,7 @@ def _add_moymod_column(
): ):
"""Ajoute la colonne moymod à rows""" """Ajoute la colonne moymod à rows"""
col_id = "moymod" col_id = "moymod"
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etud_mod_moy
context, formsemestre_id
) # > get_etud_mod_moy
nb_notes = 0 nb_notes = 0
sum_notes = 0 sum_notes = 0
notes = [] # liste des notes numeriques, pour calcul histogramme uniquement notes = [] # liste des notes numeriques, pour calcul histogramme uniquement
@ -730,12 +728,12 @@ def evaluation_check_absences(context, evaluation_id):
am, pm, demijournee = _eval_demijournee(E) am, pm, demijournee = _eval_demijournee(E)
# Liste les absences à ce moment: # Liste les absences à ce moment:
A = sco_abs.ListeAbsJour(context, ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm) A = sco_abs.list_abs_jour(ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm)
As = set([x["etudid"] for x in A]) # ensemble des etudiants absents As = set([x["etudid"] for x in A]) # ensemble des etudiants absents
NJ = sco_abs.ListeAbsNonJustJour(context, ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm) NJ = sco_abs.list_abs_non_just_jour(ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm)
NJs = set([x["etudid"] for x in NJ]) # ensemble des etudiants absents non justifies NJs = set([x["etudid"] for x in NJ]) # ensemble des etudiants absents non justifies
Just = sco_abs.ListeAbsJour( Just = sco_abs.list_abs_jour(
context, ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm, is_abs=None, is_just=True ndb.DateDMYtoISO(E["jour"]), am=am, pm=pm, is_abs=None, is_just=True
) )
Justs = set([x["etudid"] for x in Just]) # ensemble des etudiants avec justif Justs = set([x["etudid"] for x in Just]) # ensemble des etudiants avec justif

View File

@ -36,7 +36,7 @@ from app.scodoc.sco_exceptions import ScoValueError, AccessDenied
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc import scolog from app.scodoc import scolog
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_core from app.scodoc import sco_cache
# --- Gestion des "Implémentations de Modules" # --- Gestion des "Implémentations de Modules"
# Un "moduleimpl" correspond a la mise en oeuvre d'un module # Un "moduleimpl" correspond a la mise en oeuvre d'un module
@ -64,8 +64,8 @@ def do_moduleimpl_create(context, args):
"create a moduleimpl" "create a moduleimpl"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
r = _moduleimplEditor.create(cnx, args) r = _moduleimplEditor.create(cnx, args)
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=args["formsemestre_id"] formsemestre_id=args["formsemestre_id"]
) # > creation moduleimpl ) # > creation moduleimpl
return r return r
@ -91,8 +91,8 @@ def do_moduleimpl_delete(context, oid, formsemestre_id=None):
) )
# --- destruction du moduleimpl # --- destruction du moduleimpl
_moduleimplEditor.delete(cnx, oid) _moduleimplEditor.delete(cnx, oid)
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > moduleimpl_delete ) # > moduleimpl_delete
@ -115,7 +115,9 @@ def do_moduleimpl_edit(context, args, formsemestre_id=None, cnx=None):
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
_moduleimplEditor.edit(cnx, args) _moduleimplEditor.edit(cnx, args)
sco_core.inval_cache(context, formsemestre_id=formsemestre_id) # > modif moduleimpl sco_cache.invalidate_formsemestre(
formsemestre_id=formsemestre_id
) # > modif moduleimpl
def do_moduleimpl_withmodule_list( def do_moduleimpl_withmodule_list(
@ -215,8 +217,8 @@ def do_moduleimpl_inscription_create(context, args, REQUEST=None, formsemestre_i
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
log("do_moduleimpl_inscription_create: " + str(args)) log("do_moduleimpl_inscription_create: " + str(args))
r = _moduleimpl_inscriptionEditor.create(cnx, args) r = _moduleimpl_inscriptionEditor.create(cnx, args)
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > moduleimpl_inscription ) # > moduleimpl_inscription
if REQUEST: if REQUEST:
scolog.logdb( scolog.logdb(
@ -234,8 +236,8 @@ def do_moduleimpl_inscription_delete(context, oid, formsemestre_id=None):
"delete moduleimpl_inscription" "delete moduleimpl_inscription"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
_moduleimpl_inscriptionEditor.delete(cnx, oid) _moduleimpl_inscriptionEditor.delete(cnx, oid)
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > moduleimpl_inscription ) # > moduleimpl_inscription
@ -283,8 +285,8 @@ def do_moduleimpl_inscrit_etuds(
formsemestre_id=formsemestre_id, formsemestre_id=formsemestre_id,
) )
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > moduleimpl_inscrit_etuds ) # > moduleimpl_inscrit_etuds
@ -311,8 +313,7 @@ def do_ens_create(context, args):
def do_ens_delete(context, oid): def do_ens_delete(context, oid):
"delete ens" "delete ens"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
r = _modules_enseignantsEditor.delete(cnx, oid) _modules_enseignantsEditor.delete(cnx, oid)
return r
def can_change_module_resp(context, REQUEST, moduleimpl_id): def can_change_module_resp(context, REQUEST, moduleimpl_id):

View File

@ -37,7 +37,7 @@ from app.scodoc.notes_log import log
from app.scodoc.scolog import logdb from app.scodoc.scolog import logdb
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import htmlutils from app.scodoc import htmlutils
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -495,9 +495,7 @@ def get_etuds_with_capitalized_ue(context, formsemestre_id):
returns { ue_id : [ { infos } ] } returns { ue_id : [ { infos } ] }
""" """
UECaps = scu.DictDefault(defaultvalue=[]) UECaps = scu.DictDefault(defaultvalue=[])
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_ues, get_etud_ue_status
context, formsemestre_id
) # > get_ues, get_etud_ue_status
inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
context, args={"formsemestre_id": formsemestre_id} context, args={"formsemestre_id": formsemestre_id}
) )
@ -569,8 +567,8 @@ def do_etud_desinscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None)
msg="desinscription UE %s" % ue_id, msg="desinscription UE %s" % ue_id,
commit=False, commit=False,
) )
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > desinscription etudiant des modules ) # > desinscription etudiant des modules

View File

@ -37,7 +37,7 @@ from app.scodoc import html_sco_header
from app.scodoc import htmlutils from app.scodoc import htmlutils
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_compute_moy from app.scodoc import sco_compute_moy
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_formations from app.scodoc import sco_formations
@ -46,7 +46,6 @@ from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
from app.scodoc import sco_permissions_check from app.scodoc import sco_permissions_check
from app.scodoc import sco_saisie_notes
from app.scodoc import sco_users from app.scodoc import sco_users
# ported from old DTML code in oct 2009 # ported from old DTML code in oct 2009
@ -168,9 +167,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
context, moduleimpl_id=M["moduleimpl_id"] context, moduleimpl_id=M["moduleimpl_id"]
) )
nt = sco_core.get_notes_cache( nt = sco_cache.NotesTableCache.get(formsemestre_id)
context,
).get_NotesTable(context, formsemestre_id)
ModEvals = sco_evaluations.do_evaluation_list( ModEvals = sco_evaluations.do_evaluation_list(
context, {"moduleimpl_id": moduleimpl_id} context, {"moduleimpl_id": moduleimpl_id}
) )

View File

@ -32,7 +32,7 @@ import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc.scolog import logdb from app.scodoc.scolog import logdb
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formations from app.scodoc import sco_formations
from app.scodoc.sco_codes_parcours import ( from app.scodoc.sco_codes_parcours import (
@ -104,8 +104,8 @@ class DecisionSem(object):
def SituationEtudParcours(context, etud, formsemestre_id): def SituationEtudParcours(context, etud, formsemestre_id):
"""renvoie une instance de SituationEtudParcours (ou sous-classe spécialisée)""" """renvoie une instance de SituationEtudParcours (ou sous-classe spécialisée)"""
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, formsemestre_id formsemestre_id
) # > get_etud_decision_sem, get_etud_moy_gen, get_ues, get_etud_ue_status, etud_check_conditions_ues ) # > get_etud_decision_sem, get_etud_moy_gen, get_ues, get_etud_ue_status, etud_check_conditions_ues
parcours = nt.parcours parcours = nt.parcours
# #
@ -295,8 +295,8 @@ class SituationEtudParcoursGeneric(object):
sem["semestre_id"] == n1 sem["semestre_id"] == n1
and sem["formation_code"] == self.formation["formation_code"] and sem["formation_code"] == self.formation["formation_code"]
): ):
nt = sco_core.get_notes_cache(self.context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
self.context, sem["formsemestre_id"] sem["formsemestre_id"]
) # > get_etud_decision_sem ) # > get_etud_decision_sem
decision = nt.get_etud_decision_sem(self.etudid) decision = nt.get_etud_decision_sem(self.etudid)
if decision and ( if decision and (
@ -311,8 +311,8 @@ class SituationEtudParcoursGeneric(object):
sont validés. En sortie, sem_idx_set contient ceux qui n'ont pas été validés.""" sont validés. En sortie, sem_idx_set contient ceux qui n'ont pas été validés."""
for sem in self.get_semestres(): for sem in self.get_semestres():
if sem["formation_code"] == self.formation["formation_code"]: if sem["formation_code"] == self.formation["formation_code"]:
nt = sco_core.get_notes_cache(self.context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
self.context, sem["formsemestre_id"] sem["formsemestre_id"]
) # > get_etud_decision_sem ) # > get_etud_decision_sem
decision = nt.get_etud_decision_sem(self.etudid) decision = nt.get_etud_decision_sem(self.etudid)
if decision and code_semestre_validant(decision["code"]): if decision and code_semestre_validant(decision["code"]):
@ -329,9 +329,7 @@ class SituationEtudParcoursGeneric(object):
ue_acros = {} # acronyme ue : 1 ue_acros = {} # acronyme ue : 1
nb_max_ue = 0 nb_max_ue = 0
for sem in sems: for sem in sems:
nt = sco_core.get_notes_cache(self.context).get_NotesTable( nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"]) # > get_ues
self.context, sem["formsemestre_id"]
) # > get_ues
ues = nt.get_ues(filter_sport=True) ues = nt.get_ues(filter_sport=True)
for ue in ues: for ue in ues:
ue_acros[ue["acronyme"]] = 1 ue_acros[ue["acronyme"]] = 1
@ -399,8 +397,8 @@ class SituationEtudParcoursGeneric(object):
if not sem: if not sem:
code = "" # non inscrit à ce semestre code = "" # non inscrit à ce semestre
else: else:
nt = sco_core.get_notes_cache(self.context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
self.context, sem["formsemestre_id"] sem["formsemestre_id"]
) # > get_etud_decision_sem ) # > get_etud_decision_sem
decision = nt.get_etud_decision_sem(self.etudid) decision = nt.get_etud_decision_sem(self.etudid)
if decision: if decision:
@ -471,9 +469,8 @@ class SituationEtudParcoursGeneric(object):
# Verifications basiques: # Verifications basiques:
# ? # ?
# Code etat du semestre precedent: # Code etat du semestre precedent:
nt = sco_core.get_notes_cache(self.context).get_NotesTable( nt = sco_cache.NotesTableCache.get(prev["formsemestre_id"])
self.context, prev["formsemestre_id"] # > get_etud_decision_sem, get_etud_moy_gen, etud_check_conditions_ues
) # > get_etud_decision_sem, get_etud_moy_gen, etud_check_conditions_ues
self.prev_decision = nt.get_etud_decision_sem(self.etudid) self.prev_decision = nt.get_etud_decision_sem(self.etudid)
self.prev_moy_gen = nt.get_etud_moy_gen(self.etudid) self.prev_moy_gen = nt.get_etud_moy_gen(self.etudid)
self.prev_barres_ue_ok = nt.etud_check_conditions_ues(self.etudid)[0] self.prev_barres_ue_ok = nt.etud_check_conditions_ues(self.etudid)[0]
@ -530,9 +527,8 @@ class SituationEtudParcoursGeneric(object):
sem["formation_code"] == self.formation["formation_code"] sem["formation_code"] == self.formation["formation_code"]
and sem["semestre_id"] == s and sem["semestre_id"] == s
): ):
nt = sco_core.get_notes_cache(self.context).get_NotesTable( nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"])
self.context, sem["formsemestre_id"] # > get_etud_decision_sem
) # > get_etud_decision_sem
decision = nt.get_etud_decision_sem(self.etudid) decision = nt.get_etud_decision_sem(self.etudid)
if decision and code_semestre_validant(decision["code"]): if decision and code_semestre_validant(decision["code"]):
validated = True validated = True
@ -629,8 +625,8 @@ class SituationEtudParcoursGeneric(object):
REQUEST=REQUEST, REQUEST=REQUEST,
) )
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
self.context, formsemestre_id=self.prev["formsemestre_id"] formsemestre_id=self.prev["formsemestre_id"]
) # > modif decisions jury (sem, UE) ) # > modif decisions jury (sem, UE)
# -- supprime autorisations venant de ce formsemestre # -- supprime autorisations venant de ce formsemestre
@ -659,18 +655,17 @@ class SituationEtudParcoursGeneric(object):
except: except:
cnx.rollback() cnx.rollback()
raise raise
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
self.context, formsemestre_id=self.formsemestre_id formsemestre_id=self.formsemestre_id
) # > modif decisions jury et autorisations inscription ) # > modif decisions jury et autorisations inscription
if decision.formsemestre_id_utilise_pour_compenser: if decision.formsemestre_id_utilise_pour_compenser:
# inval aussi le semestre utilisé pour compenser: # inval aussi le semestre utilisé pour compenser:
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
self.context,
formsemestre_id=decision.formsemestre_id_utilise_pour_compenser, formsemestre_id=decision.formsemestre_id_utilise_pour_compenser,
) # > modif decision jury ) # > modif decision jury
for formsemestre_id in to_invalidate: for formsemestre_id in to_invalidate:
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
self.context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > modif decision jury ) # > modif decision jury
@ -909,9 +904,7 @@ def formsemestre_validate_ues(
""" """
valid_semestre = CODES_SEM_VALIDES.get(code_etat_sem, False) valid_semestre = CODES_SEM_VALIDES.get(code_etat_sem, False)
cnx = ndb.GetDBConnexion(autocommit=False) cnx = ndb.GetDBConnexion(autocommit=False)
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_ues, get_etud_ue_status
context, formsemestre_id
) # > get_ues, get_etud_ue_status
ue_ids = [x["ue_id"] for x in nt.get_ues(etudid=etudid, filter_sport=True)] ue_ids = [x["ue_id"] for x in nt.get_ues(etudid=etudid, filter_sport=True)]
for ue_id in ue_ids: for ue_id in ue_ids:
ue_status = nt.get_etud_ue_status(etudid, ue_id) ue_status = nt.get_etud_ue_status(etudid, ue_id)

View File

@ -35,7 +35,7 @@ from flask import url_for, g
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
@ -58,9 +58,7 @@ def etud_get_poursuite_info(context, sem, etud):
for s in etud["sems"]: for s in etud["sems"]:
if s["semestre_id"] == sem_id: if s["semestre_id"] == sem_id:
etudid = etud["etudid"] etudid = etud["etudid"]
nt = sco_core.get_notes_cache( nt = sco_cache.NotesTableCache.get(s["formsemestre_id"])
context,
).get_NotesTable(context, s["formsemestre_id"])
dec = nt.get_etud_decision_sem(etudid) dec = nt.get_etud_decision_sem(etudid)
# Moyennes et rangs des UE # Moyennes et rangs des UE
ues = nt.get_ues(filter_sport=True) ues = nt.get_ues(filter_sport=True)
@ -95,9 +93,7 @@ def etud_get_poursuite_info(context, sem, etud):
rangs.append(["rang_" + codeModule, rangModule]) rangs.append(["rang_" + codeModule, rangModule])
# Absences # Absences
AbsSemEtud = sco_abs.getAbsSemEtud(context, nt.sem, etudid) nbabs, nbabsjust = sco_abs.get_abs_count(etudid, nt.sem)
NbAbs = AbsSemEtud.CountAbs()
NbAbsJust = AbsSemEtud.CountAbsJust()
if ( if (
dec dec
and not sem_descr # not sem_descr pour ne prendre que le semestre validé le plus récent and not sem_descr # not sem_descr pour ne prendre que le semestre validé le plus récent
@ -115,8 +111,8 @@ def etud_get_poursuite_info(context, sem, etud):
("date_debut", s["date_debut"]), ("date_debut", s["date_debut"]),
("date_fin", s["date_fin"]), ("date_fin", s["date_fin"]),
("periode", "%s - %s" % (s["mois_debut"], s["mois_fin"])), ("periode", "%s - %s" % (s["mois_debut"], s["mois_fin"])),
("AbsNonJust", NbAbs - NbAbsJust), ("AbsNonJust", nbabs - nbabsjust),
("AbsJust", NbAbsJust), ("AbsJust", nbabsjust),
] ]
d += ( d += (
moy_ues + rg_ues + modules + rangs moy_ues + rg_ues + modules + rangs

View File

@ -112,7 +112,7 @@ get_base_preferences(context, formsemestre_id)
""" """
from flask import g from flask import g
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc.sco_exceptions import ScoValueError, ScoException from app.scodoc.sco_exceptions import ScoValueError, ScoException
from app.scodoc.TrivialFormulator import TrivialFormulator from app.scodoc.TrivialFormulator import TrivialFormulator
@ -1797,7 +1797,10 @@ class BasePreferences(object):
self.prefs[p["formsemestre_id"]] = {} self.prefs[p["formsemestre_id"]] = {}
# Convert types: # Convert types:
if p["name"] in self.prefs_dict and "type" in self.prefs_dict[p["name"]]: if (
p["name"] in self.prefs_dict
and "type" in self.prefs_dict[p["name"]]
):
typ = self.prefs_dict[p["name"]]["type"] typ = self.prefs_dict[p["name"]]["type"]
if typ == "float": if typ == "float":
# special case for float values (where NULL means 0) # special case for float values (where NULL means 0)
@ -1918,7 +1921,7 @@ class BasePreferences(object):
# les preferences peuvent affecter les PDF cachés et les notes calculées: # les preferences peuvent affecter les PDF cachés et les notes calculées:
if modif: if modif:
sco_core.inval_cache(self.context, pdfonly=False) # > modif preferences sco_cache.invalidate_formsemestre()
finally: finally:
scu.GSL.release() scu.GSL.release()
@ -1946,7 +1949,7 @@ class BasePreferences(object):
if pdb: if pdb:
log("deleting pref sem=%s %s" % (formsemestre_id, name)) log("deleting pref sem=%s %s" % (formsemestre_id, name))
self._editor.delete(cnx, pdb[0]["pref_id"]) self._editor.delete(cnx, pdb[0]["pref_id"])
sco_core.inval_cache(self.context, pdfonly=False) # > modif preferences sco_cache.invalidate_formsemestre() # > modif preferences
finally: finally:
scu.GSL.release() scu.GSL.release()

View File

@ -30,13 +30,13 @@
import time import time
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc import sco_abs
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_excel from app.scodoc import sco_excel
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_parcours_dut from app.scodoc import sco_parcours_dut
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc.sco_abs import getAbsSemEtud
from app.scodoc import VERSION from app.scodoc import VERSION
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
@ -44,8 +44,8 @@ from app.scodoc import sco_preferences
def feuille_preparation_jury(context, formsemestre_id, REQUEST): def feuille_preparation_jury(context, formsemestre_id, REQUEST):
"Feuille excel pour preparation des jurys" "Feuille excel pour preparation des jurys"
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, formsemestre_id formsemestre_id
) # > get_etudids, get_etud_moy_gen, get_ues, get_etud_ue_status, get_etud_decision_sem, identdict, ) # > get_etudids, get_etud_moy_gen, get_ues, get_etud_ue_status, get_etud_decision_sem, identdict,
etudids = nt.get_etudids(sorted=True) # tri par moy gen etudids = nt.get_etudids(sorted=True) # tri par moy gen
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
@ -77,8 +77,8 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
etud = info[0] etud = info[0]
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
if Se.prev: if Se.prev:
ntp = sco_core.get_notes_cache(context).get_NotesTable( ntp = sco_cache.NotesTableCache.get(
context, Se.prev["formsemestre_id"] Se.prev["formsemestre_id"]
) # > get_ues, get_etud_ue_status, get_etud_moy_gen, get_etud_decision_sem ) # > get_ues, get_etud_ue_status, get_etud_moy_gen, get_etud_decision_sem
for ue in ntp.get_ues(filter_sport=True): for ue in ntp.get_ues(filter_sport=True):
ue_status = ntp.get_etud_ue_status(etudid, ue["ue_id"]) ue_status = ntp.get_etud_ue_status(etudid, ue["ue_id"])
@ -129,10 +129,9 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
main_partition_id, "" main_partition_id, ""
) )
# absences: # absences:
AbsEtudSem = getAbsSemEtud(context, sem, etudid) nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
nbabs[etudid] = AbsEtudSem.CountAbs() nbabs[etudid] = nbabs
# nbabsjust[etudid] = AbsEtudSem.CountAbsJust() nbabsjust[etudid] = nbabs - nbabsjust
nbabsjust[etudid] = AbsEtudSem.CountAbs() - AbsEtudSem.CountAbsJust()
# Codes des UE "semestre précédent": # Codes des UE "semestre précédent":
ue_prev_codes = list(prev_moy_ue.keys()) ue_prev_codes = list(prev_moy_ue.keys())

View File

@ -58,7 +58,7 @@ import app.scodoc.notesdb as ndb
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_formations from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -86,6 +86,7 @@ def _descr_decisions_ues(context, nt, etudid, decisions_ue, decision_sem):
if decisions_ue[ue_id] and ( if decisions_ue[ue_id] and (
decisions_ue[ue_id]["code"] == sco_codes_parcours.ADM decisions_ue[ue_id]["code"] == sco_codes_parcours.ADM
or ( or (
# XXX ceci devrait dépendre du parcours et non pas être une option ! #sco8
scu.CONFIG.CAPITALIZE_ALL_UES scu.CONFIG.CAPITALIZE_ALL_UES
and sco_codes_parcours.code_semestre_validant(decision_sem["code"]) and sco_codes_parcours.code_semestre_validant(decision_sem["code"])
) )
@ -216,8 +217,8 @@ def dict_pvjury(
'decisions_dict' : { etudid : decision (comme ci-dessus) }, 'decisions_dict' : { etudid : decision (comme ci-dessus) },
} }
""" """
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, formsemestre_id formsemestre_id
) # > get_etudids, get_etud_etat, get_etud_decision_sem, get_etud_decision_ues ) # > get_etudids, get_etud_etat, get_etud_decision_sem, get_etud_decision_ues
if etudids is None: if etudids is None:
etudids = nt.get_etudids() etudids = nt.get_etudids()

View File

@ -39,7 +39,7 @@ 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_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_formations from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -282,8 +282,8 @@ def make_formsemestre_recapcomplet(
sem = sco_formsemestre.do_formsemestre_list( sem = sco_formsemestre.do_formsemestre_list(
context, args={"formsemestre_id": formsemestre_id} context, args={"formsemestre_id": formsemestre_id}
)[0] )[0]
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, formsemestre_id formsemestre_id
) # > get_modimpls, get_ues, get_table_moyennes_triees, get_etud_decision_sem, get_etud_etat, get_etud_rang, get_nom_short, get_mod_stats, nt.moy_moy, get_etud_decision_sem, ) # > get_modimpls, get_ues, get_table_moyennes_triees, get_etud_decision_sem, get_etud_etat, get_etud_rang, get_nom_short, get_mod_stats, nt.moy_moy, get_etud_decision_sem,
modimpls = nt.get_modimpls() modimpls = nt.get_modimpls()
ues = nt.get_ues() # incluant le(s) UE de sport ues = nt.get_ues() # incluant le(s) UE de sport
@ -868,9 +868,7 @@ def _formsemestre_recapcomplet_xml(
): ):
"XML export: liste tous les bulletins XML." "XML export: liste tous les bulletins XML."
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_table_moyennes_triees
context, formsemestre_id
) # > get_table_moyennes_triees
T = nt.get_table_moyennes_triees() T = nt.get_table_moyennes_triees()
if not T: if not T:
return "", "", "xml" return "", "", "xml"
@ -939,9 +937,7 @@ def _formsemestre_recapcomplet_json(
"bulletins": [], "bulletins": [],
} }
bulletins = J["bulletins"] bulletins = J["bulletins"]
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_table_moyennes_triees
context, formsemestre_id
) # > get_table_moyennes_triees
T = nt.get_table_moyennes_triees() T = nt.get_table_moyennes_triees()
for t in T: for t in T:
etudid = t[-1] etudid = t[-1]

View File

@ -43,7 +43,7 @@ import app.scodoc.sco_utils as scu
from app.scodoc import notesdb as ndb from app.scodoc import notesdb as ndb
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_excel from app.scodoc import sco_excel
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
@ -64,8 +64,8 @@ MAX_ETUD_IN_DESCR = 20
def formsemestre_etuds_stats(context, sem, only_primo=False): def formsemestre_etuds_stats(context, sem, only_primo=False):
"""Récupère liste d'etudiants avec etat et decision.""" """Récupère liste d'etudiants avec etat et decision."""
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, sem["formsemestre_id"] sem["formsemestre_id"]
) # > get_table_moyennes_triees, identdict, get_etud_decision_sem, get_etud_etat, ) # > get_table_moyennes_triees, identdict, get_etud_decision_sem, get_etud_etat,
T = nt.get_table_moyennes_triees() T = nt.get_table_moyennes_triees()
# Construit liste d'étudiants du semestre avec leur decision # Construit liste d'étudiants du semestre avec leur decision
@ -413,8 +413,8 @@ def table_suivi_cohorte(
logt("table_suivi_cohorte: start") logt("table_suivi_cohorte: start")
# 1-- Liste des semestres posterieurs dans lesquels ont été les etudiants de sem # 1-- Liste des semestres posterieurs dans lesquels ont été les etudiants de sem
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, formsemestre_id formsemestre_id
) # > get_etudids, get_etud_decision_sem ) # > get_etudids, get_etud_decision_sem
etudids = nt.get_etudids() etudids = nt.get_etudids()
@ -469,8 +469,8 @@ def table_suivi_cohorte(
s["members"] = orig_set.intersection(inset) s["members"] = orig_set.intersection(inset)
nb_dipl = 0 # combien de diplomes dans ce semestre ? nb_dipl = 0 # combien de diplomes dans ce semestre ?
if s["semestre_id"] == nt.parcours.NB_SEM: if s["semestre_id"] == nt.parcours.NB_SEM:
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, s["formsemestre_id"] s["formsemestre_id"]
) # > get_etud_decision_sem ) # > get_etud_decision_sem
for etudid in s["members"]: for etudid in s["members"]:
dec = nt.get_etud_decision_sem(etudid) dec = nt.get_etud_decision_sem(etudid)
@ -919,8 +919,8 @@ def _descr_etud_set(context, etudids):
def _count_dem_reo(context, formsemestre_id, etudids): def _count_dem_reo(context, formsemestre_id, etudids):
"count nb of demissions and reorientation in this etud set" "count nb of demissions and reorientation in this etud set"
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, formsemestre_id formsemestre_id
) # > get_etud_etat, get_etud_decision_sem ) # > get_etud_etat, get_etud_decision_sem
dems = set() dems = set()
reos = set() reos = set()
@ -985,8 +985,8 @@ def get_codeparcoursetud(context, etud, prefix="", separator=""):
i = len(sems) - 1 i = len(sems) - 1
while i >= 0: while i >= 0:
s = sems[i] # 'sems' est a l'envers, du plus recent au plus ancien s = sems[i] # 'sems' est a l'envers, du plus recent au plus ancien
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, s["formsemestre_id"] s["formsemestre_id"]
) # > get_etud_etat, get_etud_decision_sem ) # > get_etud_etat, get_etud_decision_sem
p.append(_codesem(s, prefix=prefix)) p.append(_codesem(s, prefix=prefix))
# code decisions jury de chaque semestre: # code decisions jury de chaque semestre:
@ -1032,9 +1032,7 @@ def tsp_etud_list(
""" """
# log('tsp_etud_list(%s, bac="%s")' % (formsemestre_id,bac)) # log('tsp_etud_list(%s, bac="%s")' % (formsemestre_id,bac))
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etudids,
context, formsemestre_id
) # > get_etudids,
etudids = nt.get_etudids() etudids = nt.get_etudids()
etuds = [] etuds = []
bacs = set() bacs = set()
@ -1287,8 +1285,8 @@ def graph_parcours(
nxt = {} nxt = {}
etudid = etud["etudid"] etudid = etud["etudid"]
for s in etud["sems"]: # du plus recent au plus ancien for s in etud["sems"]: # du plus recent au plus ancien
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, s["formsemestre_id"] s["formsemestre_id"]
) # > get_etud_decision_sem, get_etud_etat ) # > get_etud_decision_sem, get_etud_etat
dec = nt.get_etud_decision_sem(etudid) dec = nt.get_etud_decision_sem(etudid)
if nxt: if nxt:

View File

@ -47,7 +47,7 @@ from app.scodoc.TrivialFormulator import TrivialFormulator, TF
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import htmlutils from app.scodoc import htmlutils
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_excel from app.scodoc import sco_excel
@ -560,19 +560,17 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
log("*** exception in _notes_add") log("*** exception in _notes_add")
if do_it: if do_it:
# inval cache # inval cache
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=M["formsemestre_id"] formsemestre_id=M["formsemestre_id"]
) # > modif notes (exception) ) # > modif notes (exception)
cnx.rollback() # abort cnx.rollback() # abort
raise # re-raise exception raise # re-raise exception
if do_it: if do_it:
cnx.commit() cnx.commit()
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=M["formsemestre_id"] formsemestre_id=M["formsemestre_id"]
) # > modif notes ) # > modif notes
sco_core.get_evaluations_cache( sco_cache.EvaluationCache.delete(evaluation_id)
context,
).inval_cache(key=evaluation_id)
return nb_changed, nb_suppress, existing_decisions return nb_changed, nb_suppress, existing_decisions
@ -837,8 +835,8 @@ def has_existing_decision(context, M, E, etudid):
Si oui, return True Si oui, return True
""" """
formsemestre_id = M["formsemestre_id"] formsemestre_id = M["formsemestre_id"]
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, formsemestre_id formsemestre_id
) # > get_etud_decision_sem, get_etud_decision_ues ) # > get_etud_decision_sem, get_etud_decision_ues
if nt.get_etud_decision_sem(etudid): if nt.get_etud_decision_sem(etudid):
return True return True
@ -1001,20 +999,16 @@ def _get_sorted_etuds(context, E, etudids, formsemestre_id):
jour_iso = ndb.DateDMYtoISO(E["jour"]) jour_iso = ndb.DateDMYtoISO(E["jour"])
warn_abs_lst = [] warn_abs_lst = []
if E["matin"]: if E["matin"]:
nbabs = sco_abs.CountAbs(context, etudid, jour_iso, jour_iso, matin=1) nbabs = sco_abs.count_abs(etudid, jour_iso, jour_iso, matin=1)
nbabsjust = sco_abs.CountAbsJust( nbabsjust = sco_abs.count_abs_just(etudid, jour_iso, jour_iso, matin=1)
context, etudid, jour_iso, jour_iso, matin=1
)
if nbabs: if nbabs:
if nbabsjust: if nbabsjust:
warn_abs_lst.append("absent justifié le matin !") warn_abs_lst.append("absent justifié le matin !")
else: else:
warn_abs_lst.append("absent le matin !") warn_abs_lst.append("absent le matin !")
if E["apresmidi"]: if E["apresmidi"]:
nbabs = sco_abs.CountAbs(context, etudid, jour_iso, jour_iso, matin=0) nbabs = sco_abs.count_abs(etudid, jour_iso, jour_iso, matin=0)
nbabsjust = sco_abs.CountAbsJust( nbabsjust = sco_abs.count_abs_just(etudid, jour_iso, jour_iso, matin=0)
context, etudid, jour_iso, jour_iso, matin=0
)
if nbabs: if nbabs:
if nbabsjust: if nbabsjust:
warn_abs_lst.append("absent justifié l'après-midi !") warn_abs_lst.append("absent justifié l'après-midi !")

View File

@ -40,7 +40,7 @@ sem_set_list(context)
""" """
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_etape_apogee from app.scodoc import sco_etape_apogee
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_status from app.scodoc import sco_formsemestre_status
@ -232,9 +232,7 @@ class SemSet(dict):
self["etuds_without_nip"] = set() # etudids self["etuds_without_nip"] = set() # etudids
self["jury_ok"] = True self["jury_ok"] = True
for sem in self.sems: for sem in self.sems:
nt = sco_core.get_notes_cache( nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"])
context,
).get_NotesTable(context, sem["formsemestre_id"])
sem["etuds"] = list(nt.identdict.values()) sem["etuds"] = list(nt.identdict.values())
sem["nips"] = {e["code_nip"] for e in sem["etuds"] if e["code_nip"]} sem["nips"] = {e["code_nip"] for e in sem["etuds"] if e["code_nip"]}
sem["etuds_without_nip"] = { sem["etuds_without_nip"] = {

View File

@ -35,7 +35,7 @@ from operator import itemgetter
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_groups from app.scodoc import sco_groups
@ -672,7 +672,7 @@ def do_import_etuds_from_portal(context, sem, a_importer, etudsapo_ident, REQUES
cnx.commit() cnx.commit()
log("do_import_etuds_from_portal: re-raising exception") log("do_import_etuds_from_portal: re-raising exception")
# > import: modif identite, adresses, inscriptions # > import: modif identite, adresses, inscriptions
sco_core.inval_cache(context) sco_cache.invalidate_formsemestre()
raise raise
sco_news.add( sco_news.add(
@ -855,7 +855,7 @@ def formsemestre_import_etud_admission(
changed_mails.append((info, etud["mail"])) changed_mails.append((info, etud["mail"]))
else: else:
unknowns.append(code_nip) unknowns.append(code_nip)
sco_core.inval_cache(context, formsemestre_id=sem["formsemestre_id"]) sco_cache.invalidate_formsemestre(formsemestre_id=sem["formsemestre_id"])
return no_nip, unknowns, changed_mails return no_nip, unknowns, changed_mails

View File

@ -39,7 +39,7 @@ import types
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc.notes_log import log from app.scodoc.notes_log import log
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc.sco_exceptions import ScoValueError, AccessDenied from app.scodoc.sco_exceptions import ScoValueError, AccessDenied
@ -276,9 +276,7 @@ def get_etud_tagged_modules(context, etudid, tagname):
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
R = [] R = []
for sem in etud["sems"]: for sem in etud["sems"]:
nt = sco_core.get_notes_cache( nt = sco_cache.NotesTableCache.get(sem["formsemestre_id"])
context,
).get_NotesTable(context, sem["formsemestre_id"])
modimpls = nt.get_modimpls() modimpls = nt.get_modimpls()
for modimpl in modimpls: for modimpl in modimpls:
tags = module_tag_list(context, module_id=modimpl["module_id"]) tags = module_tag_list(context, module_id=modimpl["module_id"])
@ -346,5 +344,5 @@ sem = etud['sems'][0]
[ tm['moy'] for tm in get_etud_tagged_modules(context, etudid, 'allo') ] [ tm['moy'] for tm in get_etud_tagged_modules(context, etudid, 'allo') ]
# si besoin après modif par le Web: # si besoin après modif par le Web:
# sco_core.inval_cache(context) # sco_cache.invalidate_formsemestre()
""" """

View File

@ -97,17 +97,21 @@ class NotesOperation(dict):
# # il y a-t-il une modif plus recente ? # # il y a-t-il une modif plus recente ?
# if self['current_notes_by_etud']['date'] <= self['date'] + OPERATION_DATE_TOLERANCE: # if self['current_notes_by_etud']['date'] <= self['date'] + OPERATION_DATE_TOLERANCE:
# #
# + invalider cache sco_core.get_evaluations_cache(context, ).inval_cache(key=evaluation_id) # + invalider cache sco_cache.EvaluationCache.delete(evaluation_id)
def list_operations(context, evaluation_id): def list_operations(context, evaluation_id):
"""returns list of NotesOperation for this evaluation""" """returns list of NotesOperation for this evaluation"""
notes = list(sco_evaluations.do_evaluation_get_all_notes( notes = list(
context, evaluation_id, filter_suppressed=False sco_evaluations.do_evaluation_get_all_notes(
).values()) context, evaluation_id, filter_suppressed=False
notes_log = list(sco_evaluations.do_evaluation_get_all_notes( ).values()
context, evaluation_id, filter_suppressed=False, table="notes_notes_log" )
).values()) notes_log = list(
sco_evaluations.do_evaluation_get_all_notes(
context, evaluation_id, filter_suppressed=False, table="notes_notes_log"
).values()
)
dt = OPERATION_DATE_TOLERANCE dt = OPERATION_DATE_TOLERANCE
NotesDates = {} # { uid : intervalmap } NotesDates = {} # { uid : intervalmap }

View File

@ -45,7 +45,7 @@ import types
import unicodedata import unicodedata
import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
from xml.etree.ElementTree import Element from xml.etree import ElementTree
STRING_TYPES = six.string_types STRING_TYPES = six.string_types
@ -272,11 +272,6 @@ else:
CUSTOM_HTML_FOOTER_CNX = "" CUSTOM_HTML_FOOTER_CNX = ""
SCO_ENCODING = "utf-8" # used by Excel, XML, PDF, ... SCO_ENCODING = "utf-8" # used by Excel, XML, PDF, ...
# Attention: encodage lié au codage Zope et aussi à celui de postgresql
# et aussi a celui des fichiers sources Python (comme celui-ci).
# def to_utf8(s):
# return unicode(s, SCO_ENCODING).encode('utf-8')
SCO_DEFAULT_SQL_USER = "www-data" # should match Zope process UID SCO_DEFAULT_SQL_USER = "www-data" # should match Zope process UID
@ -321,6 +316,7 @@ LOGOS_IMAGES_ALLOWED_TYPES = ("jpg", "png") # remind that PIL does not read pdf
TYPE_ADMISSION_DEFAULT = "Inconnue" TYPE_ADMISSION_DEFAULT = "Inconnue"
TYPES_ADMISSION = (TYPE_ADMISSION_DEFAULT, "APB", "APB-PC", "CEF", "Direct") TYPES_ADMISSION = (TYPE_ADMISSION_DEFAULT, "APB", "APB-PC", "CEF", "Direct")
BULLETINS_VERSIONS = ("short", "selectedevals", "long")
# Support for ScoDoc7 compatibility # Support for ScoDoc7 compatibility
def get_dept_id(): def get_dept_id():
@ -823,7 +819,7 @@ def _sco_error_response(context, msg, format="html", REQUEST=None):
elif format == "xml": elif format == "xml":
REQUEST.RESPONSE.setHeader("content-type", XML_MIMETYPE) REQUEST.RESPONSE.setHeader("content-type", XML_MIMETYPE)
doc = ElementTree.Element("error", msg=msg) doc = ElementTree.Element("error", msg=msg)
return sco_xml.XML_HEADER + ElementTree.tostring(doc).decode(scu.SCO_ENCODING) return sco_xml.XML_HEADER + ElementTree.tostring(doc).decode(SCO_ENCODING)
elif format == "json": elif format == "json":
REQUEST.RESPONSE.setHeader("content-type", JSON_MIMETYPE) REQUEST.RESPONSE.setHeader("content-type", JSON_MIMETYPE)
return "undefined" # XXX voir quoi faire en cas d'erreur json return "undefined" # XXX voir quoi faire en cas d'erreur json

View File

@ -35,14 +35,14 @@ Code dérivé de la partie la plus ancienne de ScoDoc, et à revoir.
L'API de plus bas niveau est en gros: L'API de plus bas niveau est en gros:
AnnuleAbsencesDatesNoJust(etudid, dates) AnnuleAbsencesDatesNoJust(etudid, dates)
CountAbs(etudid, debut, fin, matin=None, moduleimpl_id=None) count_abs(etudid, debut, fin, matin=None, moduleimpl_id=None)
CountAbsJust(etudid, debut, fin, matin=None, moduleimpl_id=None) count_abs_just(etudid, debut, fin, matin=None, moduleimpl_id=None)
ListeAbsJust(etudid, datedebut) [pas de fin ?] list_abs_just(etudid, datedebut) [pas de fin ?]
ListeAbsNonJust(etudid, datedebut) [pas de fin ?] list_abs_non_just(etudid, datedebut) [pas de fin ?]
ListeJustifs(etudid, datedebut, datefin=None, only_no_abs=True) list_abs_justifs(etudid, datedebut, datefin=None, only_no_abs=True)
ListeAbsJour(date, am=True, pm=True, is_abs=None, is_just=None) list_abs_jour(date, am=True, pm=True, is_abs=None, is_just=None)
ListeAbsNonJustJour(date, am=True, pm=True) list_abs_non_just_jour(date, am=True, pm=True)
""" """
@ -84,8 +84,8 @@ from app.scodoc import html_sco_header
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_abs_notification from app.scodoc import sco_abs_notification
from app.scodoc import sco_abs_views from app.scodoc import sco_abs_views
from app.scodoc import sco_cache
from app.scodoc import sco_compute_moy from app.scodoc import sco_compute_moy
from app.scodoc import sco_core
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_excel from app.scodoc import sco_excel
from app.scodoc import sco_find_etud from app.scodoc import sco_find_etud
@ -261,9 +261,10 @@ sco_publish("/ListeAbsEtud", sco_abs_views.ListeAbsEtud, Permission.ScoView)
# #
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# API backward compatibility
sco_publish("/CountAbs", sco_abs.CountAbs, Permission.ScoView) sco_publish("/CountAbs", sco_abs.count_abs, Permission.ScoView)
sco_publish("/CountAbsJust", sco_abs.CountAbsJust, Permission.ScoView) sco_publish("/CountAbsJust", sco_abs.count_abs_just, Permission.ScoView)
# TODO nouvel appel rendnat les deux valeurs et utilisant le cache
@bp.route("/doSignaleAbsenceGrSemestre", methods=["GET", "POST"]) @bp.route("/doSignaleAbsenceGrSemestre", methods=["GET", "POST"])
@ -361,7 +362,7 @@ def SignaleAbsenceGrHebdo(
else: else:
# Si aucun etudiant n'est inscrit au module choisi... # Si aucun etudiant n'est inscrit au module choisi...
moduleimpl_id = None moduleimpl_id = None
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id) nt = sco_cache.NotesTableCache.get(formsemestre_id)
sem = sco_formsemestre.do_formsemestre_list( sem = sco_formsemestre.do_formsemestre_list(
context, {"formsemestre_id": formsemestre_id} context, {"formsemestre_id": formsemestre_id}
)[0] )[0]
@ -534,7 +535,7 @@ def SignaleAbsenceGrSemestre(
base_url = base_url_noweeks + "&nbweeks=%s" % nbweeks # sans le moduleimpl_id base_url = base_url_noweeks + "&nbweeks=%s" % nbweeks # sans le moduleimpl_id
if etuds: if etuds:
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id) nt = sco_cache.NotesTableCache.get(formsemestre_id)
sem = sco_formsemestre.do_formsemestre_list( sem = sco_formsemestre.do_formsemestre_list(
context, {"formsemestre_id": formsemestre_id} context, {"formsemestre_id": formsemestre_id}
)[0] )[0]
@ -749,8 +750,8 @@ def _gen_form_saisie_groupe(
# UE capitalisee dans semestre courant ? # UE capitalisee dans semestre courant ?
cap = [] cap = []
if etud["cursem"]: if etud["cursem"]:
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(
context, etud["cursem"]["formsemestre_id"] etud["cursem"]["formsemestre_id"]
) # > get_ues, get_etud_ue_status ) # > get_ues, get_etud_ue_status
for ue in nt.get_ues(): for ue in nt.get_ues():
status = nt.get_etud_ue_status(etudid, ue["ue_id"]) status = nt.get_etud_ue_status(etudid, ue["ue_id"])
@ -775,7 +776,7 @@ def _gen_form_saisie_groupe(
) )
) )
etud_abs = sco_abs.list_abs_in_range( etud_abs = sco_abs.list_abs_in_range(
context, etudid, begin, end, moduleimpl_id=moduleimpl_id, cursor=cursor etudid, begin, end, moduleimpl_id=moduleimpl_id, cursor=cursor
) )
for d in odates: for d in odates:
date = d.strftime("%Y-%m-%d") date = d.strftime("%Y-%m-%d")
@ -879,15 +880,13 @@ def EtatAbsencesGr(
T = [] T = []
for m in groups_infos.members: for m in groups_infos.members:
etud = sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0] etud = sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
nbabs = sco_abs.CountAbs( nbabs = sco_abs.count_abs(etudid=etud["etudid"], debut=datedebut, fin=datefin)
context, etudid=etud["etudid"], debut=datedebut, fin=datefin nbabsjust = sco_abs.count_abs_just(
) etudid=etud["etudid"], debut=datedebut, fin=datefin
nbabsjust = sco_abs.CountAbsJust(
context, etudid=etud["etudid"], debut=datedebut, fin=datefin
) )
nbjustifs_noabs = len( nbjustifs_noabs = len(
sco_abs.ListeJustifs( sco_abs.list_abs_justifs(
context, etudid=etud["etudid"], datedebut=datedebut, only_no_abs=True etudid=etud["etudid"], datedebut=datedebut, only_no_abs=True
) )
) )
# retrouve sem dans etud['sems'] # retrouve sem dans etud['sems']
@ -1027,19 +1026,19 @@ def EtatAbsencesDate(
""" """
) )
for etud in groups_infos.members: for etud in groups_infos.members:
nbabsam = sco_abs.CountAbs( nbabsam = sco_abs.count_abs(
context, etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=1 etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=1
) )
nbabspm = sco_abs.CountAbs( nbabspm = sco_abs.count_abs(
context, etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=0 etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=0
) )
if (nbabsam != 0) or (nbabspm != 0): if (nbabsam != 0) or (nbabspm != 0):
nbetud += 1 nbetud += 1
nbabsjustam = sco_abs.CountAbsJust( nbabsjustam = sco_abs.count_abs_just(
context, etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=1 etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=1
) )
nbabsjustpm = sco_abs.CountAbsJust( nbabsjustpm = sco_abs.count_abs_just(
context, etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=0 etudid=etud["etudid"], debut=dateiso, fin=dateiso, matin=0
) )
H.append( H.append(
"""<tr bgcolor="#FFFFFF"><td> """<tr bgcolor="#FFFFFF"><td>
@ -1516,7 +1515,7 @@ def XMLgetAbsEtud(context, beg_date="", end_date="", REQUEST=None):
if not exp.match(end_date): if not exp.match(end_date):
raise ScoValueError("invalid date: %s" % end_date) raise ScoValueError("invalid date: %s" % end_date)
Abs = sco_abs.ListeAbsDate(context, etud["etudid"], beg_date, end_date) Abs = sco_abs.list_abs_date(etud["etudid"], beg_date, end_date)
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE) REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
doc = ElementTree.Element( doc = ElementTree.Element(

View File

@ -24,7 +24,7 @@ from app.auth.models import Permission
from app.views import essais_bp as bp from app.views import essais_bp as bp
# import sco_core deviendra: # import sco_core deviendra:
from app.scodoc import sco_core from app.scodoc import sco_cache
context = ScoDoc7Context(globals()) context = ScoDoc7Context(globals())
@ -47,11 +47,11 @@ def sco_exemple(etudid="NON"):
# En ScoDoc 7, on avait des vues qui en appellaient d'autres # En ScoDoc 7, on avait des vues qui en appellaient d'autres
# avec context.sco_exemple( etudid="E12" ) # avec context.sco_exemple( etudid="E12" )
@bp.route("/<scodoc_dept>/Scolarite/sco_exemple2") # @bp.route("/<scodoc_dept>/Scolarite/sco_exemple2")
@login_required # @login_required
@scodoc7func(context) # @scodoc7func(context)
def sco_exemple2(): # def sco_exemple2():
return "Exemple 2" + context.sco_exemple(etudid="deux") # return "Exemple 2" + context.sco_exemple(etudid="deux")
@bp.route("/<scodoc_dept>/Scolarite/sco_exemple3") @bp.route("/<scodoc_dept>/Scolarite/sco_exemple3")
@ -72,7 +72,7 @@ def sco_exemple4(toto):
@bp.route("/<scodoc_dept>/Scolarite/sco_get_version") @bp.route("/<scodoc_dept>/Scolarite/sco_get_version")
@scodoc7func(context) @scodoc7func(context)
def sco_get_version(REQUEST): def sco_get_version(REQUEST):
return sco_core.sco_get_version(REQUEST) return "ok"
# Fonction ressemblant à une méthode Zope protégée # Fonction ressemblant à une méthode Zope protégée

View File

@ -83,7 +83,6 @@ from app.scodoc import sco_bulletins_pdf
from app.scodoc import sco_cache 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_compute_moy from app.scodoc import sco_compute_moy
from app.scodoc import sco_core
from app.scodoc import sco_cost_formation from app.scodoc import sco_cost_formation
from app.scodoc import sco_debouche from app.scodoc import sco_debouche
from app.scodoc import sco_edit_formation from app.scodoc import sco_edit_formation
@ -951,8 +950,8 @@ def edit_moduleimpl_expr(context, REQUEST, moduleimpl_id):
}, },
formsemestre_id=sem["formsemestre_id"], formsemestre_id=sem["formsemestre_id"],
) )
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=sem["formsemestre_id"] formsemestre_id=sem["formsemestre_id"]
) # > modif regle calcul ) # > modif regle calcul
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
"moduleimpl_status?moduleimpl_id=" "moduleimpl_status?moduleimpl_id="
@ -976,16 +975,14 @@ def view_module_abs(context, REQUEST, moduleimpl_id, format="html"):
T = [] T = []
for etudid in list_insc: for etudid in list_insc:
nb_abs = sco_abs.CountAbs( nb_abs = sco_abs.count_abs(
context,
etudid=etudid, etudid=etudid,
debut=debut_sem, debut=debut_sem,
fin=fin_sem, fin=fin_sem,
moduleimpl_id=moduleimpl_id, moduleimpl_id=moduleimpl_id,
) )
if nb_abs: if nb_abs:
nb_abs_just = sco_abs.CountAbsJust( nb_abs_just = sco_abs.count_abs_just(
context,
etudid=etudid, etudid=etudid,
debut=debut_sem, debut=debut_sem,
fin=fin_sem, fin=fin_sem,
@ -1109,8 +1106,8 @@ def edit_ue_expr(context, REQUEST, formsemestre_id, ue_id):
else: else:
sco_compute_moy.formsemestre_ue_computation_expr_create(cnx, tf[2]) sco_compute_moy.formsemestre_ue_computation_expr_create(cnx, tf[2])
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) # > modif regle calcul ) # > modif regle calcul
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
"formsemestre_status?formsemestre_id=" "formsemestre_status?formsemestre_id="
@ -1274,7 +1271,7 @@ def formsemestre_desinscription(
raise ScoValueError("desinscription impossible: semestre verrouille") raise ScoValueError("desinscription impossible: semestre verrouille")
# -- Si décisions de jury, désinscription interdite # -- Si décisions de jury, désinscription interdite
nt = sco_core.get_notes_cache(context).get_NotesTable(context, formsemestre_id) nt = sco_cache.NotesTableCache.get(formsemestre_id)
if nt.etud_has_decision(etudid): if nt.etud_has_decision(etudid):
raise ScoValueError( raise ScoValueError(
"""Désinscription impossible: l'étudiant a une décision de jury """Désinscription impossible: l'étudiant a une décision de jury
@ -1733,9 +1730,7 @@ def formsemestre_bulletins_mailetuds(
): ):
"envoi a chaque etudiant (inscrit et ayant un mail) son bulletin" "envoi a chaque etudiant (inscrit et ayant un mail) son bulletin"
prefer_mail_perso = int(prefer_mail_perso) prefer_mail_perso = int(prefer_mail_perso)
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etudids
context, formsemestre_id
) # > get_etudids
etudids = nt.get_etudids() etudids = nt.get_etudids()
# #
if not sco_bulletins.can_send_bulletin_by_mail(context, formsemestre_id, REQUEST): if not sco_bulletins.can_send_bulletin_by_mail(context, formsemestre_id, REQUEST):
@ -1891,8 +1886,8 @@ def appreciation_add_form(
msg=tf[2]["comment"], msg=tf[2]["comment"],
) )
# ennuyeux mais necessaire (pour le PDF seulement) # ennuyeux mais necessaire (pour le PDF seulement)
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, pdfonly=True, formsemestre_id=formsemestre_id pdfonly=True, formsemestre_id=formsemestre_id
) # > appreciation_add ) # > appreciation_add
return REQUEST.RESPONSE.redirect(bull_url) return REQUEST.RESPONSE.redirect(bull_url)
@ -2131,9 +2126,7 @@ def formsemestre_validation_suppress_etud(
if not dialog_confirmed: if not dialog_confirmed:
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
nt = sco_core.get_notes_cache(context).get_NotesTable( nt = sco_cache.NotesTableCache.get(formsemestre_id) # > get_etud_decision_sem
context, formsemestre_id
) # > get_etud_decision_sem
decision_jury = nt.get_etud_decision_sem(etudid) decision_jury = nt.get_etud_decision_sem(etudid)
if decision_jury: if decision_jury:
existing = ( existing = (

View File

@ -83,7 +83,7 @@ from app.scodoc import sco_import_etuds
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_archives_etud from app.scodoc import sco_archives_etud
from app.scodoc import sco_codes_parcours from app.scodoc import sco_codes_parcours
from app.scodoc import sco_core from app.scodoc import sco_cache
from app.scodoc import sco_debouche from app.scodoc import sco_debouche
from app.scodoc import sco_dept from app.scodoc import sco_dept
from app.scodoc import sco_dump_db from app.scodoc import sco_dump_db
@ -246,8 +246,11 @@ def showEtudLog(context, etudid, format="html", REQUEST=None):
page_title="Opérations sur %(nomprenom)s" % etud, page_title="Opérations sur %(nomprenom)s" % etud,
html_title="<h2>Opérations effectuées sur l'étudiant %(nomprenom)s</h2>" % etud, html_title="<h2>Opérations effectuées sur l'étudiant %(nomprenom)s</h2>" % etud,
filename="log_" + scu.make_filename(etud["nomprenom"]), filename="log_" + scu.make_filename(etud["nomprenom"]),
html_next_section='<ul><li><a href="%s">fiche de %(nomprenom)s</a></li></ul>' html_next_section=f"""
% url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid), <ul><li>
<a href="{url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)}">
fiche de {etud['nomprenom']}</a></li>
</ul>""",
preferences=sco_preferences.SemPreferences( preferences=sco_preferences.SemPreferences(
context, context,
), ),
@ -1497,9 +1500,9 @@ def _etudident_create_or_edit_form(context, REQUEST, edit):
sco_etud.fill_etuds_info([etud]) sco_etud.fill_etuds_info([etud])
# Inval semesters with this student: # Inval semesters with this student:
to_inval = [s["formsemestre_id"] for s in etud["sems"]] to_inval = [s["formsemestre_id"] for s in etud["sems"]]
if to_inval: for formsemestre_id in to_inval:
sco_core.inval_cache( sco_cache.invalidate_formsemestre(
context, formsemestre_id_list=to_inval formsemestre_id=formsemestre_id
) # > etudident_create_or_edit ) # > etudident_create_or_edit
# #
return REQUEST.RESPONSE.redirect("ficheEtud?etudid=" + etudid) return REQUEST.RESPONSE.redirect("ficheEtud?etudid=" + etudid)
@ -1574,8 +1577,8 @@ def etudident_delete(context, etudid, dialog_confirmed=False, REQUEST=None):
cnx.commit() cnx.commit()
# Inval semestres où il était inscrit: # Inval semestres où il était inscrit:
to_inval = [s["formsemestre_id"] for s in etud["sems"]] to_inval = [s["formsemestre_id"] for s in etud["sems"]]
if to_inval: for formsemestre_id in to_inval:
sco_core.inval_cache(context, formsemestre_id_list=to_inval) # > sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id) # >
return REQUEST.RESPONSE.redirect( return REQUEST.RESPONSE.redirect(
scu.ScoURL() + r"?head_message=Etudiant%20supprimé" scu.ScoURL() + r"?head_message=Etudiant%20supprimé"
) )

0
misc/ArreteDUT2005.txt Normal file → Executable file
View File

View File

@ -1,34 +1,61 @@
asn1crypto==0.24.0 alembic==1.6.5
certifi==2018.8.24 astroid==2.6.2
chardet==3.0.4 Babel==2.9.1
configparser==3.5.0b2 blinker==1.4
cracklib==2.9.6 certifi==2021.5.30
cryptography==2.6.1 chardet==4.0.0
docutils==0.14 click==8.0.1
entrypoints==0.3 cracklib==2.9.3
enum34==1.1.6 dnspython==2.1.0
gyp==0.1 dominate==2.6.0
icalendar==4.0.3 email-validator==1.1.3
idna==2.6 Flask==2.0.1
ipaddress==1.0.17 Flask-Babel==2.0.0
jaxml==3.1 Flask-Bootstrap==3.3.7.1
keyring==17.1.1 Flask-Caching==1.10.1
keyrings.alt==3.1.1 Flask-Login==0.5.0
olefile==0.46 Flask-Mail==0.9.1
Pillow==5.4.1 Flask-Migrate==3.0.1
psycopg2==2.7.7 Flask-Moment==1.0.1
pycrypto==2.6.1 Flask-SQLAlchemy==2.5.1
Pygments==2.3.1 Flask-WTF==0.15.1
PyGObject==3.30.4 greenlet==1.1.0
pyOpenSSL==19.0.0 html2text==2020.1.16
icalendar==4.0.7
idna==2.10
importlib-metadata==4.6.1
isort==5.9.2
itsdangerous==2.0.1
Jinja2==3.0.1
lazy-object-proxy==1.6.0
Mako==1.1.4
MarkupSafe==2.0.1
mccabe==0.6.1
Pillow==8.3.1
pkg-resources==0.0.0
psycopg2==2.9.1
pydot==1.4.2
PyJWT==2.1.0
pylibmc==1.6.1
pylint==2.9.3
pylint-flask-sqlalchemy==0.2.0
pymemcache==3.5.0
pyparsing==2.4.7
PyRSS2Gen==1.1 PyRSS2Gen==1.1
python-dateutil==2.7.3 python-dateutil==2.8.1
pytz==2019.1 python-dotenv==0.18.0
pyxdg==0.25 python-editor==1.0.4
reportlab==3.5.13 pytz==2021.1
requests==2.21.0 reportlab==3.5.68
roman==2.0.0 requests==2.25.1
SecretStorage==2.3.1 six==1.16.0
six==1.12.0 SQLAlchemy==1.4.20
urllib3==1.24.1 toml==0.10.2
virtualenv==15.1.0 typed-ast==1.4.3
typing-extensions==3.10.0.0
urllib3==1.26.6
visitor==0.1.3
Werkzeug==2.0.1
wrapt==1.12.1
WTForms==2.3.3
zipp==3.5.0

0
scodoc_manager.py Normal file → Executable file
View File

View File

@ -12,6 +12,8 @@ from __future__ import print_function
from debug import go_dept from debug import go_dept
import time import time
from app.scodoc import sco_cache
DeptName = "CJ" DeptName = "CJ"
context = go_dept(app, DeptName) context = go_dept(app, DeptName)
@ -23,7 +25,7 @@ L = []
n = 0 n = 0
for sem in sems: for sem in sems:
formsemestre_id = sem["formsemestre_id"] formsemestre_id = sem["formsemestre_id"]
nt = context.Notes._getNotesCache().get_NotesTable(context.Notes, formsemestre_id) nt = sco_cache.NotesTableCache.get(formsemestre_id)
etudids = nt.get_etudids() etudids = nt.get_etudids()
use_ue_coef = sco_preferences.get_preference( use_ue_coef = sco_preferences.get_preference(
context, "use_ue_coefs", formsemestre_id context, "use_ue_coefs", formsemestre_id

View File

@ -53,44 +53,62 @@ for debut, fin, demijournee in [
("15/01/2021", "15/01/2021", 1), ("15/01/2021", "15/01/2021", 1),
("18/01/2021", "18/01/2021", 0), ("18/01/2021", "18/01/2021", 0),
("19/01/2021", "19/01/2021", 2), ("19/01/2021", "19/01/2021", 2),
("22/01/2021", "22/01/2021", 1) ("22/01/2021", "22/01/2021", 1),
] : ]:
sco_abs_views.doSignaleAbsence(context.Absences, datedebut=debut, datefin=fin, demijournee=demijournee, etudid=etudid, REQUEST=REQUEST) sco_abs_views.doSignaleAbsence(
context.Absences,
datedebut=debut,
datefin=fin,
demijournee=demijournee,
etudid=etudid,
REQUEST=REQUEST,
)
# --- Justification de certaines absences # --- Justification de certaines absences
for debut, fin, demijournee in [ for debut, fin, demijournee in [
("15/01/2021", "15/01/2021", 1), ("15/01/2021", "15/01/2021", 1),
("18/01/2021", "18/01/2021", 0), ("18/01/2021", "18/01/2021", 0),
("19/01/2021", "19/01/2021", 2) ("19/01/2021", "19/01/2021", 2),
] : ]:
sco_abs_views.doJustifAbsence(context.Absences, datedebut=debut, datefin=fin, demijournee=demijournee, etudid=etudid, REQUEST=REQUEST) sco_abs_views.doJustifAbsence(
context.Absences,
datedebut=debut,
datefin=fin,
demijournee=demijournee,
etudid=etudid,
REQUEST=REQUEST,
)
# --- Utilisation de CountAbs() de sco_abs # --- Utilisation de get_abs_count() de sco_abs
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid)
nb_abs = a.CountAbs()
nb_absj = a.CountAbsJust()
# --- Utilisation de CountAbs() de ZAbsences # --- Utilisation de CountAbs() de ZAbsences
nb_abs2 = context.Absences.CountAbs(etudid=etudid, debut="01/01/2021", fin="06/30/2021") nb_abs2 = context.Absences.CountAbs(etudid=etudid, debut="01/01/2021", fin="06/30/2021")
nb_absj2 = context.Absences.CountAbsJust(etudid=etudid, debut="01/01/2021", fin="06/30/2021") nb_absj2 = context.Absences.CountAbsJust(
etudid=etudid, debut="01/01/2021", fin="06/30/2021"
)
assert nb_abs == nb_abs2 == 5 assert nbabs == nb_abs2 == 5
assert nb_absj == nb_absj2 == 4 assert nbabsjust == nb_absj2 == 4
# --- Supression d'absence # --- Suppression d'absence
_ = sco_abs_views.doAnnuleAbsence(context.Absences, "19/01/2021", "19/01/2021", 2, etudid=etudid, REQUEST=REQUEST) _ = sco_abs_views.doAnnuleAbsence(
b = sco_abs.getAbsSemEtud(context.Absences, sem, etudid) context.Absences, "19/01/2021", "19/01/2021", 2, etudid=etudid, REQUEST=REQUEST
)
# --- Vérification # --- Vérification
new_nbabs = b.CountAbs() new_nbabs, _ = sco_abs.get_abs_count(etudid, sem)
new_nbabs2 = context.Absences.CountAbs(etudid=etudid, debut="01/01/2021", fin="06/30/2021") new_nbabs2 = context.Absences.CountAbs(
etudid=etudid, debut="01/01/2021", fin="06/30/2021"
)
print(new_nbabs) print(new_nbabs)
print(new_nbabs2) print(new_nbabs2)

View File

@ -104,14 +104,16 @@ _ = sco_abs_views.doJustifAbsence(
# --- Test # --- Test
a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid) nbabs, nbabs_just = sco_abs.get_abs_count(etudid, sem)
assert a.CountAbs() == 4 #l'étudiant a été absent le 15 journée compléte (2 abs : 1 matin, 1 apres midi) et le 18 (1 matin), et le 19 (1 apres midi). assert (
assert a.CountAbsJust() == 2 # Justifie abs du matin + abs après midi nbabs == 4
) # l'étudiant a été absent le 15 journée compléte (2 abs : 1 matin, 1 apres midi) et le 18 (1 matin), et le 19 (1 apres midi).
assert nbabs_just == 2 # Justifie abs du matin + abs après midi
""" """
Commentaire : Commentaire :
Pb : le 2 ne peut pas être pris en tant que int car string dans la fonction Pb : le 2 ne peut pas être pris en tant que int car string dans la fonction
-----> Pb regler -----> Pb reglé
""" """

View File

@ -6,11 +6,9 @@ Fonctions de l'API utilisé :
- doSignaleAbsence - doSignaleAbsence
- doAnnuleAbsence - doAnnuleAbsence
- doJustifAbsence - doJustifAbsence
- getAbsSemEtud
- get_partition_groups - get_partition_groups
- get_partitions_list - get_partitions_list
- CountAbs - sco_abs.get_abs_count(etudid, sem)
- CountAbsJust
- ListeAbsEtud - ListeAbsEtud
- partition_create - partition_create
- createGroup - createGroup
@ -71,7 +69,7 @@ mi = G.create_moduleimpl(
for etud in etuds: for etud in etuds:
G.inscrit_etudiant(sem, etud) G.inscrit_etudiant(sem, etud)
#--- Création d'une évaluation # --- Création d'une évaluation
e = G.create_evaluation( e = G.create_evaluation(
moduleimpl_id=mi["moduleimpl_id"], moduleimpl_id=mi["moduleimpl_id"],
jour="22/01/2021", jour="22/01/2021",
@ -151,23 +149,26 @@ _ = sco_abs_views.doJustifAbsence(
# --- Test # --- Test
b = sco_abs.is_work_saturday(context.Absences) b = sco_abs.is_work_saturday(context.Absences)
assert b == 0 #samedi ne sont pas compris assert b == 0 # samedi ne sont pas compris
a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid) nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
assert a.CountAbs() == 5 #l'étudiant a été absent le 15 (apres midi) , (16 et 17 we), 18 (matin) et 19 janvier (matin et apres midi), et 22 (matin) assert (
assert a.CountAbsJust() == 4 #l'étudiant justifie ses abs du 15, 18 et 19 nbabs == 5
) # l'étudiant a été absent le 15 (apres midi) , (16 et 17 we), 18 (matin) et 19 janvier (matin et apres midi), et 22 (matin)
assert nbabsjust == 4 # l'étudiant justifie ses abs du 15, 18 et 19
# + vérification à l'aide de ScoDoc WEB : ok! # + vérification à l'aide de ScoDoc WEB : ok!
# --- Supression d'une absence et d'une justification # --- Supression d'une absence et d'une justification
_ = sco_abs_views.doAnnuleAbsence(context.Absences, "19/01/2021", "19/01/2021", 2, etudid=etudid, REQUEST=REQUEST) _ = sco_abs_views.doAnnuleAbsence(
a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid) context.Absences, "19/01/2021", "19/01/2021", 2, etudid=etudid, REQUEST=REQUEST
print(a.CountAbs()) #lors du print cela affiche 5 or cela devrait afficher 3 )
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
#assert a.CountAbs() == 3 print(nbabs) # lors du print cela affiche 5 or cela devrait afficher 3
# + vérification à l'aide de ScoDoc WEB : il y a bien plus que 3 abs, 2 justifiés et 1 non justifié.
# assert nbabs == 3
# + vérification à l'aide de ScoDoc WEB : il y a bien plus que 3 abs, 2 justifiés et 1 non justifié.
# --- supression d'une justification pas encore disponible à l'aide de python. # --- supression d'une justification pas encore disponible à l'aide de python.
@ -175,8 +176,12 @@ print(a.CountAbs()) #lors du print cela affiche 5 or cela devrait afficher 3
# --- Création d'une liste d'abs # --- Création d'une liste d'abs
liste_abs = sco_abs_views.ListeAbsEtud(context.Absences, etudid, format='json', absjust_only=1, REQUEST=REQUEST) liste_abs = sco_abs_views.ListeAbsEtud(
liste_abs2 = sco_abs_views.ListeAbsEtud(context.Absences, etudid, format='json', REQUEST=REQUEST) context.Absences, etudid, format="json", absjust_only=1, REQUEST=REQUEST
)
liste_abs2 = sco_abs_views.ListeAbsEtud(
context.Absences, etudid, format="json", REQUEST=REQUEST
)
load_liste_abs = json.loads(liste_abs) load_liste_abs = json.loads(liste_abs)
load_liste_abs2 = json.loads(liste_abs2) load_liste_abs2 = json.loads(liste_abs2)
@ -191,61 +196,78 @@ assert load_liste_abs2[0]["exams"] == mod["code"]
# --- Création d'un groupe # --- Création d'un groupe
_ = sco_groups.partition_create(context.Scolarite, formsemestre_id=sem["formsemestre_id"], partition_name="Eleve", REQUEST=REQUEST) _ = sco_groups.partition_create(
context.Scolarite,
formsemestre_id=sem["formsemestre_id"],
partition_name="Eleve",
REQUEST=REQUEST,
)
li1 = sco_groups.get_partitions_list(context.Scolarite, sem["formsemestre_id"]) li1 = sco_groups.get_partitions_list(context.Scolarite, sem["formsemestre_id"])
_ = sco_groups.createGroup(context.Scolarite, li1[0]["partition_id"], "Groupe 1", REQUEST=REQUEST) _ = sco_groups.createGroup(
context.Scolarite, li1[0]["partition_id"], "Groupe 1", REQUEST=REQUEST
)
# --- Affectation des élèves dans des groupes # --- Affectation des élèves dans des groupes
li_grp1 = sco_groups.get_partition_groups(context.Scolarite, li1[0]) li_grp1 = sco_groups.get_partition_groups(context.Scolarite, li1[0])
for etud in etuds : for etud in etuds:
sco_groups.set_group(context.Scolarite, etud["etudid"], li_grp1[0]["group_id"]) sco_groups.set_group(context.Scolarite, etud["etudid"], li_grp1[0]["group_id"])
# --- Test de EtatAbsencesGroupes # --- Test de EtatAbsencesGroupes
grp1_abs = context.Absences.EtatAbsencesGr(group_ids=[li_grp1[0]["group_id"]], debut="01/01/2021", fin ="30/06/2021", format="json", REQUEST=REQUEST) grp1_abs = context.Absences.EtatAbsencesGr(
group_ids=[li_grp1[0]["group_id"]],
debut="01/01/2021",
fin="30/06/2021",
format="json",
REQUEST=REQUEST,
)
load_grp1_abs = json.loads(grp1_abs) load_grp1_abs = json.loads(grp1_abs)
assert len(load_grp1_abs) == 10 assert len(load_grp1_abs) == 10
tab_id=[] #tab des id present dans load_grp1_abs tab_id = [] # tab des id present dans load_grp1_abs
for un_etud in load_grp1_abs : for un_etud in load_grp1_abs:
tab_id.append(un_etud["etudid"]) tab_id.append(un_etud["etudid"])
for etud in etuds : #verification si tous les etudiants sont present dans la liste du groupe d'absence for (
etud
) in (
etuds
): # verification si tous les etudiants sont present dans la liste du groupe d'absence
assert etud["etudid"] in tab_id assert etud["etudid"] in tab_id
for un_etud in load_grp1_abs : for un_etud in load_grp1_abs:
if un_etud["etudid"] == etudid : if un_etud["etudid"] == etudid:
assert un_etud["nbabs"] == "3" assert un_etud["nbabs"] == "3"
assert un_etud["nbjustifs_noabs"] == "2" assert un_etud["nbjustifs_noabs"] == "2"
assert un_etud["nbabsjust"] == "2" assert un_etud["nbabsjust"] == "2"
assert un_etud["nbabsnonjust"] == "1" assert un_etud["nbabsnonjust"] == "1"
assert un_etud["nomprenom"] == etuds[0]["nomprenom"] assert un_etud["nomprenom"] == etuds[0]["nomprenom"]
# --- Création de billets # --- Création de billets
b1 = context.Absences.AddBilletAbsence( b1 = context.Absences.AddBilletAbsence(
begin="2021-01-22 00:00", begin="2021-01-22 00:00",
end="2021-01-22 23:59", end="2021-01-22 23:59",
etudid=etudid, etudid=etudid,
description = "abs du 22", description="abs du 22",
justified=False, justified=False,
code_nip=etuds[0]["code_nip"], code_nip=etuds[0]["code_nip"],
code_ine=etuds[0]["code_ine"], code_ine=etuds[0]["code_ine"],
REQUEST=REQUEST, REQUEST=REQUEST,
) )
b2 = context.Absences.AddBilletAbsence( b2 = context.Absences.AddBilletAbsence(
begin="2021-01-15 00:00", begin="2021-01-15 00:00",
end="2021-01-15 23:59", end="2021-01-15 23:59",
etudid=etudid, etudid=etudid,
description = "abs du 15", description="abs du 15",
code_nip=etuds[0]["code_nip"], code_nip=etuds[0]["code_nip"],
code_ine=etuds[0]["code_ine"], code_ine=etuds[0]["code_ine"],
REQUEST=REQUEST, REQUEST=REQUEST,
) )
li_bi = context.Absences.listeBilletsEtud(etudid=etudid, REQUEST=REQUEST, format="json") li_bi = context.Absences.listeBilletsEtud(etudid=etudid, REQUEST=REQUEST, format="json")

View File

@ -12,11 +12,11 @@ Fonction de l'API utilisé :
- AddBilletAbs - AddBilletAbs
- XMLgetBilletAbsence - XMLgetBilletAbsence
- listeBilletEtud - listeBilletEtud
- ListeAbsJust - list_abs_just
- CountAbsJust - CountAbsJust
- ListAbsNonJust - ListAbsNonJust
- ListJustifs - ListJustifs
- ListeAbsJour - list_abs_jour
- ListAbsInRange - ListAbsInRange
Fonction renvoyant du code HTML : Fonction renvoyant du code HTML :
@ -83,14 +83,21 @@ for etud in etuds:
# --- Création d'un groupe # --- Création d'un groupe
_ = sco_groups.partition_create(context.Scolarite, formsemestre_id=sem["formsemestre_id"], partition_name="Eleve", REQUEST=REQUEST) _ = sco_groups.partition_create(
context.Scolarite,
formsemestre_id=sem["formsemestre_id"],
partition_name="Eleve",
REQUEST=REQUEST,
)
li1 = sco_groups.get_partitions_list(context.Scolarite, sem["formsemestre_id"]) li1 = sco_groups.get_partitions_list(context.Scolarite, sem["formsemestre_id"])
_ = sco_groups.createGroup(context.Scolarite, li1[0]["partition_id"], "Groupe 1", REQUEST=REQUEST) _ = sco_groups.createGroup(
context.Scolarite, li1[0]["partition_id"], "Groupe 1", REQUEST=REQUEST
)
# --- Affectation des élèves dans des groupes # --- Affectation des élèves dans des groupes
li_grp1 = sco_groups.get_partition_groups(context.Scolarite, li1[0]) li_grp1 = sco_groups.get_partition_groups(context.Scolarite, li1[0])
for etud in etuds : for etud in etuds:
sco_groups.set_group(context.Scolarite, etud["etudid"], li_grp1[0]["group_id"]) sco_groups.set_group(context.Scolarite, etud["etudid"], li_grp1[0]["group_id"])
# --- Saisie absences # --- Saisie absences
@ -100,9 +107,16 @@ for debut, fin, demijournee in [
("15/01/2021", "15/01/2021", 1), ("15/01/2021", "15/01/2021", 1),
("18/01/2021", "18/01/2021", 0), ("18/01/2021", "18/01/2021", 0),
("19/01/2021", "19/01/2021", 2), ("19/01/2021", "19/01/2021", 2),
("22/01/2021", "22/01/2021", 1) ("22/01/2021", "22/01/2021", 1),
] : ]:
sco_abs_views.doSignaleAbsence(context.Absences, datedebut=debut, datefin=fin, demijournee=demijournee, etudid=etudid, REQUEST=REQUEST) sco_abs_views.doSignaleAbsence(
context.Absences,
datedebut=debut,
datefin=fin,
demijournee=demijournee,
etudid=etudid,
REQUEST=REQUEST,
)
_ = sco_abs_views.doSignaleAbsence( _ = sco_abs_views.doSignaleAbsence(
context.Absences, context.Absences,
@ -115,44 +129,51 @@ _ = sco_abs_views.doSignaleAbsence(
# --- Justification de certaines absences # --- Justification de certaines absences
for debut, fin, demijournee in [ for debut, fin, demijournee in [
("15/01/2021", "15/01/2021", 1), ("15/01/2021", "15/01/2021", 1),
("18/01/2021", "18/01/2021", 0), ("18/01/2021", "18/01/2021", 0),
("19/01/2021", "19/01/2021", 2) ("19/01/2021", "19/01/2021", 2),
] : ]:
sco_abs_views.doJustifAbsence(context.Absences, datedebut=debut, datefin=fin, demijournee=demijournee, etudid=etudid, REQUEST=REQUEST) sco_abs_views.doJustifAbsence(
context.Absences,
datedebut=debut,
datefin=fin,
demijournee=demijournee,
etudid=etudid,
REQUEST=REQUEST,
)
# --- Test # --- Test
_ = context.Absences.doSignaleAbsenceGrSemestre( _ = context.Absences.doSignaleAbsenceGrSemestre(
dates="2021-01-13,2021-01-25", dates="2021-01-13,2021-01-25",
etudids= etuds[5]["etudid"]+","+etuds[6]["etudid"], etudids=etuds[5]["etudid"] + "," + etuds[6]["etudid"],
destination="", destination="",
REQUEST=REQUEST REQUEST=REQUEST,
) # <----- rien ne se passe (pb parametre ?) ) # <----- rien ne se passe (pb parametre ?)
# --- Création de billets # --- Création de billets
b1 = context.Absences.AddBilletAbsence( b1 = context.Absences.AddBilletAbsence(
begin="2021-01-22 00:00", begin="2021-01-22 00:00",
end="2021-01-22 23:59", end="2021-01-22 23:59",
etudid=etudid, etudid=etudid,
description = "abs du 22", description="abs du 22",
justified=False, justified=False,
code_nip=etuds[0]["code_nip"], code_nip=etuds[0]["code_nip"],
code_ine=etuds[0]["code_ine"], code_ine=etuds[0]["code_ine"],
REQUEST=REQUEST, REQUEST=REQUEST,
) )
b2 = context.Absences.AddBilletAbsence( b2 = context.Absences.AddBilletAbsence(
begin="2021-01-15 00:00", begin="2021-01-15 00:00",
end="2021-01-15 23:59", end="2021-01-15 23:59",
etudid=etudid, etudid=etudid,
description = "abs du 15", description="abs du 15",
code_nip=etuds[0]["code_nip"], code_nip=etuds[0]["code_nip"],
code_ine=etuds[0]["code_ine"], code_ine=etuds[0]["code_ine"],
REQUEST=REQUEST, REQUEST=REQUEST,
) )
# --- XMLgetBilletEtud # --- XMLgetBilletEtud
@ -161,22 +182,24 @@ print(1)
print(xml_bi) print(xml_bi)
print(1) print(1)
# --- Supression de billet # --- Supression de billet
li_bi = context.Absences.listeBilletsEtud(etudid=etudid, REQUEST=REQUEST, format="json") li_bi = context.Absences.listeBilletsEtud(etudid=etudid, REQUEST=REQUEST, format="json")
load_li_bi = json.loads(li_bi) load_li_bi = json.loads(li_bi)
#_ = context.Absences.deleteBilletAbsence(load_li_bi[1]["billet_id"], REQUEST=REQUEST) # _ = context.Absences.deleteBilletAbsence(load_li_bi[1]["billet_id"], REQUEST=REQUEST)
li_bi2 = context.Absences.listeBilletsEtud(etudid=etudid, REQUEST=REQUEST, format="json") li_bi2 = context.Absences.listeBilletsEtud(
etudid=etudid, REQUEST=REQUEST, format="json"
)
load_li_bi2 = json.loads(li_bi) load_li_bi2 = json.loads(li_bi)
#assert len(load_li_bi2) == 1 # assert len(load_li_bi2) == 1
#assert load_li_bi2[0]["description"] == "abs du 22" # assert load_li_bi2[0]["description"] == "abs du 22"
# --- Créaton de listes # --- Créaton de listes
li_abs_just = context.Absences.ListeAbsJust(etudid = etudid, datedebut="01/01/2021") li_abs_just = sco_abs.list_abs_just(etudid=etudid, datedebut="01/01/2021")
nb_abs_just = context.Absences.CountAbsJust(etudid, debut="01/01/2021", fin="06/30/2021") nb_abs_just = sco_abs.count_abs_just(etudid, debut="01/01/2021", fin="06/30/2021")
assert len(li_abs_just) == nb_abs_just assert len(li_abs_just) == nb_abs_just
assert li_abs_just[0]["etudid"] == etudid assert li_abs_just[0]["etudid"] == etudid
assert li_abs_just[0]["matin"] == True assert li_abs_just[0]["matin"] == True
@ -193,57 +216,64 @@ assert li_abs_njust[0]["etudid"] == etudid
assert li_abs_njust[0]["jour"] == datetime.date(2021, 1, 22) assert li_abs_njust[0]["jour"] == datetime.date(2021, 1, 22)
li_just = context.Absences.ListeJustifs(etudid=etudid, datedebut="01/01/2021") li_just = sco_abs.list_abs_justifs(etudid=etudid, datedebut="2021-01-01")
assert len(li_just) == 4 assert len(li_just) == 4
li_just2 = context.Absences.ListeJustifs(etudid=etudid, datedebut="01/01/2021", datefin="01/18/2021") li_just2 = context.Absences.list_abs_justifs(
etudid=etudid, datedebut="2021-01-01", datefin="2021-01-18"
)
assert len(li_just2) == 2 assert len(li_just2) == 2
li_jour = context.Absences.ListeAbsJour(date="01/22/2021") li_jour = sco_abs.list_abs_jour(date="01/22/2021")
assert len(li_jour) == 2 assert len(li_jour) == 2
li_jour2 = context.Absences.ListeAbsJour(date="01/18/2021") li_jour2 = sco_abs.list_abs_jour(date="01/18/2021")
assert len(li_jour2) == 1 assert len(li_jour2) == 1
li_range = context.Absences.ListAbsInRange(etudid, debut="01/01/2021", fin="06/01/2021") li_range = context.Absences.ListAbsInRange(etudid, debut="01/01/2021", fin="06/01/2021")
assert len(li_range) == 5 assert len(li_range) == 5
#li_xml = context.Absences.XMLgetAbsEtud(beg_date="01/01/2021", end_date="01/06/2021", REQUEST=REQUEST) # li_xml = context.Absences.XMLgetAbsEtud(beg_date="01/01/2021", end_date="01/06/2021", REQUEST=REQUEST)
#print(li_xml) need etudid # print(li_xml) need etudid
# --- Annulation d'absence # --- Annulation d'absence
#context.Absences.AnnuleAbsencesDatesNoJust(etudid, dates="22/01/2021", REQUEST=REQUEST) # context.Absences.AnnuleAbsencesDatesNoJust(etudid, dates="22/01/2021", REQUEST=REQUEST)
# --- Fonction renvoyant du code HTML # --- Fonction renvoyant du code HTML
etat_abs = context.Absences.EtatAbsences(REQUEST=REQUEST) etat_abs = context.Absences.EtatAbsences(REQUEST=REQUEST)
#cal_abs = sco_abs_views.CalAbs(context.Absences, REQUEST=REQUEST) #<--- retourne html + need etudid : how? # cal_abs = sco_abs_views.CalAbs(context.Absences, REQUEST=REQUEST) #<--- retourne html + need etudid : how?
sag = context.Absences.SignaleAbsenceGrSemestre( sag = context.Absences.SignaleAbsenceGrSemestre(
datedebut="15/01/2021", datedebut="15/01/2021",
datefin="22/01/2021", datefin="22/01/2021",
group_ids=[li_grp1[0]["group_id"]], group_ids=[li_grp1[0]["group_id"]],
REQUEST=REQUEST, REQUEST=REQUEST,
) )
sagh = context.Absences.SignaleAbsenceGrHebdo( sagh = context.Absences.SignaleAbsenceGrHebdo(
datelundi="18/01/2021", group_ids=[li_grp1[0]["group_id"]], destination="", REQUEST=REQUEST datelundi="18/01/2021",
) group_ids=[li_grp1[0]["group_id"]],
destination="",
REQUEST=REQUEST,
)
grp_abs_d = context.Absences.EtatAbsencesDate(group_ids=[li_grp1[0]["group_id"]], date="22/01/2021", REQUEST=REQUEST) grp_abs_d = context.Absences.EtatAbsencesDate(
group_ids=[li_grp1[0]["group_id"]], date="22/01/2021", REQUEST=REQUEST
)
billet_form = context.Absences.AddBilletAbsenceForm(etudid=etudid, REQUEST=REQUEST) billet_form = context.Absences.AddBilletAbsenceForm(etudid=etudid, REQUEST=REQUEST)
#an_abs = AnnuleAbsenceEtud(context.Absences, REQUEST=REQUEST) #<- retourne html + need etudid : how? # an_abs = AnnuleAbsenceEtud(context.Absences, REQUEST=REQUEST) #<- retourne html + need etudid : how?
#proc = context.Absences.ProcessBilletAbsenceForm(billet_id=load_li_bi[0]["billet_id"], REQUEST=REQUEST) #error # proc = context.Absences.ProcessBilletAbsenceForm(billet_id=load_li_bi[0]["billet_id"], REQUEST=REQUEST) #error
#just_form = sco_abs_views.JustifAbsenceEtud(context.Absences, REQUEST=REQUEST) # just_form = sco_abs_views.JustifAbsenceEtud(context.Absences, REQUEST=REQUEST)
#delete_just = sco_abs_views.doAnnuleJustif(context.Absences, datedebut0="22/01/2021", datefin0="22/01/2021", demijournee=2, REQUEST=REQUEST) # delete_just = sco_abs_views.doAnnuleJustif(context.Absences, datedebut0="22/01/2021", datefin0="22/01/2021", demijournee=2, REQUEST=REQUEST)
""" """
@ -263,5 +293,3 @@ XMLgetBilletsEtud, deleteBilletAbsence -> fonction get ne retourne rien et delet
AnnuleAbsencesDatesNoJust -> error line 323, jour='2' (2 doit être un int et non un string?) AnnuleAbsencesDatesNoJust -> error line 323, jour='2' (2 doit être un int et non un string?)
""" """

View File

@ -152,9 +152,9 @@ _ = sco_abs_views.doJustifAbsence(
REQUEST=REQUEST, REQUEST=REQUEST,
) )
a = sco_abs.getAbsSemEtud(context, sem, etudid) nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
assert a.CountAbs() == 6, "incorrect CountAbs (%d)" % a.CountAbs() assert nbabs == 6, "incorrect nbabs (%d)" % nbabs
assert a.CountAbsJust() == 2, "incorrect CountAbsJust (%s)" % a.CountAbsJust() assert nbabsjust == 2, "incorrect nbabsjust (%s)" % nbabsjust
# --- Permission saisie notes et décisions de jury, avec ou sans démission ou défaillance # --- Permission saisie notes et décisions de jury, avec ou sans démission ou défaillance
# on n'a pas encore saisi de décisions # on n'a pas encore saisi de décisions