Modif config Jina2. Refonte ScoData, fournit par défaut à tous les templates.

This commit is contained in:
Emmanuel Viennet 2024-04-06 12:16:53 +02:00
parent 5a5ddcacd7
commit 2b150cf521
11 changed files with 107 additions and 82 deletions

View File

@ -315,12 +315,6 @@ def create_app(config_class=DevConfig):
app.register_error_handler(503, postgresql_server_error)
app.register_error_handler(APIInvalidParams, handle_invalid_usage)
# Add some globals
# previously in Flask-Bootstrap:
app.jinja_env.globals["bootstrap_is_hidden_field"] = lambda field: isinstance(
field, HiddenField
)
from app.auth import bp as auth_bp
app.register_blueprint(auth_bp, url_prefix="/auth")
@ -338,8 +332,15 @@ def create_app(config_class=DevConfig):
from app.api import api_bp
from app.api import api_web_bp
# Jinja2 configuration
# Enable autoescaping of all templates, including .j2
app.jinja_env.autoescape = select_autoescape(default_for_string=True, default=True)
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
# previously in Flask-Bootstrap:
app.jinja_env.globals["bootstrap_is_hidden_field"] = lambda field: isinstance(
field, HiddenField
)
# https://scodoc.fr/ScoDoc
app.register_blueprint(scodoc_bp)

View File

@ -1,6 +1,4 @@
{# Base de toutes les pages ScoDoc #}
{% block doc -%}
<!DOCTYPE html>
{%- block doc -%}<!DOCTYPE html>{# Base de toutes les pages ScoDoc #}
<html{% block html_attribs %}{% endblock html_attribs %}>
{%- block html %}
<head>

View File

@ -1,5 +1,5 @@
{# -*- mode: jinja-html -*- #}
{% extends "base.j2" %}
{% extends "sco_page.j2" %}
{% import 'wtf.j2' as wtf %}
{% block app_content %}

View File

@ -3,31 +3,31 @@
<!-- formsemestre_header -->
<div class="formsemestre_page_title noprint">
<div class="infos">
<span class="semtitle"><a class="stdlink" title="{{sco.sem.session_id()}}" href="{{
<span class="semtitle"><a class="stdlink" title="{{sco.formsemestre.session_id()}}" href="{{
url_for('notes.formsemestre_status',
scodoc_dept=g.scodoc_dept, formsemestre_id=sco.sem.id)
}}">{{sco.sem.titre}}</a>
<a title="{{sco.sem.etapes_apo_str()}}">
{% if sco.sem.semestre_id != -1 %}, {{sco.sem.formation.get_cursus().SESSION_NAME}}
{{sco.sem.semestre_id}}
scodoc_dept=g.scodoc_dept, formsemestre_id=sco.formsemestre.id)
}}">{{sco.formsemestre.titre}}</a>
<a title="{{sco.formsemestre.etapes_apo_str()}}">
{% if sco.formsemestre.semestre_id != -1 %}, {{sco.formsemestre.formation.get_cursus().SESSION_NAME}}
{{sco.formsemestre.semestre_id}}
{% endif %}</a>
{% if sco.sem.modalite %} en {{sco.sem.modalite}}{% endif %}</span>
{% if sco.formsemestre.modalite %} en {{sco.formsemestre.modalite}}{% endif %}</span>
<span class="dates">
<a title="du {{sco.sem.date_debut.strftime('%d/%m/%Y')}}
au {{sco.sem.date_fin.strftime('%d/%m/%Y')}} ">{{scu.MONTH_NAMES_ABBREV[ sco.sem.date_debut.month - 1]}}
{{sco.sem.date_debut.year}} - {{scu.MONTH_NAMES_ABBREV[sco.sem.date_fin.month - 1]}}
{{sco.sem.date_fin.year}}</a></span>
<a title="du {{sco.formsemestre.date_debut.strftime('%d/%m/%Y')}}
au {{sco.formsemestre.date_fin.strftime('%d/%m/%Y')}} ">{{scu.MONTH_NAMES_ABBREV[ sco.formsemestre.date_debut.month - 1]}}
{{sco.formsemestre.date_debut.year}} - {{scu.MONTH_NAMES_ABBREV[sco.formsemestre.date_fin.month - 1]}}
{{sco.formsemestre.date_fin.year}}</a></span>
<span class="resp"><a
title="{{sco.sem.responsables_str(abbrev_prenom=False)}}">{{sco.sem.responsables_str()}}</a></span>
title="{{sco.formsemestre.responsables_str(abbrev_prenom=False)}}">{{sco.formsemestre.responsables_str()}}</a></span>
<span class="nbinscrits"><a class="discretelink" href="{{url_for('scolar.groups_view', scodoc_dept=g.scodoc_dept,
formsemestre_id=sco.sem.id)}}">{{sco.sem.inscriptions|length}} inscrits</a></span><span class="lock">{% if
not sco.sem.etat %}<a href="{{url_for('notes.formsemestre_flip_lock', scodoc_dept=g.scodoc_dept,
formsemestre_id=sco.sem.id)}}">{{scu.icontag("lock_img", border="0", title="Semestre
formsemestre_id=sco.formsemestre.id)}}">{{sco.formsemestre.inscriptions|length}} inscrits</a></span><span class="lock">{% if
not sco.formsemestre.etat %}<a href="{{url_for('notes.formsemestre_flip_lock', scodoc_dept=g.scodoc_dept,
formsemestre_id=sco.formsemestre.id)}}">{{scu.icontag("lock_img", border="0", title="Semestre
verrouillé")|safe}}</a>{% endif %}</span><span class="eye">
{% if not scu.is_passerelle_disabled() %}
<a href="{{url_for('notes.formsemestre_change_publication_bul', scodoc_dept=g.scodoc_dept,
formsemestre_id=sco.sem.id)}}">
{% if sco.sem.bul_hide_xml %}
formsemestre_id=sco.formsemestre.id)}}">
{% if sco.formsemestre.bul_hide_xml %}
{{ scu.ICON_HIDDEN|safe}}
{% else %}
{{ scu.ICON_PUBLISHED|safe }}
@ -36,6 +36,6 @@
</span>
</div>
{{ sco.sem_menu_bar|safe }}
{{ sco.formsemestre_menu_bar|safe }}
</div>
<!-- end of formsemestre_header -->

