# -*- coding: UTF-8 -* """ScoDoc Flask views """ import datetime from functools import cached_property from flask import Blueprint from flask import g, current_app, request from flask_login import current_user from app import db from app.models import Identite from app.models.formsemestre import FormSemestre from app.scodoc import notesdb as ndb from app.scodoc import sco_assiduites from app.scodoc import sco_formsemestre_status from app.scodoc import sco_preferences from app.scodoc.html_sidebar import retreive_formsemestre_from_request from app.scodoc.sco_permissions import Permission from app.scodoc import sco_utils as scu import sco_version scodoc_bp = Blueprint("scodoc", __name__) scolar_bp = Blueprint("scolar", __name__) notes_bp = Blueprint("notes", __name__) users_bp = Blueprint("users", __name__) absences_bp = Blueprint("absences", __name__) assiduites_bp = Blueprint("assiduites", __name__) # Cette fonction est bien appelée avant toutes les requêtes # de tous les blueprints # mais apparemment elle n'a pas acces aux arguments @scodoc_bp.before_app_request def start_scodoc_request(): """Affecte toutes les requêtes, de tous les blueprints""" # current_app.logger.info(f"start_scodoc_request") ndb.open_db_connection() if current_user and current_user.is_authenticated: current_user.last_seen = datetime.datetime.utcnow() db.session.commit() # caches locaux (durée de vie=la requête en cours) g.stored_get_formsemestre = {} # g.stored_etud_info = {} optim en cours, voir si utile @scodoc_bp.teardown_app_request def close_dept_db_connection(arg): # current_app.logger.info("close_db_connection") ndb.close_db_connection() class ScoData: """Classe utilisée pour passer des valeurs aux vues (templates)""" def __init__(self, etud: Identite = None, formsemestre: FormSemestre = None): # Champs utilisés par toutes les pages ScoDoc (sidebar, en-tête) self.Permission = Permission self.scu = scu self.SCOVERSION = sco_version.SCOVERSION self._init_etud = etud self._init_formsemestre = formsemestre # les comptes d'absences sont initialisés lors de l'accès à etud_cur_sem self.nb_abs_nj = 0 self.nb_abs_just = 0 self.nb_abs = 0 # .etud, .formsemestre, etc. sont des cached_property # car ScoData() est créé par @context_processor # AVANT le décorateur scodoc qui initialise g.scodoc_xxx @cached_property def etud(self) -> Identite | None: "Informations étudiant courant, si sélectionné" if self._init_etud is None: etudid = g.get("etudid", None) if etudid is None: if request.method == "GET": etudid = request.args.get("etudid", None) elif request.method == "POST": etudid = request.form.get("etudid", None) if etudid is not None: return Identite.get_etud(etudid) return self._init_etud @cached_property def etud_cur_sem(self) -> FormSemestre | None: "le semestre courant de l'étudiant courant" etud = self.etud if etud is None: return None ins = self.etud.inscription_courante() cur_sem = ins.formsemestre if ins: ( self.nb_abs_nj, self.nb_abs_just, self.nb_abs, ) = sco_assiduites.get_assiduites_count_in_interval( etud.id, cur_sem.date_debut.isoformat(), cur_sem.date_fin.isoformat(), scu.translate_assiduites_metric( sco_preferences.get_preference("assi_metrique") ), ) return cur_sem return None @cached_property def formsemestre(self) -> FormSemestre | None: "Le formsemestre courant, si sélectionné" if self._init_formsemestre is None: formsemestre_id = retreive_formsemestre_from_request() return ( FormSemestre.get_formsemestre(formsemestre_id) if formsemestre_id is not None else None ) return self._init_formsemestre @cached_property def sem_menu_bar(self) -> str | None: "Le html de la bare de menu formsemestre s'il y en a un." return ( sco_formsemestre_status.formsemestre_status_menubar(self.formsemestre) if self.formsemestre else None ) @cached_property def prefs(self): "Préférences" # prefs fallback to global pref if no current formsemestre: return sco_preferences.SemPreferences( self.formsemestre.id if self.formsemestre else None ) def formsemestre_status_menu_bar(self) -> str: "Le HTML de la barre de menu semestre" return sco_formsemestre_status.formsemestre_status_menubar(self.formsemestre) # Ajout des routes from app.but import bulletin_but_court # ne pas enlever: ajoute des routes ! from app.but import jury_dut120 # ne pas enlever: ajoute des routes ! from app.pe import pe_view # ne pas enlever, ajoute des routes ! from app.views import ( absences, assiduites, but_formation, jury_validations, notes_formsemestre, notes, pn_modules, refcomp, scodoc, scolar, users, user_board, )