forked from ScoDoc/ScoDoc
Base multi-départements. En cours
This commit is contained in:
parent
317d60d447
commit
486f20d7f7
@ -23,9 +23,6 @@ from flask_caching import Cache
|
||||
|
||||
from config import DevConfig
|
||||
|
||||
from app.scodoc import notesdb as ndb
|
||||
from app.scodoc import sco_cache
|
||||
|
||||
db = SQLAlchemy()
|
||||
migrate = Migrate()
|
||||
login = LoginManager()
|
||||
@ -131,6 +128,18 @@ def create_app(config_class=DevConfig):
|
||||
return app
|
||||
|
||||
|
||||
def set_sco_dept(scodoc_dept: str):
|
||||
"""Set global g object to given dept and open db connection if needed"""
|
||||
# Check that dept exists
|
||||
dept = Departement.query.filter_by(acronym=scodoc_dept).first()
|
||||
if not dept:
|
||||
raise ScoValueError(f"Invalid dept: {scodoc_dept}")
|
||||
g.scodoc_dept = scodoc_dept # l'acronyme
|
||||
g.scodoc_dept_id = dept.id # l'id
|
||||
if not hasattr(g, "db_conn"):
|
||||
ndb.open_db_connection()
|
||||
|
||||
|
||||
def user_db_init():
|
||||
"""Initialize the users database."""
|
||||
from app.auth.models import User, Role
|
||||
@ -214,8 +223,14 @@ def clear_scodoc_cache():
|
||||
|
||||
r = redis.Redis()
|
||||
r.flushall()
|
||||
# Also clear local caches:
|
||||
sco_preferences.clear_base_preferences()
|
||||
|
||||
|
||||
from app.models import Departement
|
||||
from app.scodoc import notesdb as ndb, sco_preferences
|
||||
from app.scodoc import sco_cache
|
||||
|
||||
# admin_role = Role.query.filter_by(name="SuperAdmin").first()
|
||||
# if admin_role:
|
||||
# admin = (
|
||||
|
@ -98,10 +98,37 @@ class ZResponse(object):
|
||||
self.headers[header.lower()] = value
|
||||
|
||||
|
||||
def scodoc(func):
|
||||
"""Décorateur pour toutes les fonctions ScoDoc
|
||||
Affecte le département à g
|
||||
et ouvre la connexion à la base
|
||||
|
||||
Set `g.scodoc_dept` and `g.scodoc_dept_id` if `scodoc_dept` is present
|
||||
in the argument (for routes like
|
||||
`/<scodoc_dept>/Scolarite/sco_exemple`).
|
||||
"""
|
||||
|
||||
@wraps(func)
|
||||
def scodoc_function(*args, **kwargs):
|
||||
if "scodoc_dept" in kwargs:
|
||||
dept_acronym = kwargs["scodoc_dept"]
|
||||
current_app.logger.info("setting dept to " + dept_acronym)
|
||||
app.set_sco_dept(dept_acronym)
|
||||
del kwargs["scodoc_dept"]
|
||||
elif not hasattr(g, "scodoc_dept"):
|
||||
current_app.logger.info("setting dept to None")
|
||||
g.scodoc_dept = None
|
||||
g.scodoc_dept_id = -1 # invalide
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return scodoc_function
|
||||
|
||||
|
||||
def permission_required(permission):
|
||||
def decorator(f):
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
# current_app.logger.info("PERMISSION; kwargs=%s" % str(kwargs))
|
||||
if "scodoc_dept" in kwargs:
|
||||
g.scodoc_dept = kwargs["scodoc_dept"]
|
||||
del kwargs["scodoc_dept"]
|
||||
@ -142,7 +169,6 @@ def scodoc7func(context):
|
||||
2. or be called directly from Python.
|
||||
|
||||
If called via a route, this decorator setups a REQUEST object (emulating Zope2 REQUEST)
|
||||
and `g.scodoc_dept` if present in the argument (for routes like `/<scodoc_dept>/Scolarite/sco_exemple`).
|
||||
"""
|
||||
# Détermine si on est appelé via une route ("toplevel")
|
||||
# ou par un appel de fonction python normal.
|
||||
@ -150,14 +176,6 @@ def scodoc7func(context):
|
||||
if not top_level:
|
||||
# ne "redécore" pas
|
||||
return func(*args, **kwargs)
|
||||
#
|
||||
if "scodoc_dept" in kwargs:
|
||||
g.scodoc_dept = kwargs["scodoc_dept"]
|
||||
del kwargs["scodoc_dept"]
|
||||
elif not hasattr(g, "scodoc_dept"):
|
||||
g.scodoc_dept = None
|
||||
# --- Open DB connection
|
||||
app.views.open_dept_db_connection()
|
||||
# --- Emulate Zope's REQUEST
|
||||
REQUEST = ZRequest()
|
||||
g.zrequest = REQUEST
|
||||
|
@ -11,6 +11,9 @@ APO_CODE_STR_LEN = 16 # nb de car max d'un code Apogée
|
||||
from app.models.raw_sql_init import create_database_functions
|
||||
|
||||
from app.models.absences import Absence, AbsenceNotification, BilletAbsence
|
||||
|
||||
from app.models.departements import Departement
|
||||
|
||||
from app.models.entreprises import (
|
||||
Entreprise,
|
||||
EntrepriseCorrespondant,
|
||||
@ -56,4 +59,4 @@ from app.models.notes import (
|
||||
NotesNotes,
|
||||
NotesNotesLog,
|
||||
)
|
||||
from app.models.preferences import ScoPreferences
|
||||
from app.models.preferences import ScoPreference
|
||||
|
36
app/models/departements.py
Normal file
36
app/models/departements.py
Normal file
@ -0,0 +1,36 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""ScoDoc8 models : departements
|
||||
"""
|
||||
from typing import Any
|
||||
|
||||
from app import db
|
||||
from app.models import SHORT_STR_LEN
|
||||
|
||||
|
||||
class Departement(db.Model):
|
||||
"""Un département ScoDoc"""
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
acronym = db.Column(db.String(SHORT_STR_LEN), nullable=False, index=True)
|
||||
description = db.Column(db.Text())
|
||||
date_creation = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
visible = db.Column(
|
||||
db.Boolean(), nullable=False, default=True, server_default="true"
|
||||
) # sur page d'accueil
|
||||
|
||||
entreprises = db.relationship("Entreprise", lazy="dynamic", backref="departement")
|
||||
etudiants = db.relationship("Identite", lazy="dynamic", backref="departement")
|
||||
formations = db.relationship(
|
||||
"NotesFormation", lazy="dynamic", backref="departement"
|
||||
)
|
||||
formsemestres = db.relationship(
|
||||
"FormSemestre", lazy="dynamic", backref="departement"
|
||||
)
|
||||
preferences = db.relationship(
|
||||
"ScoPreference", lazy="dynamic", backref="departement"
|
||||
)
|
||||
semsets = db.relationship("NotesSemSet", lazy="dynamic", backref="departement")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Departement {self.acronym}>"
|
@ -15,7 +15,7 @@ class Entreprise(db.Model):
|
||||
__tablename__ = "entreprises"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
entreprise_id = db.synonym("id")
|
||||
|
||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
||||
nom = db.Column(db.Text)
|
||||
adresse = db.Column(db.Text)
|
||||
ville = db.Column(db.Text)
|
||||
|
@ -17,6 +17,7 @@ class Identite(db.Model):
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
etudid = db.synonym("id")
|
||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
||||
|
||||
nom = db.Column(db.Text())
|
||||
prenom = db.Column(db.Text())
|
||||
|
@ -15,6 +15,8 @@ class NotesFormation(db.Model):
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
formation_id = db.synonym("id")
|
||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
||||
|
||||
acronyme = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
||||
titre = db.Column(db.Text(), nullable=False)
|
||||
titre_officiel = db.Column(db.Text(), nullable=False)
|
||||
@ -28,6 +30,8 @@ class NotesFormation(db.Model):
|
||||
type_parcours = db.Column(db.Integer, default=0, server_default="0")
|
||||
code_specialite = db.Column(db.String(SHORT_STR_LEN))
|
||||
|
||||
formsemestres = db.relationship("FormSemestre", lazy="dynamic", backref="formation")
|
||||
|
||||
|
||||
class NotesUE(db.Model):
|
||||
"""Unité d'Enseignement"""
|
||||
@ -106,6 +110,8 @@ class NotesTag(db.Model):
|
||||
__tablename__ = "notes_tags"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
||||
|
||||
tag_id = db.synonym("id")
|
||||
title = db.Column(db.String(SHORT_STR_LEN), nullable=False, unique=True)
|
||||
|
||||
|
@ -19,6 +19,9 @@ class FormSemestre(db.Model):
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
formsemestre_id = db.synonym("id")
|
||||
# dept_id est aussi dans la formation, ajpouté ici pour
|
||||
# simplifier et accélérer les selects dans notesdb
|
||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
||||
formation_id = db.Column(db.Integer, db.ForeignKey("notes_formations.id"))
|
||||
semestre_id = db.Column(db.Integer, nullable=False, default=1, server_default="1")
|
||||
titre = db.Column(db.Text())
|
||||
@ -309,6 +312,8 @@ class NotesSemSet(db.Model):
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
semset_id = db.synonym("id")
|
||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"))
|
||||
|
||||
title = db.Column(db.Text)
|
||||
annee_scolaire = db.Column(db.Integer, nullable=True, default=None)
|
||||
# periode: 0 (année), 1 (Simpair), 2 (Spair)
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
"""Model : preferences
|
||||
"""
|
||||
|
||||
from app import db
|
||||
|
||||
|
||||
class ScoPreferences(db.Model):
|
||||
class ScoPreference(db.Model):
|
||||
"""ScoDoc preferences"""
|
||||
|
||||
__tablename__ = "sco_prefs"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
pref_id = db.synonym("id")
|
||||
dept = db.Column(db.String(16), index=True)
|
||||
name = db.Column(db.String(128), nullable=False)
|
||||
|
||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"))
|
||||
|
||||
name = db.Column(db.String(128), nullable=False, index=True)
|
||||
value = db.Column(db.Text())
|
||||
formsemestre_id = db.Column(db.Integer, db.ForeignKey("notes_formsemestre.id"))
|
||||
|
@ -7,8 +7,9 @@ import psycopg2
|
||||
import psycopg2.pool
|
||||
import psycopg2.extras
|
||||
|
||||
from flask import g
|
||||
from flask import g, current_app
|
||||
|
||||
import app
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc.notes_log import log
|
||||
from app.scodoc.sco_exceptions import ScoException, ScoValueError, NoteProcessError
|
||||
@ -33,28 +34,17 @@ def unquote(s):
|
||||
return s.replace("&", "&")
|
||||
|
||||
|
||||
def open_dept_connection(scodoc_dept=None):
|
||||
"""Open a connection to the current dept db (g.scodoc_dept)
|
||||
or to the argument scodoc_dept
|
||||
"""
|
||||
return psycopg2.connect(scu.get_db_cnx_string(scodoc_dept))
|
||||
def open_db_connection():
|
||||
"""Open a connection to the database"""
|
||||
g.db_conn = psycopg2.connect(current_app.config["SQLALCHEMY_DATABASE_URI"])
|
||||
|
||||
|
||||
def close_dept_connection():
|
||||
"""Commit and close dept db."""
|
||||
# log("close_dept_connection to " + scu.get_db_cnx_string())
|
||||
g.db_conn.commit()
|
||||
g.db_conn.close()
|
||||
|
||||
|
||||
def set_sco_dept(scodoc_dept):
|
||||
"""Set "context" to given dept
|
||||
open db connection
|
||||
"""
|
||||
g.scodoc_dept = scodoc_dept
|
||||
def close_db_connection():
|
||||
"""Commit and close database."""
|
||||
if hasattr(g, "db_conn"):
|
||||
close_dept_connection()
|
||||
g.db_conn = open_dept_connection()
|
||||
g.db_conn.commit()
|
||||
g.db_conn.close()
|
||||
del g.db_conn
|
||||
|
||||
|
||||
def GetDBConnexion(autocommit=True): # on n'utilise plus autocommit
|
||||
@ -277,6 +267,7 @@ class EditableTable(object):
|
||||
html_quote=True,
|
||||
fields_creators={}, # { field : [ sql_command_to_create_it ] }
|
||||
filter_nulls=True, # dont allow to set fields to null
|
||||
filter_dept=False, # ajoute selection sur g.scodoc_dept_id
|
||||
):
|
||||
self.table_name = table_name
|
||||
self.id_name = id_name
|
||||
@ -295,6 +286,7 @@ class EditableTable(object):
|
||||
self.html_quote = html_quote
|
||||
self.fields_creators = fields_creators
|
||||
self.filter_nulls = filter_nulls
|
||||
self.filter_dept = filter_dept
|
||||
self.sql_default_values = None
|
||||
|
||||
def create(self, cnx, args):
|
||||
@ -304,6 +296,8 @@ class EditableTable(object):
|
||||
del vals[self.id_name]
|
||||
if "id" in vals:
|
||||
del vals["id"]
|
||||
if self.filter_dept:
|
||||
vals["dept_id"] = g.scodoc_dept_id
|
||||
if self.html_quote:
|
||||
quote_dict(vals) # quote all HTML markup
|
||||
# format value
|
||||
@ -334,6 +328,8 @@ class EditableTable(object):
|
||||
vals = dictfilter(args, self.dbfields, self.filter_nulls)
|
||||
if (id_value is not None) and (not "id" in vals):
|
||||
vals["id"] = id_value
|
||||
if self.filter_dept:
|
||||
vals["dept_id"] = g.scodoc_dept_id
|
||||
if not sortkey:
|
||||
sortkey = self.sortkey
|
||||
res = DBSelectArgs(
|
||||
|
@ -118,7 +118,10 @@ def abs_notify_send(
|
||||
msg["To"] = email
|
||||
sco_emails.sendEmail(context, msg)
|
||||
ndb.SimpleQuery(
|
||||
"""insert into absences_notifications (etudid, email, nbabs, nbabsjust, formsemestre_id) values (%(etudid)s, %(email)s, %(nbabs)s, %(nbabsjust)s, %(formsemestre_id)s)""",
|
||||
"""insert into absences_notifications
|
||||
(etudid, email, nbabs, nbabsjust, formsemestre_id)
|
||||
VALUES (%(etudid)s, %(email)s, %(nbabs)s, %(nbabsjust)s, %(formsemestre_id)s)
|
||||
""",
|
||||
vars(),
|
||||
cursor=cursor,
|
||||
)
|
||||
|
@ -138,9 +138,18 @@ class EvaluationCache(ScoDocCache):
|
||||
|
||||
@classmethod
|
||||
def invalidate_all_sems(cls):
|
||||
"delete all evaluations from cache"
|
||||
"delete all evaluations in current dept from cache"
|
||||
evaluation_ids = [
|
||||
x[0] for x in ndb.SimpleQuery("SELECT id FROM notes_evaluation", "")
|
||||
x[0]
|
||||
for x in ndb.SimpleQuery(
|
||||
"""SELECT e.id
|
||||
FROM notes_evaluation e, notes_moduleimpl mi, notes_formsemestre s
|
||||
WHERE s.dept_id=%(dept_id)s
|
||||
AND s.id = mi.formsemestre_id
|
||||
AND mi.id = e.moduleimpl_id;
|
||||
""",
|
||||
{"dept_id": g.scodoc_dept_id},
|
||||
)
|
||||
]
|
||||
cls.delete_many(evaluation_ids)
|
||||
|
||||
@ -243,7 +252,13 @@ def invalidate_formsemestre( # was inval_cache( context, formsemestre_id=None,
|
||||
# clear all caches
|
||||
log("----- invalidate_formsemestre: clearing all caches -----")
|
||||
formsemestre_ids = [
|
||||
x[0] for x in ndb.SimpleQuery("SELECT id FROM notes_formsemestre", "")
|
||||
x[0]
|
||||
for x in ndb.SimpleQuery(
|
||||
"""SELECT id FROM notes_formsemestre s
|
||||
WHERE s.dept_id=%(dept_id)s
|
||||
""",
|
||||
{"dept_id": g.scodoc_dept_id},
|
||||
)
|
||||
]
|
||||
else:
|
||||
formsemestre_ids = [
|
||||
|
@ -65,7 +65,7 @@ SCO_DUMP_LOCK = "/tmp/scodump.lock"
|
||||
|
||||
|
||||
def sco_dump_and_send_db(context, REQUEST=None):
|
||||
"""Dump base de données du département courant et l'envoie anonymisée pour debug"""
|
||||
"""Dump base de données et l'envoie anonymisée pour debug"""
|
||||
H = [html_sco_header.sco_header(page_title="Assistance technique")]
|
||||
# get currect (dept) DB name:
|
||||
cursor = ndb.SimpleQuery("SELECT current_database()", {})
|
||||
@ -75,7 +75,7 @@ def sco_dump_and_send_db(context, REQUEST=None):
|
||||
try:
|
||||
x = open(SCO_DUMP_LOCK, "w+")
|
||||
fcntl.flock(x, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except (IOError, OSError): # exception changed from Python 2 to 3
|
||||
except (IOError, OSError):
|
||||
raise ScoValueError(
|
||||
"Un envoi de la base "
|
||||
+ db_name
|
||||
|
@ -148,6 +148,7 @@ _entreprisesEditor = EntreprisesEditor(
|
||||
"note",
|
||||
"date_creation",
|
||||
),
|
||||
filter_dept=True,
|
||||
sortkey="nom",
|
||||
input_formators={
|
||||
"nom": _format_nom,
|
||||
|
@ -258,6 +258,7 @@ _identiteEditor = ndb.EditableTable(
|
||||
"code_ine",
|
||||
"code_nip",
|
||||
),
|
||||
filter_dept=True,
|
||||
sortkey="nom",
|
||||
input_formators={
|
||||
"nom": force_uppercase,
|
||||
|
@ -32,6 +32,7 @@ from flask import url_for, g
|
||||
from flask_login import current_user
|
||||
|
||||
from scodoc_manager import sco_mgr
|
||||
import app
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
from app.scodoc.gen_tables import GenTable
|
||||
@ -48,7 +49,7 @@ def form_search_etud(
|
||||
dest_url=None,
|
||||
parameters=None,
|
||||
parameters_keys=None,
|
||||
title="Rechercher un étudiant par nom : ",
|
||||
title="Rechercher un étudiant par nom : ",
|
||||
add_headers=False, # complete page
|
||||
):
|
||||
"form recherche par nom"
|
||||
@ -274,7 +275,7 @@ def search_etud_in_accessible_depts(expnom=None, code_nip=None):
|
||||
if current_user.has_permission(Permission.ScoView, dept=dept):
|
||||
if expnom or code_nip:
|
||||
accessible_depts.append(dept)
|
||||
ndb.set_sco_dept(dept)
|
||||
app.set_sco_dept(dept)
|
||||
etuds = search_etuds_infos(expnom=expnom, code_nip=code_nip)
|
||||
else:
|
||||
etuds = []
|
||||
|
@ -64,6 +64,7 @@ _formationEditor = ndb.EditableTable(
|
||||
"type_parcours",
|
||||
"code_specialite",
|
||||
),
|
||||
filter_dept=True,
|
||||
sortkey="acronyme",
|
||||
)
|
||||
|
||||
|
@ -65,6 +65,7 @@ _formsemestreEditor = ndb.EditableTable(
|
||||
"elt_sem_apo",
|
||||
"elt_annee_apo",
|
||||
),
|
||||
filter_dept=True,
|
||||
sortkey="date_debut",
|
||||
output_formators={
|
||||
"date_debut": ndb.DateISOtoDMY,
|
||||
|
@ -113,6 +113,7 @@ get_base_preferences(formsemestre_id)
|
||||
import flask
|
||||
from flask import g
|
||||
|
||||
from app.models import Departement
|
||||
from app.scodoc import sco_cache
|
||||
from app.scodoc.notes_log import log
|
||||
from app.scodoc.sco_exceptions import ScoValueError, ScoException
|
||||
@ -120,15 +121,22 @@ from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||
import app.scodoc.notesdb as ndb
|
||||
import app.scodoc.sco_utils as scu
|
||||
|
||||
_SCO_BASE_PREFERENCES = {} # { URL: BasePreferences instance }
|
||||
_SCO_BASE_PREFERENCES = {} # { dept_acronym: BasePreferences instance }
|
||||
|
||||
|
||||
def clear_base_preferences():
|
||||
"""Clear cached preferences"""
|
||||
# usefull only for tests, where the same process may run
|
||||
# successively on several databases
|
||||
_SCO_BASE_PREFERENCES.clear()
|
||||
|
||||
|
||||
def get_base_preferences():
|
||||
"""Return global preferences for the current department"""
|
||||
dept = g.scodoc_dept
|
||||
if not dept in _SCO_BASE_PREFERENCES:
|
||||
_SCO_BASE_PREFERENCES[dept] = BasePreferences()
|
||||
return _SCO_BASE_PREFERENCES[dept]
|
||||
dept_acronym = g.scodoc_dept
|
||||
if not dept_acronym in _SCO_BASE_PREFERENCES:
|
||||
_SCO_BASE_PREFERENCES[dept_acronym] = BasePreferences(dept_acronym)
|
||||
return _SCO_BASE_PREFERENCES[dept_acronym]
|
||||
|
||||
|
||||
def get_preference(name, formsemestre_id=None):
|
||||
@ -198,7 +206,8 @@ class BasePreferences(object):
|
||||
_editor = ndb.EditableTable(
|
||||
"sco_prefs",
|
||||
"pref_id",
|
||||
("pref_id", "name", "value", "formsemestre_id"),
|
||||
("pref_id", "dept_id", "name", "value", "formsemestre_id"),
|
||||
filter_dept=True,
|
||||
sortkey="name",
|
||||
convert_null_outputs_to_empty=False,
|
||||
# allow_set_id=True, #sco8
|
||||
@ -206,7 +215,11 @@ class BasePreferences(object):
|
||||
filter_nulls=False,
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, dept_acronym: str):
|
||||
dept = Departement.query.filter_by(acronym=dept_acronym).first()
|
||||
if not dept:
|
||||
raise ScoValueError(f"Invalid departement: {dept_acronym}")
|
||||
self.dept_id = dept.id
|
||||
self.init()
|
||||
self.load()
|
||||
|
||||
@ -1785,11 +1798,11 @@ class BasePreferences(object):
|
||||
|
||||
def load(self):
|
||||
"""Load all preferences from db"""
|
||||
log("loading preferences")
|
||||
log(f"loading preferences for dept_id={self.dept_id}")
|
||||
try:
|
||||
scu.GSL.acquire()
|
||||
cnx = ndb.GetDBConnexion()
|
||||
preflist = self._editor.list(cnx)
|
||||
preflist = self._editor.list(cnx, {"dept_id": self.dept_id})
|
||||
self.prefs = {None: {}} # { formsemestre_id (or None) : { name : value } }
|
||||
self.default = {} # { name : default_value }
|
||||
for p in preflist:
|
||||
@ -1850,7 +1863,9 @@ class BasePreferences(object):
|
||||
self.prefs[None][name] = value
|
||||
log("creating missing preference for %s=%s" % (name, value))
|
||||
# add to db table
|
||||
self._editor.create(cnx, {"name": name, "value": value})
|
||||
self._editor.create(
|
||||
cnx, {"dept_id": self.dept_id, "name": name, "value": value}
|
||||
)
|
||||
finally:
|
||||
scu.GSL.release()
|
||||
|
||||
@ -1898,14 +1913,20 @@ class BasePreferences(object):
|
||||
value = "1" if value else "0"
|
||||
# existe deja ?
|
||||
pdb = self._editor.list(
|
||||
cnx, args={"formsemestre_id": formsemestre_id, "name": name}
|
||||
cnx,
|
||||
args={
|
||||
"dept_id": self.dept_id,
|
||||
"formsemestre_id": formsemestre_id,
|
||||
"name": name,
|
||||
},
|
||||
)
|
||||
if not pdb:
|
||||
# cree preference
|
||||
# crée préférence
|
||||
log("create pref sem=%s %s=%s" % (formsemestre_id, name, value))
|
||||
self._editor.create(
|
||||
cnx,
|
||||
{
|
||||
"dept_id": self.dept_id,
|
||||
"name": name,
|
||||
"value": value,
|
||||
"formsemestre_id": formsemestre_id,
|
||||
@ -1959,6 +1980,7 @@ class BasePreferences(object):
|
||||
)
|
||||
if pdb:
|
||||
log("deleting pref sem=%s %s" % (formsemestre_id, name))
|
||||
assert pdb[0]["dept_id"] == self.dept_id
|
||||
self._editor.delete(cnx, pdb[0]["pref_id"])
|
||||
sco_cache.invalidate_formsemestre() # > modif preferences
|
||||
finally:
|
||||
|
@ -40,6 +40,7 @@ sem_set_list(context)
|
||||
"""
|
||||
|
||||
import flask
|
||||
from flask import g
|
||||
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_cache
|
||||
@ -58,7 +59,10 @@ import app.scodoc.sco_utils as scu
|
||||
|
||||
|
||||
_semset_editor = ndb.EditableTable(
|
||||
"notes_semset", "semset_id", ("semset_id", "title", "annee_scolaire", "sem_id")
|
||||
"notes_semset",
|
||||
"semset_id",
|
||||
("semset_id", "title", "annee_scolaire", "sem_id"),
|
||||
filter_dept=True,
|
||||
)
|
||||
|
||||
semset_create = _semset_editor.create
|
||||
@ -156,14 +160,24 @@ class SemSet(dict):
|
||||
)
|
||||
|
||||
ndb.SimpleQuery(
|
||||
"INSERT INTO notes_semset_formsemestre (formsemestre_id, semset_id) VALUES (%(formsemestre_id)s, %(semset_id)s)",
|
||||
{"formsemestre_id": formsemestre_id, "semset_id": self.semset_id},
|
||||
"""INSERT INTO notes_semset_formsemestre
|
||||
(dept_id, id, semset_id)
|
||||
VALUES (%(dept_id)s, %(formsemestre_id)s, %(semset_id)s)
|
||||
""",
|
||||
{
|
||||
"dept_id": g.scodoc_dept_id,
|
||||
"formsemestre_id": formsemestre_id,
|
||||
"semset_id": self.semset_id,
|
||||
},
|
||||
)
|
||||
self.load_sems() # update our list
|
||||
|
||||
def remove(self, formsemestre_id):
|
||||
ndb.SimpleQuery(
|
||||
"DELETE FROM notes_semset_formsemestre WHERE semset_id=%(semset_id)s AND formsemestre_id=%(formsemestre_id)s",
|
||||
"""DELETE FROM notes_semset_formsemestre
|
||||
WHERE id=%(semset_id)s
|
||||
AND formsemestre_id=%(formsemestre_id)s
|
||||
""",
|
||||
{"formsemestre_id": formsemestre_id, "semset_id": self.semset_id},
|
||||
)
|
||||
self.load_sems() # update our list
|
||||
|
@ -75,8 +75,8 @@ class ScoTag(object):
|
||||
r = ndb.SimpleDictFetch(
|
||||
"SELECT id as tag_id, * FROM "
|
||||
+ self.tag_table
|
||||
+ " WHERE title = %(title)s",
|
||||
{"title": self.title},
|
||||
+ " WHERE dept_id=%(dept_id) AND title = %(title)s",
|
||||
{"dept_id": g.scodoc_dept_id, "title": self.title},
|
||||
)
|
||||
if r:
|
||||
self.tag_id = r[0]["tag_id"]
|
||||
@ -182,8 +182,8 @@ class ModuleTag(ScoTag):
|
||||
r = ndb.SimpleDictFetch(
|
||||
"""SELECT mt.module_id
|
||||
FROM notes_modules_tags mt, notes_modules m, notes_formations f
|
||||
WHERE mt.tag_id = %(tag_id)s
|
||||
AND m.id = mt.module_id
|
||||
WHERE mt.tag_id = %(tag_id)s
|
||||
AND m.id = mt.module_id
|
||||
AND m.formation_id = f.id
|
||||
AND f.formation_code = %(formation_code)s
|
||||
""",
|
||||
|
@ -52,7 +52,7 @@ STRING_TYPES = six.string_types
|
||||
|
||||
from PIL import Image as PILImage
|
||||
|
||||
from flask import g, url_for, request, current_app
|
||||
from flask import g, url_for, request
|
||||
|
||||
from scodoc_manager import sco_mgr
|
||||
|
||||
@ -319,19 +319,10 @@ BULLETINS_VERSIONS = ("short", "selectedevals", "long")
|
||||
|
||||
# Support for ScoDoc7 compatibility
|
||||
def get_dept_id():
|
||||
"acronyme du dept courant"
|
||||
return g.scodoc_dept # en scodoc 8.1 #sco8
|
||||
|
||||
|
||||
# if g.scodoc_dept in sco_mgr.get_dept_ids():
|
||||
# return g.scodoc_dept
|
||||
# raise sco_exceptions.ScoInvalidDept("département invalide: %s" % g.scodoc_dept)
|
||||
|
||||
|
||||
def get_db_cnx_string(scodoc_dept=None):
|
||||
return current_app.config["SQLALCHEMY_DATABASE_URI"]
|
||||
# return "dbname=SCO" + (scodoc_dept or g.scodoc_dept)
|
||||
|
||||
|
||||
def ScoURL():
|
||||
"""base URL for this sco instance.
|
||||
e.g. https://scodoc.xxx.fr/ScoDoc/DEPT/Scolarite
|
||||
|
@ -2,7 +2,7 @@
|
||||
"""ScoDoc Flask views
|
||||
"""
|
||||
from flask import Blueprint
|
||||
from flask import g
|
||||
from flask import g, current_app
|
||||
from app.scodoc import notesdb as ndb
|
||||
|
||||
scodoc_bp = Blueprint("scodoc", __name__)
|
||||
@ -12,19 +12,18 @@ users_bp = Blueprint("users", __name__)
|
||||
absences_bp = Blueprint("absences", __name__)
|
||||
essais_bp = Blueprint("essais", __name__)
|
||||
|
||||
from app.views import scodoc, notes, scolar, absences, users, essais
|
||||
|
||||
# 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 open_dept_db_connection():
|
||||
# current_app.logger.info("open_dept_db_connection")
|
||||
if hasattr(g, "scodoc_dept") and not hasattr(g, "db_conn") and g.scodoc_dept:
|
||||
g.db_conn = ndb.open_dept_connection()
|
||||
def start_scodoc_request():
|
||||
"""Affecte toutes les requêtes, de tous les blueprints"""
|
||||
ndb.open_db_connection()
|
||||
|
||||
|
||||
@scodoc_bp.teardown_app_request
|
||||
def close_dept_db_connection(arg):
|
||||
# current_app.logger.info("close_dept_db_connection")
|
||||
if hasattr(g, "db_conn"):
|
||||
ndb.close_dept_connection()
|
||||
|
||||
|
||||
from app.views import scodoc, notes, scolar, absences, users, essais
|
||||
# current_app.logger.info("close_db_connection")
|
||||
ndb.close_db_connection()
|
||||
|
@ -63,6 +63,7 @@ from flask import url_for
|
||||
from flask import current_app
|
||||
|
||||
from app.decorators import (
|
||||
scodoc,
|
||||
scodoc7func,
|
||||
ScoDoc7Context,
|
||||
permission_required,
|
||||
@ -109,7 +110,7 @@ def sco_publish(route, function, permission, methods=["GET"]):
|
||||
protected by permission and called following ScoDoc 7 Zope standards.
|
||||
"""
|
||||
return bp.route(route, methods=methods)(
|
||||
permission_required(permission)(scodoc7func(context)(function))
|
||||
permission_required(permission)(scodoc7func(context)(scodoc(function)))
|
||||
)
|
||||
|
||||
|
||||
@ -127,6 +128,7 @@ def _toboolean(x):
|
||||
|
||||
@bp.route("/")
|
||||
@bp.route("/index_html")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def index_html(context, REQUEST=None):
|
||||
@ -267,6 +269,7 @@ sco_publish("/CountAbsJust", sco_abs.count_abs_just, Permission.ScoView)
|
||||
|
||||
|
||||
@bp.route("/doSignaleAbsenceGrSemestre", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoAbsChange)
|
||||
@scodoc7func(context)
|
||||
def doSignaleAbsenceGrSemestre(
|
||||
@ -310,6 +313,7 @@ def doSignaleAbsenceGrSemestre(
|
||||
|
||||
# ------------ HTML Interfaces
|
||||
@bp.route("/SignaleAbsenceGrHebdo", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoAbsChange)
|
||||
@scodoc7func(context)
|
||||
def SignaleAbsenceGrHebdo(
|
||||
@ -473,6 +477,7 @@ def SignaleAbsenceGrHebdo(
|
||||
|
||||
|
||||
@bp.route("/SignaleAbsenceGrSemestre", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoAbsChange)
|
||||
@scodoc7func(context)
|
||||
def SignaleAbsenceGrSemestre(
|
||||
@ -846,6 +851,7 @@ def _gen_form_saisie_groupe(
|
||||
|
||||
|
||||
@bp.route("/EtatAbsencesGr")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context) # ported from dtml
|
||||
def EtatAbsencesGr(
|
||||
@ -984,6 +990,7 @@ ou entrez une date pour visualiser les absents un jour donné :
|
||||
|
||||
|
||||
@bp.route("/EtatAbsencesDate")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def EtatAbsencesDate(
|
||||
@ -1068,6 +1075,7 @@ def EtatAbsencesDate(
|
||||
|
||||
# ----- Gestion des "billets d'absence": signalement par les etudiants eux mêmes (à travers le portail)
|
||||
@bp.route("/AddBilletAbsence")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoAbsAddBillet)
|
||||
@scodoc7func(context)
|
||||
def AddBilletAbsence(
|
||||
@ -1127,6 +1135,7 @@ def AddBilletAbsence(
|
||||
|
||||
|
||||
@bp.route("/AddBilletAbsenceForm")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoAbsAddBillet)
|
||||
@scodoc7func(context)
|
||||
def AddBilletAbsenceForm(context, etudid, REQUEST=None):
|
||||
@ -1239,6 +1248,7 @@ def _tableBillets(context, billets, etud=None, title=""):
|
||||
|
||||
|
||||
@bp.route("/listeBilletsEtud")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def listeBilletsEtud(context, etudid=False, REQUEST=None, format="html"):
|
||||
@ -1255,6 +1265,7 @@ def listeBilletsEtud(context, etudid=False, REQUEST=None, format="html"):
|
||||
|
||||
|
||||
@bp.route("/XMLgetBilletsEtud")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def XMLgetBilletsEtud(context, etudid=False, REQUEST=None):
|
||||
@ -1268,6 +1279,7 @@ def XMLgetBilletsEtud(context, etudid=False, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/listeBillets")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def listeBillets(context, REQUEST=None):
|
||||
@ -1296,6 +1308,7 @@ def listeBillets(context, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/deleteBilletAbsence")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoAbsChange)
|
||||
@scodoc7func(context)
|
||||
def deleteBilletAbsence(context, billet_id, REQUEST=None, dialog_confirmed=False):
|
||||
@ -1390,6 +1403,7 @@ def _ProcessBilletAbsence(context, billet, estjust, description, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/ProcessBilletAbsenceForm")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoAbsChange)
|
||||
@scodoc7func(context)
|
||||
def ProcessBilletAbsenceForm(context, billet_id, REQUEST=None):
|
||||
@ -1480,6 +1494,7 @@ def ProcessBilletAbsenceForm(context, billet_id, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/XMLgetAbsEtud")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def XMLgetAbsEtud(context, beg_date="", end_date="", REQUEST=None):
|
||||
|
@ -14,6 +14,7 @@ from flask import request
|
||||
from flask import url_for
|
||||
|
||||
from app.decorators import (
|
||||
scodoc,
|
||||
scodoc7func,
|
||||
ScoDoc7Context,
|
||||
permission_required,
|
||||
@ -31,6 +32,7 @@ context = ScoDoc7Context(globals())
|
||||
|
||||
|
||||
@bp.route("/<scodoc_dept>/Scolarite/sco_exemple")
|
||||
@scodoc
|
||||
@scodoc7func(context)
|
||||
def sco_exemple(etudid="NON"):
|
||||
"""Un exemple de fonction ScoDoc 7"""
|
||||
@ -56,6 +58,7 @@ def sco_exemple(etudid="NON"):
|
||||
|
||||
|
||||
@bp.route("/<scodoc_dept>/Scolarite/sco_exemple3")
|
||||
@scodoc
|
||||
@login_required
|
||||
@scodoc7func(context)
|
||||
def sco_exemple3(toto):
|
||||
@ -63,6 +66,7 @@ def sco_exemple3(toto):
|
||||
|
||||
|
||||
@bp.route("/<scodoc_dept>/Scolarite/sco_exemple4")
|
||||
@scodoc
|
||||
@login_required
|
||||
@scodoc7func(context)
|
||||
def sco_exemple4(toto):
|
||||
@ -71,6 +75,7 @@ def sco_exemple4(toto):
|
||||
|
||||
# Test avec un seul argument REQUEST positionnel
|
||||
@bp.route("/<scodoc_dept>/Scolarite/sco_get_version")
|
||||
@scodoc
|
||||
@scodoc7func(context)
|
||||
def sco_get_version(REQUEST):
|
||||
return "ok"
|
||||
@ -78,8 +83,9 @@ def sco_get_version(REQUEST):
|
||||
|
||||
# Fonction ressemblant à une méthode Zope protégée
|
||||
@bp.route("/<scodoc_dept>/Scolarite/sco_test_view")
|
||||
@scodoc7func(context)
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def sco_test_view(REQUEST=None):
|
||||
return """Vous avez vu sco_test_view !"""
|
||||
|
||||
|
@ -48,6 +48,7 @@ import scodoc_manager
|
||||
from app.auth.models import User
|
||||
|
||||
from app.decorators import (
|
||||
scodoc,
|
||||
scodoc7func,
|
||||
ScoDoc7Context,
|
||||
permission_required,
|
||||
@ -150,6 +151,7 @@ def sco_publish(route, function, permission, methods=["GET"]):
|
||||
|
||||
# --------------------- Quelques essais élémentaires:
|
||||
@bp.route("/essai")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def essai(context, REQUEST=None):
|
||||
@ -380,6 +382,7 @@ sco_publish(
|
||||
#
|
||||
@bp.route("/")
|
||||
@bp.route("/index_html")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def index_html(context, REQUEST=None):
|
||||
@ -432,6 +435,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/formation_list")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formation_list(context, format=None, REQUEST=None, formation_id=None, args={}):
|
||||
@ -443,6 +447,7 @@ def formation_list(context, format=None, REQUEST=None, formation_id=None, args={
|
||||
|
||||
|
||||
@bp.route("/formation_export")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formation_export(
|
||||
@ -455,6 +460,7 @@ def formation_export(
|
||||
|
||||
|
||||
@bp.route("/formation_import_xml")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoChangeFormation)
|
||||
@scodoc7func(context)
|
||||
def formation_import_xml(context, file):
|
||||
@ -465,6 +471,7 @@ def formation_import_xml(context, file):
|
||||
|
||||
|
||||
@bp.route("/formation_import_xml_form", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoChangeFormation)
|
||||
@scodoc7func(context)
|
||||
def formation_import_xml_form(context, REQUEST):
|
||||
@ -546,6 +553,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/formation_count_sems")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formation_count_sems(context, formation_id):
|
||||
@ -578,6 +586,7 @@ sco_publish("/ue_move", sco_edit_formation.ue_move, Permission.ScoChangeFormatio
|
||||
|
||||
|
||||
@bp.route("/formsemestre_list")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_list(
|
||||
@ -604,6 +613,7 @@ def formsemestre_list(
|
||||
|
||||
|
||||
@bp.route("/XMLgetFormsemestres")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def XMLgetFormsemestres(context, etape_apo=None, formsemestre_id=None, REQUEST=None):
|
||||
@ -656,6 +666,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/formsemestre_custommenu_edit", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_custommenu_edit(context, REQUEST, formsemestre_id):
|
||||
@ -668,6 +679,7 @@ def formsemestre_custommenu_edit(context, REQUEST, formsemestre_id):
|
||||
|
||||
# --- dialogue modif enseignants/moduleimpl
|
||||
@bp.route("/edit_enseignants_form", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def edit_enseignants_form(context, REQUEST, moduleimpl_id):
|
||||
@ -778,6 +790,7 @@ def edit_enseignants_form(context, REQUEST, moduleimpl_id):
|
||||
|
||||
|
||||
@bp.route("/edit_moduleimpl_resp", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def edit_moduleimpl_resp(context, REQUEST, moduleimpl_id):
|
||||
@ -885,6 +898,7 @@ _EXPR_HELP = """<p class="help">Expérimental: formule de calcul de la moyenne %
|
||||
|
||||
|
||||
@bp.route("/edit_moduleimpl_expr", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def edit_moduleimpl_expr(context, REQUEST, moduleimpl_id):
|
||||
@ -953,6 +967,7 @@ def edit_moduleimpl_expr(context, REQUEST, moduleimpl_id):
|
||||
|
||||
|
||||
@bp.route("/view_module_abs")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def view_module_abs(context, REQUEST, moduleimpl_id, format="html"):
|
||||
@ -1033,6 +1048,7 @@ def view_module_abs(context, REQUEST, moduleimpl_id, format="html"):
|
||||
|
||||
|
||||
@bp.route("/edit_ue_expr", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def edit_ue_expr(context, REQUEST, formsemestre_id, ue_id):
|
||||
@ -1107,6 +1123,7 @@ def edit_ue_expr(context, REQUEST, formsemestre_id, ue_id):
|
||||
|
||||
|
||||
@bp.route("/formsemestre_enseignants_list")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_enseignants_list(context, REQUEST, formsemestre_id, format="html"):
|
||||
@ -1191,6 +1208,7 @@ def formsemestre_enseignants_list(context, REQUEST, formsemestre_id, format="htm
|
||||
|
||||
|
||||
@bp.route("/edit_enseignants_form_delete", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def edit_enseignants_form_delete(context, REQUEST, moduleimpl_id, ens_id):
|
||||
@ -1230,6 +1248,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/do_formsemestre_inscription_listinscrits")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def do_formsemestre_inscription_listinscrits(
|
||||
@ -1243,6 +1262,7 @@ def do_formsemestre_inscription_listinscrits(
|
||||
|
||||
|
||||
@bp.route("/formsemestre_desinscription")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoImplement)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_desinscription(
|
||||
@ -1329,6 +1349,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/etud_desinscrit_ue")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def etud_desinscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
|
||||
@ -1344,6 +1365,7 @@ def etud_desinscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/etud_inscrit_ue")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def etud_inscrit_ue(context, etudid, formsemestre_id, ue_id, REQUEST=None):
|
||||
@ -1407,6 +1429,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/evaluation_delete", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEnsView)
|
||||
@scodoc7func(context)
|
||||
def evaluation_delete(context, REQUEST, evaluation_id):
|
||||
@ -1490,6 +1513,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/evaluation_edit", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEnsView)
|
||||
@scodoc7func(context)
|
||||
def evaluation_edit(evaluation_id, REQUEST):
|
||||
@ -1500,6 +1524,7 @@ def evaluation_edit(evaluation_id, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/evaluation_create", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEnsView)
|
||||
@scodoc7func(context)
|
||||
def evaluation_create(moduleimpl_id, REQUEST):
|
||||
@ -1510,6 +1535,7 @@ def evaluation_create(moduleimpl_id, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/evaluation_listenotes")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def evaluation_listenotes(context, REQUEST=None):
|
||||
@ -1591,6 +1617,7 @@ sco_publish(
|
||||
|
||||
# --- Bulletins
|
||||
@bp.route("/formsemestre_bulletins_pdf")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_bulletins_pdf(
|
||||
@ -1607,6 +1634,7 @@ _EXPL_BULL = """Versions des bulletins:<ul><li><bf>courte</bf>: moyennes des mod
|
||||
|
||||
|
||||
@bp.route("/formsemestre_bulletins_pdf_choice")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_bulletins_pdf_choice(context, REQUEST, formsemestre_id, version=None):
|
||||
@ -1626,6 +1654,7 @@ def formsemestre_bulletins_pdf_choice(context, REQUEST, formsemestre_id, version
|
||||
|
||||
|
||||
@bp.route("/etud_bulletins_pdf")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"):
|
||||
@ -1637,6 +1666,7 @@ def etud_bulletins_pdf(context, etudid, REQUEST, version="selectedevals"):
|
||||
|
||||
|
||||
@bp.route("/formsemestre_bulletins_mailetuds_choice")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_bulletins_mailetuds_choice(
|
||||
@ -1703,6 +1733,7 @@ def formsemestre_bulletins_choice(
|
||||
|
||||
|
||||
@bp.route("/formsemestre_bulletins_mailetuds")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_bulletins_mailetuds(
|
||||
@ -1766,6 +1797,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/appreciation_add_form", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEnsView)
|
||||
@scodoc7func(context)
|
||||
def appreciation_add_form(
|
||||
@ -1875,6 +1907,7 @@ def appreciation_add_form(
|
||||
|
||||
|
||||
@bp.route("/formsemestre_validation_etud_form")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_validation_etud_form(
|
||||
@ -1903,6 +1936,7 @@ def formsemestre_validation_etud_form(
|
||||
|
||||
|
||||
@bp.route("/formsemestre_validation_etud")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_validation_etud(
|
||||
@ -1934,6 +1968,7 @@ def formsemestre_validation_etud(
|
||||
|
||||
|
||||
@bp.route("/formsemestre_validation_etud_manu")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_validation_etud_manu(
|
||||
@ -1971,6 +2006,7 @@ def formsemestre_validation_etud_manu(
|
||||
|
||||
|
||||
@bp.route("/formsemestre_validate_previous_ue")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_validate_previous_ue(
|
||||
@ -1997,6 +2033,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/formsemestre_ext_edit_ue_validations", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_ext_edit_ue_validations(
|
||||
@ -2022,6 +2059,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/etud_ue_suppress_validation")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST=None):
|
||||
@ -2038,6 +2076,7 @@ def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST
|
||||
|
||||
|
||||
@bp.route("/formsemestre_validation_auto")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
|
||||
@ -2055,6 +2094,7 @@ def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/do_formsemestre_validation_auto")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
|
||||
@ -2072,6 +2112,7 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/formsemestre_validation_suppress_etud", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_validation_suppress_etud(
|
||||
@ -2312,6 +2353,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/check_sem_integrity")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoImplement)
|
||||
@scodoc7func(context)
|
||||
def check_sem_integrity(context, formsemestre_id, REQUEST, fix=False):
|
||||
@ -2384,6 +2426,7 @@ def check_sem_integrity(context, formsemestre_id, REQUEST, fix=False):
|
||||
|
||||
|
||||
@bp.route("/check_form_integrity")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def check_form_integrity(context, formation_id, fix=False, REQUEST=None):
|
||||
@ -2423,6 +2466,7 @@ def check_form_integrity(context, formation_id, fix=False, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/check_formsemestre_integrity")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def check_formsemestre_integrity(context, formsemestre_id, REQUEST=None):
|
||||
@ -2473,6 +2517,7 @@ def check_formsemestre_integrity(context, formsemestre_id, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/check_integrity_all")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def check_integrity_all(context, REQUEST=None):
|
||||
|
@ -45,7 +45,7 @@ from app.scodoc.sco_permissions import Permission
|
||||
|
||||
@bp.route("/ScoDoc")
|
||||
@bp.route("/ScoDoc/index")
|
||||
def index():
|
||||
def index(): # XXX TODO A REECRIRE
|
||||
dept_ids = sco_mgr.get_dept_ids()
|
||||
return render_template(
|
||||
"scodoc.html",
|
||||
|
@ -48,6 +48,7 @@ from flask_login import current_user
|
||||
from config import Config
|
||||
import scodoc_manager
|
||||
from app.decorators import (
|
||||
scodoc,
|
||||
scodoc7func,
|
||||
ScoDoc7Context,
|
||||
permission_required,
|
||||
@ -120,7 +121,7 @@ def sco_publish(route, function, permission, methods=("GET",)):
|
||||
protected by permission and called following ScoDoc 7 Zope standards.
|
||||
"""
|
||||
return bp.route(route, methods=methods)(
|
||||
permission_required(permission)(scodoc7func(context)(function))
|
||||
permission_required(permission)(scodoc7func(context)(scodoc(function)))
|
||||
)
|
||||
|
||||
|
||||
@ -135,6 +136,7 @@ log("ScoDoc8 restarting...")
|
||||
|
||||
|
||||
@bp.route("/about")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def about(context, REQUEST):
|
||||
@ -169,6 +171,7 @@ def about(context, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/edit_preferences", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoChangePreferences)
|
||||
@scodoc7func(context)
|
||||
def edit_preferences(context, REQUEST):
|
||||
@ -177,6 +180,7 @@ def edit_preferences(context, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/formsemestre_edit_preferences", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_edit_preferences(context, formsemestre_id, REQUEST):
|
||||
@ -196,6 +200,7 @@ def formsemestre_edit_preferences(context, formsemestre_id, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/doc_preferences")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def doc_preferences(REQUEST):
|
||||
@ -212,6 +217,7 @@ def doc_preferences(REQUEST):
|
||||
|
||||
|
||||
@bp.route("/showEtudLog")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def showEtudLog(context, etudid, format="html", REQUEST=None):
|
||||
@ -248,8 +254,22 @@ def showEtudLog(context, etudid, format="html", REQUEST=None):
|
||||
|
||||
|
||||
# ---------- PAGE ACCUEIL (listes) --------------
|
||||
@bp.route("/")
|
||||
@bp.route("/index_html")
|
||||
# @bp.route("/")
|
||||
@bp.route("/kimo")
|
||||
@scodoc
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def kimo(context, REQUEST=None, showcodes=0, showsemtable=0):
|
||||
import time
|
||||
|
||||
return f"{time.time()} := {g.scodoc_dept}"
|
||||
|
||||
|
||||
# @bp.route("/")
|
||||
@bp.route("/index_html2")
|
||||
@scodoc
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def index_html(context, REQUEST=None, showcodes=0, showsemtable=0):
|
||||
@ -287,6 +307,7 @@ sco_publish(
|
||||
|
||||
# -------------------------- INFOS SUR ETUDIANTS --------------------------
|
||||
@bp.route("/getEtudInfo")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def getEtudInfo(
|
||||
@ -321,6 +342,7 @@ sco_publish(
|
||||
# XMLgetEtudInfos était le nom dans l'ancienne API ScoDoc 6
|
||||
@bp.route("/etud_info")
|
||||
@bp.route("/XMLgetEtudInfos")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def etud_info(context, etudid=None, format="xml", REQUEST=None):
|
||||
@ -494,6 +516,7 @@ sco_publish(
|
||||
|
||||
|
||||
@bp.route("/doAddAnnotation", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudAddAnnotations)
|
||||
@scodoc7func(context)
|
||||
def doAddAnnotation(etudid, comment):
|
||||
@ -514,6 +537,7 @@ def doAddAnnotation(etudid, comment):
|
||||
|
||||
|
||||
@bp.route("/doSuppressAnnotation", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def doSuppressAnnotation(context, etudid, annotation_id, REQUEST):
|
||||
@ -541,6 +565,7 @@ def doSuppressAnnotation(context, etudid, annotation_id, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/formChangeCoordonnees", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudChangeAdr)
|
||||
@scodoc7func(context)
|
||||
def formChangeCoordonnees(context, etudid, REQUEST):
|
||||
@ -704,6 +729,7 @@ sco_publish(
|
||||
methods=["GET", "POST"],
|
||||
)
|
||||
# @bp.route("/partition_create", methods=["GET", "POST"])
|
||||
# @scodoc
|
||||
# @permission_required(Permission.ScoView)
|
||||
# @scodoc7func(context)
|
||||
# def partition_create(
|
||||
@ -725,6 +751,7 @@ sco_publish("/etud_photo_html", sco_photos.etud_photo_html, Permission.ScoView)
|
||||
|
||||
|
||||
@bp.route("/etud_photo_orig_page")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def etud_photo_orig_page(context, etudid=None, REQUEST=None):
|
||||
@ -743,6 +770,7 @@ def etud_photo_orig_page(context, etudid=None, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/formChangePhoto", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudChangeAdr)
|
||||
@scodoc7func(context)
|
||||
def formChangePhoto(context, etudid=None, REQUEST=None):
|
||||
@ -802,6 +830,7 @@ def formChangePhoto(context, etudid=None, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/formSuppressPhoto")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudChangeAdr)
|
||||
@scodoc7func(context)
|
||||
def formSuppressPhoto(context, etudid=None, REQUEST=None, dialog_confirmed=False):
|
||||
@ -826,6 +855,7 @@ def formSuppressPhoto(context, etudid=None, REQUEST=None, dialog_confirmed=False
|
||||
|
||||
#
|
||||
@bp.route("/formDem")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def formDem(context, etudid, formsemestre_id, REQUEST):
|
||||
@ -841,6 +871,7 @@ def formDem(context, etudid, formsemestre_id, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/formDef")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def formDef(context, etudid, formsemestre_id, REQUEST):
|
||||
@ -902,6 +933,7 @@ def _formDem_of_Def(
|
||||
|
||||
|
||||
@bp.route("/doDemEtudiant")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def doDemEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=None):
|
||||
@ -919,6 +951,7 @@ def doDemEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=Non
|
||||
|
||||
|
||||
@bp.route("/doDefEtudiant")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def doDefEtudiant(context, etudid, formsemestre_id, event_date=None, REQUEST=None):
|
||||
@ -980,6 +1013,7 @@ def _do_dem_or_def_etud(
|
||||
|
||||
|
||||
@bp.route("/doCancelDem", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def doCancelDem(
|
||||
@ -1002,6 +1036,7 @@ def doCancelDem(
|
||||
|
||||
|
||||
@bp.route("/doCancelDef", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def doCancelDef(
|
||||
@ -1087,6 +1122,7 @@ def _do_cancel_dem_or_def(
|
||||
|
||||
|
||||
@bp.route("/etudident_create_form", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def etudident_create_form(context, REQUEST=None):
|
||||
@ -1095,6 +1131,7 @@ def etudident_create_form(context, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/etudident_edit_form", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def etudident_edit_form(context, REQUEST=None):
|
||||
@ -1501,6 +1538,7 @@ def _etudident_create_or_edit_form(context, REQUEST, edit):
|
||||
|
||||
|
||||
@bp.route("/etudident_delete", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def etudident_delete(context, etudid, dialog_confirmed=False, REQUEST=None):
|
||||
@ -1573,6 +1611,7 @@ def etudident_delete(context, etudid, dialog_confirmed=False, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/check_group_apogee")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def check_group_apogee(
|
||||
@ -1724,6 +1763,7 @@ def check_group_apogee(
|
||||
|
||||
|
||||
@bp.route("/form_students_import_excel")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def form_students_import_excel(context, REQUEST, formsemestre_id=None):
|
||||
@ -1864,6 +1904,7 @@ Les champs avec un astérisque (*) doivent être présents (nulls non autorisés
|
||||
|
||||
|
||||
@bp.route("/import_generate_excel_sample")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudInscrit)
|
||||
@scodoc7func(context)
|
||||
def import_generate_excel_sample(context, REQUEST, with_codesemestre="1"):
|
||||
@ -1881,6 +1922,7 @@ def import_generate_excel_sample(context, REQUEST, with_codesemestre="1"):
|
||||
|
||||
# --- Données admission
|
||||
@bp.route("/import_generate_admission_sample")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def import_generate_admission_sample(context, REQUEST, formsemestre_id):
|
||||
@ -1902,6 +1944,7 @@ def import_generate_admission_sample(context, REQUEST, formsemestre_id):
|
||||
|
||||
# --- Données admission depuis fichier excel (version nov 2016)
|
||||
@bp.route("/form_students_import_infos_admissions", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None):
|
||||
@ -2009,6 +2052,7 @@ def form_students_import_infos_admissions(context, REQUEST, formsemestre_id=None
|
||||
|
||||
|
||||
@bp.route("/formsemestre_import_etud_admission")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoEtudChangeAdr)
|
||||
@scodoc7func(context)
|
||||
def formsemestre_import_etud_admission(
|
||||
@ -2057,6 +2101,7 @@ sco_publish(
|
||||
|
||||
# --- Statistiques
|
||||
@bp.route("/stat_bac")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def stat_bac(context, formsemestre_id):
|
||||
|
@ -48,6 +48,7 @@ from app.auth.models import User
|
||||
from app.auth.models import Role
|
||||
from app.auth.models import UserRole
|
||||
from app.decorators import (
|
||||
scodoc,
|
||||
scodoc7func,
|
||||
ScoDoc7Context,
|
||||
permission_required,
|
||||
@ -71,6 +72,7 @@ context = ScoDoc7Context("users") # sco8
|
||||
|
||||
@bp.route("/")
|
||||
@bp.route("/index_html")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoUsersView)
|
||||
@scodoc7func(context)
|
||||
def index_html(context, REQUEST, all_depts=False, with_inactives=False, format="html"):
|
||||
@ -84,6 +86,7 @@ def index_html(context, REQUEST, all_depts=False, with_inactives=False, format="
|
||||
|
||||
|
||||
@bp.route("/user_info")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoUsersView)
|
||||
@scodoc7func(context)
|
||||
def user_info(user_name, format="json", REQUEST=None):
|
||||
@ -92,6 +95,7 @@ def user_info(user_name, format="json", REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/create_user_form", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoUsersAdmin)
|
||||
@scodoc7func(context)
|
||||
def create_user_form(context, REQUEST, user_name=None, edit=0):
|
||||
@ -464,6 +468,7 @@ def import_users_form():
|
||||
|
||||
|
||||
@bp.route("/user_info_page")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoUsersView)
|
||||
@scodoc7func(context)
|
||||
def user_info_page(user_name, REQUEST=None):
|
||||
@ -471,6 +476,7 @@ def user_info_page(user_name, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/get_user_list_xml")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def get_user_list_xml(dept=None, start="", limit=25, REQUEST=None):
|
||||
@ -496,6 +502,7 @@ def get_user_list_xml(dept=None, start="", limit=25, REQUEST=None):
|
||||
|
||||
|
||||
@bp.route("/form_change_password")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def form_change_password(REQUEST, user_name=None):
|
||||
@ -534,6 +541,7 @@ def form_change_password(REQUEST, user_name=None):
|
||||
|
||||
|
||||
@bp.route("/change_password", methods=["POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func(context)
|
||||
def change_password(user_name, password, password2, REQUEST):
|
||||
@ -593,6 +601,7 @@ def change_password(user_name, password, password2, REQUEST):
|
||||
|
||||
|
||||
@bp.route("/delete_user_form", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoUsersAdmin)
|
||||
@scodoc7func(context)
|
||||
def delete_user_form(REQUEST, user_name, dialog_confirmed=False):
|
||||
|
28
scodoc.py
28
scodoc.py
@ -146,11 +146,22 @@ def user_password(username, password=None): # user-password
|
||||
@app.cli.command()
|
||||
@click.argument("dept")
|
||||
def sco_delete_dept(dept): # sco-delete-dept
|
||||
"Delete existing departement"
|
||||
raise NotImplementedError()
|
||||
if os.system('tools/delete_dept.sh -n "{}"'.format(dept)):
|
||||
sys.stderr.write("error deleting dept " + dept)
|
||||
return 1
|
||||
"""Delete existing departement"""
|
||||
click.confirm(
|
||||
f"""Attention: Cela va effacer toutes les données du département {dept}
|
||||
(étudiants, notes, formations, etc)
|
||||
Voulez-vous vraiment continuer ?
|
||||
""",
|
||||
abort=True,
|
||||
)
|
||||
db.reflect()
|
||||
d = models.Departement.query.filter_by(acronym=dept).first()
|
||||
if d is None:
|
||||
sys.stderr.write(f"Erreur: le departement {dept} n'existe pas !")
|
||||
return 2
|
||||
# XXX TODO: détruire les objets du département !
|
||||
db.session.delete(d)
|
||||
db.session.commit()
|
||||
return 0
|
||||
|
||||
|
||||
@ -158,10 +169,9 @@ def sco_delete_dept(dept): # sco-delete-dept
|
||||
@click.argument("dept")
|
||||
def sco_create_dept(dept): # sco-create-dept
|
||||
"Create new departement"
|
||||
raise NotImplementedError()
|
||||
if os.system(f'tools/create_dept.sh -n "{dept}"'):
|
||||
sys.stderr.write(f"error creating dept {dept}\n")
|
||||
return 1
|
||||
d = models.Departement(acronym=dept)
|
||||
db.session.add(d)
|
||||
db.session.commit()
|
||||
return 0
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@ from flask import g
|
||||
from flask_login import login_user, logout_user, current_user
|
||||
|
||||
from config import TestConfig
|
||||
import app
|
||||
from app import db, create_app
|
||||
from app import initialize_scodoc_database, clear_scodoc_cache
|
||||
from app import models
|
||||
@ -44,9 +45,13 @@ def test_client():
|
||||
u.add_role(admin_role, TestConfig.DEPT_TEST)
|
||||
db.session.add(u)
|
||||
db.session.commit()
|
||||
ndb.set_sco_dept(TestConfig.DEPT_TEST) # set db connection
|
||||
# Creation département de Test
|
||||
d = models.Departement(acronym=TestConfig.DEPT_TEST)
|
||||
db.session.add(d)
|
||||
db.session.commit()
|
||||
app.set_sco_dept(TestConfig.DEPT_TEST) # set db connection
|
||||
yield client
|
||||
# ndb.close_dept_connection()
|
||||
ndb.close_db_connection()
|
||||
# Teardown:
|
||||
db.session.commit()
|
||||
db.session.remove()
|
||||
|
@ -11,6 +11,7 @@ Usage: pytest tests/unit/test_caches.py
|
||||
|
||||
from flask import current_app, g
|
||||
|
||||
import app
|
||||
from app import db
|
||||
from app.scodoc import sco_cache
|
||||
from app.scodoc import sco_evaluations
|
||||
@ -25,7 +26,7 @@ context = None # #context
|
||||
|
||||
def test_notes_table(test_client):
|
||||
"""Test construction et cache de NotesTable."""
|
||||
ndb.set_sco_dept(DEPT)
|
||||
app.set_sco_dept(DEPT)
|
||||
assert g.scodoc_dept == DEPT
|
||||
# prépare le département avec quelques semestres:
|
||||
run_sco_basic()
|
||||
@ -49,7 +50,7 @@ def test_notes_table(test_client):
|
||||
def test_cache_evaluations(test_client):
|
||||
""""""
|
||||
# cherche un semestre ayant des evaluations
|
||||
ndb.set_sco_dept(DEPT)
|
||||
app.set_sco_dept(DEPT)
|
||||
# prépare le département avec quelques semestres:
|
||||
run_sco_basic()
|
||||
#
|
||||
|
94
tests/unit/test_departements.py
Normal file
94
tests/unit/test_departements.py
Normal file
@ -0,0 +1,94 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Test ORM departement/formation/preferences
|
||||
|
||||
|
||||
Utiliser comme:
|
||||
pytest tests/unit/test_departements.py
|
||||
|
||||
"""
|
||||
from flask import g
|
||||
import app
|
||||
from app import db
|
||||
from app.models import Departement, ScoPreference, FormSemestre, formsemestre
|
||||
from app.scodoc import notesdb as ndb
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_preferences
|
||||
from tests.unit import test_sco_basic
|
||||
|
||||
|
||||
def test_preferences_orm(test_client):
|
||||
"""preferences, via ORM and legacy ScoDoc"""
|
||||
d = Departement(acronym="TT")
|
||||
p1 = ScoPreference(name="temperature", value="24", departement=d)
|
||||
p2 = ScoPreference(name="couleur", value="bleue", departement=d)
|
||||
db.session.add(d)
|
||||
db.session.add(p1)
|
||||
db.session.add(p2)
|
||||
db.session.commit()
|
||||
prefs = d.preferences.all()
|
||||
assert isinstance(prefs, list)
|
||||
assert len(prefs) == 2
|
||||
|
||||
|
||||
def test_preferences(test_client):
|
||||
"""ScoDoc preferences"""
|
||||
# preferences "globales" d'un département:
|
||||
current_dept = Departement.query.filter_by(acronym=g.scodoc_dept).first()
|
||||
prefs = sco_preferences.get_base_preferences()
|
||||
assert isinstance(prefs, sco_preferences.BasePreferences)
|
||||
assert prefs.dept_id == current_dept.id
|
||||
# Compare nombre de d'items
|
||||
assert len(ScoPreference.query.filter_by(dept_id=current_dept.id).all()) == len(
|
||||
prefs
|
||||
)
|
||||
# Accès à une valeur via ORM
|
||||
assert (
|
||||
len(
|
||||
ScoPreference.query.filter_by(
|
||||
dept_id=current_dept.id, name="abs_notification_mail_tmpl"
|
||||
).all()
|
||||
)
|
||||
== 1
|
||||
)
|
||||
orm_val = (
|
||||
ScoPreference.query.filter_by(
|
||||
dept_id=current_dept.id, name="abs_notification_mail_tmpl"
|
||||
)
|
||||
.first()
|
||||
.value
|
||||
)
|
||||
# Compare valeurs
|
||||
sco_val = prefs.get(None, "abs_notification_mail_tmpl")
|
||||
assert orm_val.strip() == sco_val.strip()
|
||||
# nb: I don't understand why SQLAlchemy strips the string ?!
|
||||
|
||||
# --- Charge dans un autre département
|
||||
# departement fictif créé ici:
|
||||
d = Departement(acronym="D2")
|
||||
db.session.add(d)
|
||||
db.session.commit()
|
||||
app.set_sco_dept("D2")
|
||||
prefs2 = sco_preferences.get_base_preferences()
|
||||
assert len(prefs2) == len(prefs)
|
||||
prefs2.set(None, "abs_notification_mail_tmpl", "toto")
|
||||
assert prefs2.get(None, "abs_notification_mail_tmpl") == "toto"
|
||||
assert prefs.get(None, "abs_notification_mail_tmpl") != "toto"
|
||||
orm_val = (
|
||||
ScoPreference.query.filter_by(dept_id=d.id, name="abs_notification_mail_tmpl")
|
||||
.first()
|
||||
.value
|
||||
)
|
||||
assert orm_val == "toto"
|
||||
# --- Preferences d'un semestre
|
||||
# rejoure ce test pour avoir un semestre créé
|
||||
test_sco_basic.run_sco_basic()
|
||||
sem = sco_formsemestre.do_formsemestre_list(None)[0]
|
||||
formsemestre_id = sem["formsemestre_id"]
|
||||
semp = sco_preferences.SemPreferences(formsemestre_id=formsemestre_id)
|
||||
assert semp["abs_notification_mail_tmpl"] == "toto"
|
||||
assert semp.is_global("abs_notification_mail_tmpl")
|
||||
# donne une valeur pour le semestre:
|
||||
prefs2.set(formsemestre_id, "abs_notification_mail_tmpl", "foo")
|
||||
assert not semp.is_global("abs_notification_mail_tmpl")
|
||||
assert semp["abs_notification_mail_tmpl"] == "foo"
|
@ -7,8 +7,8 @@
|
||||
Utiliser comme:
|
||||
pytest tests/unit/test_sco_basic.py
|
||||
|
||||
Au préalable, créer un département de test neuf:
|
||||
flask sco-delete-dept TEST00 && flask sco-create-dept TEST00
|
||||
Au besoin, créer un base de test neuve:
|
||||
./tools/create_database.sh SCODOC_TEST
|
||||
|
||||
"""
|
||||
import random
|
||||
@ -18,6 +18,7 @@ from flask import g
|
||||
from config import TestConfig
|
||||
from tests.unit import sco_fake_gen
|
||||
|
||||
import app
|
||||
from app.scodoc import notesdb as ndb
|
||||
from app.scodoc import sco_abs
|
||||
from app.scodoc import sco_abs_views
|
||||
@ -38,7 +39,7 @@ def test_sco_basic(test_client):
|
||||
Création 10 étudiants, formation, semestre, inscription etudiant,
|
||||
creation 1 evaluation, saisie 10 notes.
|
||||
"""
|
||||
ndb.set_sco_dept(DEPT)
|
||||
app.set_sco_dept(DEPT)
|
||||
run_sco_basic()
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user