View File

@ -1,5 +1,6 @@
{%- extends 'babase.j2' -%}
{# -*- Base des pages ordinaires, dans départements -*- #}
{% extends 'babase.j2' %}
<!-- sco_page -->
{% block styles %}
{{super()}}
@ -27,7 +28,7 @@
<div id="gtrcontent" class="gtrcontent">
{% include "flashed_messages.j2" %}
{% if sco.sem %}
{% if sco.formsemestre %}
{% block formsemestre_header %}
{% include "formsemestre_header.j2" %}
{% endblock %}

View File

@ -58,7 +58,7 @@
{% if sco.etud_cur_sem %}
<span title="absences du {{ sco.etud_cur_sem['date_debut'].strftime('%d/%m/%Y') }}
au {{ sco.etud_cur_sem['date_fin'].strftime('%d/%m/%Y') }}">({{sco.prefs["assi_metrique"]}})
<br />{{'%1g'|format(sco.nbabsjust)}} J., {{'%1g'|format(sco.nbabsnj)}} N.J.</span>
<br />{{'%1g'|format(sco.nb_abs_just)}} J., {{'%1g'|format(sco.nb_abs_nj)}} N.J.</span>
{% endif %}
<ul>
{% if current_user.has_permission(sco.Permission.AbsChange) %}

View File

@ -2,6 +2,7 @@
"""ScoDoc Flask views
"""
import datetime
from functools import cached_property
from flask import Blueprint
from flask import g, current_app, request
@ -57,8 +58,20 @@ class ScoData:
self.Permission = Permission
self.scu = scu
self.SCOVERSION = sco_version.SCOVERSION
# -- Informations étudiant courant, si sélectionné:
if etud is None:
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":
@ -66,50 +79,61 @@ class ScoData:
elif request.method == "POST":
etudid = request.form.get("etudid", None)
if etudid is not None:
etud = Identite.get_etud(etudid)
self.etud = etud
if etud is not None:
# Infos sur l'étudiant courant
ins = self.etud.inscription_courante()
if ins:
self.etud_cur_sem = ins.formsemestre
(
self.nbabsnj,
self.nbabsjust,
self.nbabs,
) = sco_assiduites.get_assiduites_count_in_interval(
etud.id,
self.etud_cur_sem.date_debut.isoformat(),
self.etud_cur_sem.date_fin.isoformat(),
scu.translate_assiduites_metric(
sco_preferences.get_preference("assi_metrique")
),
)
else:
self.etud_cur_sem = None
else:
self.etud = None
# --- Informations sur semestre courant, si sélectionné
if formsemestre is None:
formsemestre_id = retreive_formsemestre_from_request()
if formsemestre_id is not None:
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
if formsemestre is None:
self.sem = None
self.sem_menu_bar = None
else:
self.sem = formsemestre
self.sem_menu_bar = sco_formsemestre_status.formsemestre_status_menubar(
self.sem
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")
),
)
self.formsemestre = formsemestre
# --- Préférences
# prefs fallback to global pref if sem is None:
if formsemestre:
formsemestre_id = formsemestre.id
else:
formsemestre_id = None
self.prefs = sco_preferences.SemPreferences(formsemestre_id)
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
)
from app.views import (

View File

@ -823,7 +823,8 @@ def form_change_coordonnees(etudid):
("telephonemobile", {"size": 13, "title": "Mobile"}),
),
initvalues=adr,
submitlabel="Valider le formulaire",
submitlabel="Enregistrer",
cancelbutton="Annuler",
)
dest_url = url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
if tf[0] == 0:

View File

@ -1,7 +1,7 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
SCOVERSION = "9.6.959"
SCOVERSION = "9.6.960"
SCONAME = "ScoDoc"

View File

@ -45,7 +45,7 @@ from app.models.evaluations import Evaluation
from app.scodoc import sco_dump_db
from app.scodoc.sco_logos import make_logo_local
from app.scodoc.sco_permissions import Permission
from app.views import notes, scolar
from app.views import notes, scolar, ScoData
import app.scodoc.sco_utils as scu
import tools
from tools.fakedatabase import create_test_api_database
@ -58,9 +58,9 @@ cli.register(app)
@app.context_processor
def inject_sco_utils():
"Make scu available in all Jinja templates"
"Make scu and sco available in all Jinja templates"
# if modified, put the same in conftest.py#27
return dict(scu=scu)
return {"scu": scu, "sco": ScoData()}
@app.shell_context_processor

View File

@ -27,7 +27,7 @@ def test_client():
@apptest.context_processor
def inject_sco_utils():
"Make scu available in all Jinja templates"
return dict(scu=scu)
return {"scu": scu, "sco": ScoData()}
with apptest.test_request_context():
# initialize scodoc "g":