forked from ScoDoc/DocScoDoc
Merge branch 'new_api' of https://scodoc.org/git/ScoDoc/ScoDoc into new_api
This commit is contained in:
commit
208aeb35a0
@ -24,6 +24,10 @@
|
|||||||
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
from flask import abort
|
||||||
from flask import g
|
from flask import g
|
||||||
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth
|
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth
|
||||||
from app.auth.models import User
|
from app.auth.models import User
|
||||||
@ -63,15 +67,17 @@ def get_user_roles(user):
|
|||||||
return user.roles
|
return user.roles
|
||||||
|
|
||||||
|
|
||||||
# def token_permission_required(permission):
|
def token_permission_required(permission):
|
||||||
# def decorator(f):
|
def decorator(f):
|
||||||
# @wraps(f)
|
@wraps(f)
|
||||||
# def decorated_function(*args, **kwargs):
|
def decorated_function(*args, **kwargs):
|
||||||
# scodoc_dept = getattr(g, "scodoc_dept", None)
|
scodoc_dept = getattr(g, "scodoc_dept", None)
|
||||||
# if not current_user.has_permission(permission, scodoc_dept):
|
if hasattr(g, "current_user") and not g.current_user.has_permission(
|
||||||
# abort(403)
|
permission, scodoc_dept
|
||||||
# return f(*args, **kwargs)
|
):
|
||||||
|
abort(403)
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
# return login_required(decorated_function)
|
return decorated_function # login_required(decorated_function)
|
||||||
|
|
||||||
# return decorator
|
return decorator
|
||||||
|
@ -1,23 +1,17 @@
|
|||||||
############################################### Departements ##########################################################
|
############################################### Departements ##########################################################
|
||||||
|
from flask import g
|
||||||
from flask import jsonify
|
from flask import jsonify
|
||||||
|
|
||||||
from app import models
|
from app import models
|
||||||
from app.api import bp
|
from app.api import bp
|
||||||
from app.api.auth import token_auth
|
from app.api.auth import token_auth, token_permission_required
|
||||||
from app.api.errors import error_response
|
from app.api.errors import error_response
|
||||||
from app.decorators import permission_required
|
|
||||||
from app.models import ApcReferentielCompetences
|
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.scodoc.sco_prepajury import feuille_preparation_jury
|
|
||||||
from app.scodoc.sco_pvjury import formsemestre_pvjury
|
|
||||||
from app.scodoc.sco_recapcomplet import formsemestre_recapcomplet
|
|
||||||
from app.scodoc.sco_saisie_notes import notes_add
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departements", methods=["GET"])
|
@bp.route("/departements", methods=["GET"])
|
||||||
@token_auth.login_required # Commenté le temps des tests
|
@token_auth.login_required
|
||||||
# @permission_required(Permission.ScoView)
|
@token_permission_required(Permission.APIView)
|
||||||
def departements():
|
def departements():
|
||||||
"""
|
"""
|
||||||
Retourne la liste des ids de départements visibles
|
Retourne la liste des ids de départements visibles
|
||||||
@ -34,7 +28,9 @@ def departements():
|
|||||||
|
|
||||||
|
|
||||||
@bp.route("/departements/<string:dept>/etudiants/liste", methods=["GET"])
|
@bp.route("/departements/<string:dept>/etudiants/liste", methods=["GET"])
|
||||||
@bp.route("/departements/<string:dept>/etudiants/liste/<int:formsemestre_id>", methods=["GET"])
|
@bp.route(
|
||||||
|
"/departements/<string:dept>/etudiants/liste/<int:formsemestre_id>", methods=["GET"]
|
||||||
|
)
|
||||||
@token_auth.login_required
|
@token_auth.login_required
|
||||||
# @permission_required(Permission.APIView)
|
# @permission_required(Permission.APIView)
|
||||||
def liste_etudiants(dept: str, formsemestre_id=None):
|
def liste_etudiants(dept: str, formsemestre_id=None):
|
||||||
@ -154,7 +150,10 @@ def liste_semestres_courant(dept: str):
|
|||||||
return jsonify(data)
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departements/<string:dept>/formations/<int:formation_id>/referentiel_competences", methods=["GET"])
|
@bp.route(
|
||||||
|
"/departements/<string:dept>/formations/<int:formation_id>/referentiel_competences",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
# @permission_required(Permission.APIView)
|
# @permission_required(Permission.APIView)
|
||||||
def referenciel_competences(dept: str, formation_id: int):
|
def referenciel_competences(dept: str, formation_id: int):
|
||||||
"""
|
"""
|
||||||
@ -167,12 +166,16 @@ def referenciel_competences(dept: str, formation_id: int):
|
|||||||
|
|
||||||
id_dept = depts[0].id
|
id_dept = depts[0].id
|
||||||
|
|
||||||
formations = models.Formation.query.filter_by(id=formation_id, dept_id=id_dept).all()
|
formations = models.Formation.query.filter_by(
|
||||||
|
id=formation_id, dept_id=id_dept
|
||||||
|
).all()
|
||||||
|
|
||||||
ref_comp = formations[0].referentiel_competence_id
|
ref_comp = formations[0].referentiel_competence_id
|
||||||
|
|
||||||
if ref_comp is None:
|
if ref_comp is None:
|
||||||
return error_response(204, message="Pas de référenciel de compétences pour cette formation")
|
return error_response(
|
||||||
|
204, message="Pas de référenciel de compétences pour cette formation"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return jsonify(ref_comp)
|
return jsonify(ref_comp)
|
||||||
|
|
||||||
@ -181,7 +184,10 @@ def referenciel_competences(dept: str, formation_id: int):
|
|||||||
# return jsonify(ref.to_dict())
|
# return jsonify(ref.to_dict())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departements/<string:dept>/formsemestre/<string:formsemestre_id>/programme", methods=["GET"])
|
@bp.route(
|
||||||
|
"/departements/<string:dept>/formsemestre/<string:formsemestre_id>/programme",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
# @permission_required(Permission.APIView)
|
# @permission_required(Permission.APIView)
|
||||||
def semestre_index(dept: str, formsemestre_id: int):
|
def semestre_index(dept: str, formsemestre_id: int):
|
||||||
"""
|
"""
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
################################################## Tests ##############################################################
|
################################################## Tests ##############################################################
|
||||||
|
|
||||||
|
|
||||||
|
# XXX OBSOLETE ??? XXX
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -15,6 +18,7 @@ CHECK_CERTIFICATE = bool(int(os.environ.get("CHECK_CERTIFICATE", False)))
|
|||||||
|
|
||||||
HEADERS = None
|
HEADERS = None
|
||||||
|
|
||||||
|
|
||||||
def get_token():
|
def get_token():
|
||||||
"""
|
"""
|
||||||
Permet de set le token dans le header
|
Permet de set le token dans le header
|
||||||
@ -52,7 +56,8 @@ def get_departement():
|
|||||||
# departements
|
# departements
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements",
|
SCODOC_URL + "/ScoDoc/api/departements",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE,
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
|
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
@ -90,17 +95,40 @@ def get_formsemestre():
|
|||||||
# liste_semestres_courant
|
# liste_semestres_courant
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements/" + dept_acronym + "/semestres_courants",
|
SCODOC_URL + "/ScoDoc/api/departements/" + dept_acronym + "/semestres_courants",
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
)
|
)
|
||||||
|
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
formsemestre = r.json()[0]
|
formsemestre = r.json()[0]
|
||||||
print(r.json()[0])
|
print(r.json()[0])
|
||||||
|
|
||||||
fields = ["gestion_semestrielle", "titre", "scodoc7_id", "date_debut", "bul_bgcolor", "date_fin",
|
fields = [
|
||||||
"resp_can_edit", "dept_id", "etat", "resp_can_change_ens", "id", "modalite", "ens_can_edit_eval",
|
"gestion_semestrielle",
|
||||||
"formation_id", "gestion_compensation", "elt_sem_apo", "semestre_id", "bul_hide_xml", "elt_annee_apo",
|
"titre",
|
||||||
"block_moyennes", "formsemestre_id", "titre_num", "date_debut_iso", "date_fin_iso", "responsables"]
|
"scodoc7_id",
|
||||||
|
"date_debut",
|
||||||
|
"bul_bgcolor",
|
||||||
|
"date_fin",
|
||||||
|
"resp_can_edit",
|
||||||
|
"dept_id",
|
||||||
|
"etat",
|
||||||
|
"resp_can_change_ens",
|
||||||
|
"id",
|
||||||
|
"modalite",
|
||||||
|
"ens_can_edit_eval",
|
||||||
|
"formation_id",
|
||||||
|
"gestion_compensation",
|
||||||
|
"elt_sem_apo",
|
||||||
|
"semestre_id",
|
||||||
|
"bul_hide_xml",
|
||||||
|
"elt_annee_apo",
|
||||||
|
"block_moyennes",
|
||||||
|
"formsemestre_id",
|
||||||
|
"titre_num",
|
||||||
|
"date_debut_iso",
|
||||||
|
"date_fin_iso",
|
||||||
|
"responsables",
|
||||||
|
]
|
||||||
|
|
||||||
for field in formsemestre:
|
for field in formsemestre:
|
||||||
if field not in fields:
|
if field not in fields:
|
||||||
@ -114,7 +142,6 @@ def get_formsemestre():
|
|||||||
return error_response(409, "La requête ne peut être traitée en l’état actuel")
|
return error_response(409, "La requête ne peut être traitée en l’état actuel")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/test_etu", methods=["GET"])
|
@bp.route("/test_etu", methods=["GET"])
|
||||||
def get_etudiant():
|
def get_etudiant():
|
||||||
"""
|
"""
|
||||||
@ -124,14 +151,23 @@ def get_etudiant():
|
|||||||
# etudiants
|
# etudiants
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/etudiants/courant",
|
SCODOC_URL + "/ScoDoc/api/etudiants/courant",
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
)
|
)
|
||||||
|
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
etu = r.json()[0]
|
etu = r.json()[0]
|
||||||
|
|
||||||
fields = ["civilite", "code_ine", "code_nip", "date_naissance", "email", "emailperso", "etudid", "nom",
|
fields = [
|
||||||
"prenom"]
|
"civilite",
|
||||||
|
"code_ine",
|
||||||
|
"code_nip",
|
||||||
|
"date_naissance",
|
||||||
|
"email",
|
||||||
|
"emailperso",
|
||||||
|
"etudid",
|
||||||
|
"nom",
|
||||||
|
"prenom",
|
||||||
|
]
|
||||||
|
|
||||||
for field in etu:
|
for field in etu:
|
||||||
if field not in fields:
|
if field not in fields:
|
||||||
@ -162,12 +198,22 @@ def test_departements_liste_etudiants():
|
|||||||
global FORMSEMESTRE
|
global FORMSEMESTRE
|
||||||
|
|
||||||
# Set les fields à vérifier
|
# Set les fields à vérifier
|
||||||
fields = ["civilite", "code_ine", "code_nip", "date_naissance", "email", "emailperso", "etudid", "nom", "prenom"]
|
fields = [
|
||||||
|
"civilite",
|
||||||
|
"code_ine",
|
||||||
|
"code_nip",
|
||||||
|
"date_naissance",
|
||||||
|
"email",
|
||||||
|
"emailperso",
|
||||||
|
"etudid",
|
||||||
|
"nom",
|
||||||
|
"prenom",
|
||||||
|
]
|
||||||
|
|
||||||
# liste_etudiants (sans formsemestre)
|
# liste_etudiants (sans formsemestre)
|
||||||
r1 = requests.get(
|
r1 = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements/" + DEPT["acronym"] + "/etudiants/liste",
|
SCODOC_URL + "/ScoDoc/api/departements/" + DEPT["acronym"] + "/etudiants/liste",
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
)
|
)
|
||||||
|
|
||||||
if r1.status_code == 200: # Si la requête est "OK"
|
if r1.status_code == 200: # Si la requête est "OK"
|
||||||
@ -180,12 +226,14 @@ def test_departements_liste_etudiants():
|
|||||||
if field not in fields:
|
if field not in fields:
|
||||||
return error_response(501, field + " field missing")
|
return error_response(501, field + " field missing")
|
||||||
|
|
||||||
|
|
||||||
# liste_etudiants (avec formsemestre)
|
# liste_etudiants (avec formsemestre)
|
||||||
r2 = requests.get(
|
r2 = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements/" + DEPT["acronym"] + "/etudiants/liste/" +
|
SCODOC_URL
|
||||||
str(FORMSEMESTRE["formsemestre_id"]),
|
+ "/ScoDoc/api/departements/"
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
+ DEPT["acronym"]
|
||||||
|
+ "/etudiants/liste/"
|
||||||
|
+ str(FORMSEMESTRE["formsemestre_id"]),
|
||||||
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
)
|
)
|
||||||
|
|
||||||
if r2.status_code == 200: # Si la requête est "OK"
|
if r2.status_code == 200: # Si la requête est "OK"
|
||||||
@ -216,9 +264,13 @@ def test_departements_referenciel_competences():
|
|||||||
|
|
||||||
# referenciel_competences
|
# referenciel_competences
|
||||||
r = requests.post(
|
r = requests.post(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements/" + DEPT["acronym"] + "/formations/" +
|
SCODOC_URL
|
||||||
FORMSEMESTRE["formation_id"] + "/referentiel_competences",
|
+ "/ScoDoc/api/departements/"
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
+ DEPT["acronym"]
|
||||||
|
+ "/formations/"
|
||||||
|
+ FORMSEMESTRE["formation_id"]
|
||||||
|
+ "/referentiel_competences",
|
||||||
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -229,53 +281,42 @@ def test_departements_semestre_index():
|
|||||||
"""
|
"""
|
||||||
# semestre_index
|
# semestre_index
|
||||||
r5 = requests.post(
|
r5 = requests.post(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements/" + DEPT["acronym"] + "/formsemestre/" +
|
SCODOC_URL
|
||||||
FORMSEMESTRE["formation_id"] + "/programme",
|
+ "/ScoDoc/api/departements/"
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
+ DEPT["acronym"]
|
||||||
|
+ "/formsemestre/"
|
||||||
|
+ FORMSEMESTRE["formation_id"]
|
||||||
|
+ "/programme",
|
||||||
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#################################################### Etudiants ########################################################
|
#################################################### Etudiants ########################################################
|
||||||
|
|
||||||
|
|
||||||
def test_routes_etudiants():
|
def test_routes_etudiants():
|
||||||
"""
|
"""
|
||||||
Test les routes de la partie Etudiants
|
Test les routes de la partie Etudiants
|
||||||
"""
|
"""
|
||||||
# etudiants
|
# etudiants
|
||||||
r1 = requests.get(
|
r1 = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/etudiants",
|
SCODOC_URL + "/ScoDoc/api/etudiants", auth=(SCODOC_USER, SCODOC_PASSWORD)
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# etudiants_courant
|
# etudiants_courant
|
||||||
r2 = requests.post(
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# etudiant
|
# etudiant
|
||||||
r3 = requests.post(
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# etudiant_formsemestres
|
# etudiant_formsemestres
|
||||||
r4 = requests.post(
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# etudiant_bulletin_semestre
|
# etudiant_bulletin_semestre
|
||||||
r5 = requests.post(
|
r5 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# etudiant_groups
|
# etudiant_groups
|
||||||
r6 = requests.post(
|
r6 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_routes_formation():
|
def test_routes_formation():
|
||||||
@ -283,40 +324,22 @@ def test_routes_formation():
|
|||||||
Test les routes de la partie Formation
|
Test les routes de la partie Formation
|
||||||
"""
|
"""
|
||||||
# formations
|
# formations
|
||||||
r1 = requests.post(
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# formations_by_id
|
# formations_by_id
|
||||||
r2 = requests.post(
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# formation_export_by_formation_id
|
# formation_export_by_formation_id
|
||||||
r3 = requests.post(
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# formsemestre_apo
|
# formsemestre_apo
|
||||||
r4 = requests.post(
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# moduleimpls
|
# moduleimpls
|
||||||
r5 = requests.post(
|
r5 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# moduleimpls_sem
|
# moduleimpls_sem
|
||||||
r6 = requests.post(
|
r6 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_routes_formsemestres():
|
def test_routes_formsemestres():
|
||||||
@ -324,28 +347,16 @@ def test_routes_formsemestres():
|
|||||||
Test les routes de la partie Formsemestres
|
Test les routes de la partie Formsemestres
|
||||||
"""
|
"""
|
||||||
# formsemestre
|
# formsemestre
|
||||||
r1 = requests.post(
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# etudiant_bulletin
|
# etudiant_bulletin
|
||||||
r2 = requests.post(
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# bulletins
|
# bulletins
|
||||||
r3 = requests.post(
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# jury
|
# jury
|
||||||
r4 = requests.post(
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_routes_partitions():
|
def test_routes_partitions():
|
||||||
@ -353,22 +364,13 @@ def test_routes_partitions():
|
|||||||
Test les routes de la partie Partitions
|
Test les routes de la partie Partitions
|
||||||
"""
|
"""
|
||||||
# partition
|
# partition
|
||||||
r1 = requests.post(
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# etud_in_group
|
# etud_in_group
|
||||||
r2 = requests.post(
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# set_groups
|
# set_groups
|
||||||
r3 = requests.post(
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_routes_evaluations():
|
def test_routes_evaluations():
|
||||||
@ -376,22 +378,13 @@ def test_routes_evaluations():
|
|||||||
Test les routes de la partie Evaluations
|
Test les routes de la partie Evaluations
|
||||||
"""
|
"""
|
||||||
# evaluations
|
# evaluations
|
||||||
r1 = requests.post(
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# evaluation_notes
|
# evaluation_notes
|
||||||
r2 = requests.post(
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# evaluation_set_notes
|
# evaluation_set_notes
|
||||||
r3 = requests.post(
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_routes_jury():
|
def test_routes_jury():
|
||||||
@ -399,28 +392,16 @@ def test_routes_jury():
|
|||||||
Test les routes de la partie Jury
|
Test les routes de la partie Jury
|
||||||
"""
|
"""
|
||||||
# jury_preparation
|
# jury_preparation
|
||||||
r1 = requests.post(
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# jury_decisions
|
# jury_decisions
|
||||||
r2 = requests.post(
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# set_decision_jury
|
# set_decision_jury
|
||||||
r3 = requests.post(
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# annule_decision_jury
|
# annule_decision_jury
|
||||||
r4 = requests.post(
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_routes_absences():
|
def test_routes_absences():
|
||||||
@ -428,40 +409,22 @@ def test_routes_absences():
|
|||||||
Test les routes de la partie Absences
|
Test les routes de la partie Absences
|
||||||
"""
|
"""
|
||||||
# absences
|
# absences
|
||||||
r1 = requests.post(
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# absences_justify
|
# absences_justify
|
||||||
r2 = requests.post(
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# abs_signale
|
# abs_signale
|
||||||
r3 = requests.post(
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# abs_annule
|
# abs_annule
|
||||||
r4 = requests.post(
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# abs_annule_justif
|
# abs_annule_justif
|
||||||
r5 = requests.post(
|
r5 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# abs_groupe_etat
|
# abs_groupe_etat
|
||||||
r6 = requests.post(
|
r6 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_routes_logos():
|
def test_routes_logos():
|
||||||
@ -469,25 +432,13 @@ def test_routes_logos():
|
|||||||
Test les routes de la partie Logos
|
Test les routes de la partie Logos
|
||||||
"""
|
"""
|
||||||
# liste_logos
|
# liste_logos
|
||||||
r1 = requests.post(
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# recup_logo_global
|
# recup_logo_global
|
||||||
r2 = requests.post(
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# logo_dept
|
# logo_dept
|
||||||
r3 = requests.post(
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
|
||||||
# recup_logo_dept_global
|
# recup_logo_dept_global
|
||||||
r4 = requests.post(
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
SCODOC_URL + "/ScoDoc/api",
|
|
||||||
auth=(SCODOC_USER, SCODOC_PASSWORD)
|
|
||||||
)
|
|
||||||
|
@ -531,10 +531,11 @@ class BonusCachan1(BonusSportAdditif):
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li> DUT/LP : la meilleure note d'option, si elle est supérieure à 10,
|
<li> DUT/LP : la meilleure note d'option, si elle est supérieure à 10,
|
||||||
bonifie les moyennes d'UE (<b>sauf l'UE41 dont le code est UE41_E</b>) à raison
|
bonifie les moyennes d'UE (uniquement UE13_E pour le semestre 1, UE23_E
|
||||||
|
pour le semestre 2, UE33_E pour le semestre 3 et UE43_E pour le semestre
|
||||||
|
4) à raison
|
||||||
de <em>bonus = (option - 10)/10</em>.
|
de <em>bonus = (option - 10)/10</em>.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li> BUT : la meilleure note d'option, si elle est supérieure à 10, bonifie
|
<li> BUT : la meilleure note d'option, si elle est supérieure à 10, bonifie
|
||||||
les moyennes d'UE à raison de <em>bonus = (option - 10) * 3%</em>.</li>
|
les moyennes d'UE à raison de <em>bonus = (option - 10) * 3%</em>.</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -545,6 +546,7 @@ class BonusCachan1(BonusSportAdditif):
|
|||||||
seuil_moy_gen = 10.0 # tous les points sont comptés
|
seuil_moy_gen = 10.0 # tous les points sont comptés
|
||||||
proportion_point = 0.03
|
proportion_point = 0.03
|
||||||
classic_use_bonus_ues = True
|
classic_use_bonus_ues = True
|
||||||
|
ues_bonifiables_cachan = {"UE13_E", "UE23_E", "UE33_E", "UE43_E"}
|
||||||
|
|
||||||
def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
|
def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
|
||||||
"""calcul du bonus, avec réglage différent suivant le type de formation"""
|
"""calcul du bonus, avec réglage différent suivant le type de formation"""
|
||||||
@ -569,7 +571,7 @@ class BonusCachan1(BonusSportAdditif):
|
|||||||
dtype=float,
|
dtype=float,
|
||||||
)
|
)
|
||||||
else: # --- DUT
|
else: # --- DUT
|
||||||
# pareil mais proportion différente et exclusion d'une UE
|
# pareil mais proportion différente et application à certaines UEs
|
||||||
proportion_point = 0.1
|
proportion_point = 0.1
|
||||||
bonus_moy_arr = np.where(
|
bonus_moy_arr = np.where(
|
||||||
note_bonus_max > self.seuil_moy_gen,
|
note_bonus_max > self.seuil_moy_gen,
|
||||||
@ -582,10 +584,10 @@ class BonusCachan1(BonusSportAdditif):
|
|||||||
columns=ues_idx,
|
columns=ues_idx,
|
||||||
dtype=float,
|
dtype=float,
|
||||||
)
|
)
|
||||||
# Pas de bonus sur la ou les ue de code "UE41_E"
|
# Applique bonus seulement sur certaines UE de code connu:
|
||||||
ue_exclues = [ue for ue in ues if ue.ue_code == "UE41_E"]
|
for ue in ues:
|
||||||
for ue in ue_exclues:
|
if ue.ue_code not in self.ues_bonifiables_cachan:
|
||||||
self.bonus_ues[ue.id] = 0.0
|
self.bonus_ues[ue.id] = 0.0 # annule
|
||||||
|
|
||||||
|
|
||||||
class BonusCalais(BonusSportAdditif):
|
class BonusCalais(BonusSportAdditif):
|
||||||
@ -1011,7 +1013,7 @@ class BonusTarbes(BonusSportAdditif):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
name = "bonus_tarbes"
|
name = "bonus_tarbes"
|
||||||
displayed_name = "IUT de Tazrbes"
|
displayed_name = "IUT de Tarbes"
|
||||||
seuil_moy_gen = 10.0
|
seuil_moy_gen = 10.0
|
||||||
proportion_point = 1 / 30.0
|
proportion_point = 1 / 30.0
|
||||||
classic_use_bonus_ues = True
|
classic_use_bonus_ues = True
|
||||||
|
@ -16,7 +16,7 @@ from app import models
|
|||||||
|
|
||||||
from app.scodoc import notesdb as ndb
|
from app.scodoc import notesdb as ndb
|
||||||
from app.scodoc.sco_bac import Baccalaureat
|
from app.scodoc.sco_bac import Baccalaureat
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoInvalidParamError
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
|
|
||||||
|
|
||||||
@ -358,7 +358,7 @@ def make_etud_args(
|
|||||||
try:
|
try:
|
||||||
args = {"etudid": int(etudid)}
|
args = {"etudid": int(etudid)}
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
raise ScoValueError("Adresse invalide") from exc
|
raise ScoInvalidParamError() from exc
|
||||||
elif code_nip:
|
elif code_nip:
|
||||||
args = {"code_nip": code_nip}
|
args = {"code_nip": code_nip}
|
||||||
elif use_request: # use form from current request (Flask global)
|
elif use_request: # use form from current request (Flask global)
|
||||||
|
@ -2,9 +2,21 @@
|
|||||||
|
|
||||||
"""Evenements et logs divers
|
"""Evenements et logs divers
|
||||||
"""
|
"""
|
||||||
|
import datetime
|
||||||
|
import re
|
||||||
|
|
||||||
|
from flask import g, url_for
|
||||||
|
from flask_login import current_user
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
|
from app import email
|
||||||
|
from app import log
|
||||||
|
from app.auth.models import User
|
||||||
from app.models import SHORT_STR_LEN
|
from app.models import SHORT_STR_LEN
|
||||||
|
from app.models.formsemestre import FormSemestre
|
||||||
|
from app.models.moduleimpls import ModuleImpl
|
||||||
|
import app.scodoc.sco_utils as scu
|
||||||
|
from app.scodoc import sco_preferences
|
||||||
|
|
||||||
|
|
||||||
class Scolog(db.Model):
|
class Scolog(db.Model):
|
||||||
@ -24,13 +36,213 @@ class Scolog(db.Model):
|
|||||||
class ScolarNews(db.Model):
|
class ScolarNews(db.Model):
|
||||||
"""Nouvelles pour page d'accueil"""
|
"""Nouvelles pour page d'accueil"""
|
||||||
|
|
||||||
|
NEWS_INSCR = "INSCR" # inscription d'étudiants (object=None ou formsemestre_id)
|
||||||
|
NEWS_NOTE = "NOTES" # saisie note (object=moduleimpl_id)
|
||||||
|
NEWS_FORM = "FORM" # modification formation (object=formation_id)
|
||||||
|
NEWS_SEM = "SEM" # creation semestre (object=None)
|
||||||
|
NEWS_ABS = "ABS" # saisie absence
|
||||||
|
NEWS_MISC = "MISC" # unused
|
||||||
|
NEWS_MAP = {
|
||||||
|
NEWS_INSCR: "inscription d'étudiants",
|
||||||
|
NEWS_NOTE: "saisie note",
|
||||||
|
NEWS_FORM: "modification formation",
|
||||||
|
NEWS_SEM: "création semestre",
|
||||||
|
NEWS_MISC: "opération", # unused
|
||||||
|
}
|
||||||
|
NEWS_TYPES = list(NEWS_MAP.keys())
|
||||||
|
|
||||||
__tablename__ = "scolar_news"
|
__tablename__ = "scolar_news"
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
||||||
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
date = db.Column(
|
||||||
authenticated_user = db.Column(db.Text) # login, sans contrainte
|
db.DateTime(timezone=True), server_default=db.func.now(), index=True
|
||||||
|
)
|
||||||
|
authenticated_user = db.Column(db.Text, index=True) # login, sans contrainte
|
||||||
# type in 'INSCR', 'NOTES', 'FORM', 'SEM', 'MISC'
|
# type in 'INSCR', 'NOTES', 'FORM', 'SEM', 'MISC'
|
||||||
type = db.Column(db.String(SHORT_STR_LEN))
|
type = db.Column(db.String(SHORT_STR_LEN), index=True)
|
||||||
object = db.Column(db.Integer) # moduleimpl_id, formation_id, formsemestre_id
|
object = db.Column(
|
||||||
|
db.Integer, index=True
|
||||||
|
) # moduleimpl_id, formation_id, formsemestre_id
|
||||||
text = db.Column(db.Text)
|
text = db.Column(db.Text)
|
||||||
url = db.Column(db.Text)
|
url = db.Column(db.Text)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return (
|
||||||
|
f"<{self.__class__.__name__}(id={self.id}, date='{self.date.isoformat()}')>"
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"'Chargement notes dans Stage (S3 FI) par Aurélie Dupont'"
|
||||||
|
formsemestre = self.get_news_formsemestre()
|
||||||
|
user = User.query.filter_by(user_name=self.authenticated_user).first()
|
||||||
|
|
||||||
|
sem_text = (
|
||||||
|
f"""(<a href="{url_for('notes.formsemestre_status', scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)
|
||||||
|
}">{formsemestre.sem_modalite()}</a>)"""
|
||||||
|
if formsemestre
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
author = f"par {user.get_nomcomplet()}" if user else ""
|
||||||
|
return f"{self.text} {sem_text} {author}"
|
||||||
|
|
||||||
|
def formatted_date(self) -> str:
|
||||||
|
"06 Avr 14h23"
|
||||||
|
mois = scu.MONTH_NAMES_ABBREV[self.date.month - 1]
|
||||||
|
return f"{self.date.day} {mois} {self.date.hour:02d}h{self.date.minute:02d}"
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {
|
||||||
|
"date": {
|
||||||
|
"display": self.date.strftime("%d/%m/%Y %H:%M"),
|
||||||
|
"timestamp": self.date.timestamp(),
|
||||||
|
},
|
||||||
|
"type": self.NEWS_MAP.get(self.type, "?"),
|
||||||
|
"authenticated_user": self.authenticated_user,
|
||||||
|
"text": self.text,
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def last_news(cls, n=1) -> list:
|
||||||
|
"The most recent n news. Returns list of ScolarNews instances."
|
||||||
|
return cls.query.order_by(cls.date.desc()).limit(n).all()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add(cls, typ, obj=None, text="", url=None, max_frequency=0):
|
||||||
|
"""Enregistre une nouvelle
|
||||||
|
Si max_frequency, ne génère pas 2 nouvelles "identiques"
|
||||||
|
à moins de max_frequency secondes d'intervalle.
|
||||||
|
Deux nouvelles sont considérées comme "identiques" si elles ont
|
||||||
|
même (obj, typ, user).
|
||||||
|
La nouvelle enregistrée est aussi envoyée par mail.
|
||||||
|
"""
|
||||||
|
if max_frequency:
|
||||||
|
last_news = (
|
||||||
|
cls.query.filter_by(
|
||||||
|
dept_id=g.scodoc_dept_id,
|
||||||
|
authenticated_user=current_user.user_name,
|
||||||
|
type=typ,
|
||||||
|
object=obj,
|
||||||
|
)
|
||||||
|
.order_by(cls.date.desc())
|
||||||
|
.limit(1)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
if last_news:
|
||||||
|
now = datetime.datetime.now(tz=last_news.date.tzinfo)
|
||||||
|
if (now - last_news.date) < datetime.timedelta(seconds=max_frequency):
|
||||||
|
# on n'enregistre pas
|
||||||
|
return
|
||||||
|
|
||||||
|
news = ScolarNews(
|
||||||
|
dept_id=g.scodoc_dept_id,
|
||||||
|
authenticated_user=current_user.user_name,
|
||||||
|
type=typ,
|
||||||
|
object=obj,
|
||||||
|
text=text,
|
||||||
|
url=url,
|
||||||
|
)
|
||||||
|
db.session.add(news)
|
||||||
|
db.session.commit()
|
||||||
|
log(f"news: {news}")
|
||||||
|
news.notify_by_mail()
|
||||||
|
|
||||||
|
def get_news_formsemestre(self) -> FormSemestre:
|
||||||
|
"""formsemestre concerné par la nouvelle
|
||||||
|
None si inexistant
|
||||||
|
"""
|
||||||
|
formsemestre_id = None
|
||||||
|
if self.type == self.NEWS_INSCR:
|
||||||
|
formsemestre_id = self.object
|
||||||
|
elif self.type == self.NEWS_NOTE:
|
||||||
|
moduleimpl_id = self.object
|
||||||
|
if moduleimpl_id:
|
||||||
|
modimpl = ModuleImpl.query.get(moduleimpl_id)
|
||||||
|
if modimpl is None:
|
||||||
|
return None # module does not exists anymore
|
||||||
|
formsemestre_id = modimpl.formsemestre_id
|
||||||
|
|
||||||
|
if not formsemestre_id:
|
||||||
|
return None
|
||||||
|
formsemestre = FormSemestre.query.get(formsemestre_id)
|
||||||
|
return formsemestre
|
||||||
|
|
||||||
|
def notify_by_mail(self):
|
||||||
|
"""Notify by email"""
|
||||||
|
formsemestre = self.get_news_formsemestre()
|
||||||
|
|
||||||
|
prefs = sco_preferences.SemPreferences(
|
||||||
|
formsemestre_id=formsemestre.id if formsemestre else None
|
||||||
|
)
|
||||||
|
destinations = prefs["emails_notifications"] or ""
|
||||||
|
destinations = [x.strip() for x in destinations.split(",")]
|
||||||
|
destinations = [x for x in destinations if x]
|
||||||
|
if not destinations:
|
||||||
|
return
|
||||||
|
#
|
||||||
|
txt = self.text
|
||||||
|
if formsemestre:
|
||||||
|
txt += f"""\n\nSemestre {formsemestre.titre_mois()}\n\n"""
|
||||||
|
txt += f"""<a href="{url_for("notes.formsemestre_status", _external=True,
|
||||||
|
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)
|
||||||
|
}">{formsemestre.sem_modalite()}</a>
|
||||||
|
"""
|
||||||
|
user = User.query.filter_by(user_name=self.authenticated_user).first()
|
||||||
|
if user:
|
||||||
|
txt += f"\n\nEffectué par: {user.get_nomcomplet()}\n"
|
||||||
|
|
||||||
|
txt = (
|
||||||
|
"\n"
|
||||||
|
+ txt
|
||||||
|
+ """\n
|
||||||
|
--- Ceci est un message de notification automatique issu de ScoDoc
|
||||||
|
--- vous recevez ce message car votre adresse est indiquée dans les paramètres de ScoDoc.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
# Transforme les URL en URL absolues
|
||||||
|
base = scu.ScoURL()
|
||||||
|
txt = re.sub('href=/.*?"', 'href="' + base + "/", txt)
|
||||||
|
|
||||||
|
# Transforme les liens HTML en texte brut: '<a href="url">texte</a>' devient 'texte: url'
|
||||||
|
# (si on veut des messages non html)
|
||||||
|
txt = re.sub(r'<a.*?href\s*=\s*"(.*?)".*?>(.*?)</a>', r"\2: \1", txt)
|
||||||
|
|
||||||
|
subject = "[ScoDoc] " + self.NEWS_MAP.get(self.type, "?")
|
||||||
|
sender = prefs["email_from_addr"]
|
||||||
|
|
||||||
|
email.send_email(subject, sender, destinations, txt)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def scolar_news_summary_html(cls, n=5) -> str:
|
||||||
|
"""News summary, formated in HTML"""
|
||||||
|
news_list = cls.last_news(n=n)
|
||||||
|
if not news_list:
|
||||||
|
return ""
|
||||||
|
H = [
|
||||||
|
f"""<div class="news"><span class="newstitle"><a href="{
|
||||||
|
url_for("scolar.dept_news", scodoc_dept=g.scodoc_dept)
|
||||||
|
}">Dernières opérations</a>
|
||||||
|
</span><ul class="newslist">"""
|
||||||
|
]
|
||||||
|
|
||||||
|
for news in news_list:
|
||||||
|
H.append(
|
||||||
|
f"""<li class="newslist"><span class="newsdate">{news.formatted_date()}</span><span
|
||||||
|
class="newstext">{news}</span></li>"""
|
||||||
|
)
|
||||||
|
|
||||||
|
H.append("</ul>")
|
||||||
|
|
||||||
|
# Informations générales
|
||||||
|
H.append(
|
||||||
|
f"""<div>
|
||||||
|
Pour être informé des évolutions de ScoDoc,
|
||||||
|
vous pouvez vous
|
||||||
|
<a class="stdlink" href="{scu.SCO_ANNONCES_WEBSITE}">
|
||||||
|
abonner à la liste de diffusion</a>.
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
H.append("</div>")
|
||||||
|
return "\n".join(H)
|
||||||
|
@ -374,6 +374,16 @@ class FormSemestre(db.Model):
|
|||||||
return self.titre
|
return self.titre
|
||||||
return f"{self.titre} {self.formation.get_parcours().SESSION_NAME} {self.semestre_id}"
|
return f"{self.titre} {self.formation.get_parcours().SESSION_NAME} {self.semestre_id}"
|
||||||
|
|
||||||
|
def sem_modalite(self) -> str:
|
||||||
|
"""Le semestre et la modialité, ex "S2 FI" ou "S3 APP" """
|
||||||
|
if self.semestre_id > 0:
|
||||||
|
descr_sem = f"S{self.semestre_id}"
|
||||||
|
else:
|
||||||
|
descr_sem = ""
|
||||||
|
if self.modalite:
|
||||||
|
descr_sem += " " + self.modalite
|
||||||
|
return descr_sem
|
||||||
|
|
||||||
def get_abs_count(self, etudid):
|
def get_abs_count(self, etudid):
|
||||||
"""Les comptes d'absences de cet étudiant dans ce semestre:
|
"""Les comptes d'absences de cet étudiant dans ce semestre:
|
||||||
tuple (nb abs, nb abs justifiées)
|
tuple (nb abs, nb abs justifiées)
|
||||||
|
@ -32,6 +32,7 @@ from flask import g, request
|
|||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
import app
|
import app
|
||||||
|
from app.models import ScolarNews
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
@ -40,9 +41,7 @@ import app.scodoc.notesdb as ndb
|
|||||||
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_modalites
|
from app.scodoc import sco_modalites
|
||||||
from app.scodoc import sco_news
|
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc import sco_up_to_date
|
|
||||||
from app.scodoc import sco_users
|
from app.scodoc import sco_users
|
||||||
|
|
||||||
|
|
||||||
@ -53,7 +52,7 @@ def index_html(showcodes=0, showsemtable=0):
|
|||||||
H = []
|
H = []
|
||||||
|
|
||||||
# News:
|
# News:
|
||||||
H.append(sco_news.scolar_news_summary_html())
|
H.append(ScolarNews.scolar_news_summary_html())
|
||||||
|
|
||||||
# Avertissement de mise à jour:
|
# Avertissement de mise à jour:
|
||||||
H.append("""<div id="update_warning"></div>""")
|
H.append("""<div id="update_warning"></div>""")
|
||||||
|
@ -37,6 +37,7 @@ from app.models import SHORT_STR_LEN
|
|||||||
from app.models.formations import Formation
|
from app.models.formations import Formation
|
||||||
from app.models.modules import Module
|
from app.models.modules import Module
|
||||||
from app.models.ues import UniteEns
|
from app.models.ues import UniteEns
|
||||||
|
from app.models import ScolarNews
|
||||||
|
|
||||||
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
|
||||||
@ -44,13 +45,10 @@ 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_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
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_news
|
|
||||||
|
|
||||||
|
|
||||||
def formation_delete(formation_id=None, dialog_confirmed=False):
|
def formation_delete(formation_id=None, dialog_confirmed=False):
|
||||||
@ -117,11 +115,10 @@ def do_formation_delete(oid):
|
|||||||
sco_formations._formationEditor.delete(cnx, oid)
|
sco_formations._formationEditor.delete(cnx, oid)
|
||||||
|
|
||||||
# news
|
# news
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_FORM,
|
typ=ScolarNews.NEWS_FORM,
|
||||||
object=oid,
|
obj=oid,
|
||||||
text="Suppression de la formation %(acronyme)s" % F,
|
text=f"Suppression de la formation {F['acronyme']}",
|
||||||
max_frequency=3,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -281,10 +278,9 @@ def do_formation_create(args):
|
|||||||
#
|
#
|
||||||
r = sco_formations._formationEditor.create(cnx, args)
|
r = sco_formations._formationEditor.create(cnx, args)
|
||||||
|
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_FORM,
|
typ=ScolarNews.NEWS_FORM,
|
||||||
text="Création de la formation %(titre)s (%(acronyme)s)" % args,
|
text="Création de la formation %(titre)s (%(acronyme)s)" % args,
|
||||||
max_frequency=3,
|
|
||||||
)
|
)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
"""
|
"""
|
||||||
import flask
|
import flask
|
||||||
from flask import g, url_for, request
|
from flask import g, url_for, request
|
||||||
|
from app.models.events import ScolarNews
|
||||||
from app.models.formations import Matiere
|
from app.models.formations import Matiere
|
||||||
|
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
@ -78,8 +79,7 @@ def do_matiere_edit(*args, **kw):
|
|||||||
def do_matiere_create(args):
|
def do_matiere_create(args):
|
||||||
"create a matiere"
|
"create a matiere"
|
||||||
from app.scodoc import sco_edit_ue
|
from app.scodoc import sco_edit_ue
|
||||||
from app.scodoc import sco_formations
|
from app.models import ScolarNews
|
||||||
from app.scodoc import sco_news
|
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
# check
|
# check
|
||||||
@ -89,11 +89,11 @@ def do_matiere_create(args):
|
|||||||
|
|
||||||
# news
|
# news
|
||||||
formation = Formation.query.get(ue["formation_id"])
|
formation = Formation.query.get(ue["formation_id"])
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_FORM,
|
typ=ScolarNews.NEWS_FORM,
|
||||||
object=ue["formation_id"],
|
obj=ue["formation_id"],
|
||||||
text=f"Modification de la formation {formation.acronyme}",
|
text=f"Modification de la formation {formation.acronyme}",
|
||||||
max_frequency=3,
|
max_frequency=10 * 60,
|
||||||
)
|
)
|
||||||
formation.invalidate_cached_sems()
|
formation.invalidate_cached_sems()
|
||||||
return r
|
return r
|
||||||
@ -174,10 +174,8 @@ def can_delete_matiere(matiere: Matiere) -> tuple[bool, str]:
|
|||||||
|
|
||||||
def do_matiere_delete(oid):
|
def do_matiere_delete(oid):
|
||||||
"delete matiere and attached modules"
|
"delete matiere and attached modules"
|
||||||
from app.scodoc import sco_formations
|
|
||||||
from app.scodoc import sco_edit_ue
|
from app.scodoc import sco_edit_ue
|
||||||
from app.scodoc import sco_edit_module
|
from app.scodoc import sco_edit_module
|
||||||
from app.scodoc import sco_news
|
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
# check
|
# check
|
||||||
@ -197,11 +195,11 @@ def do_matiere_delete(oid):
|
|||||||
|
|
||||||
# news
|
# news
|
||||||
formation = Formation.query.get(ue["formation_id"])
|
formation = Formation.query.get(ue["formation_id"])
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_FORM,
|
typ=ScolarNews.NEWS_FORM,
|
||||||
object=ue["formation_id"],
|
obj=ue["formation_id"],
|
||||||
text=f"Modification de la formation {formation.acronyme}",
|
text=f"Modification de la formation {formation.acronyme}",
|
||||||
max_frequency=3,
|
max_frequency=10 * 60,
|
||||||
)
|
)
|
||||||
formation.invalidate_cached_sems()
|
formation.invalidate_cached_sems()
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ from app import models
|
|||||||
from app.models import APO_CODE_STR_LEN
|
from app.models import APO_CODE_STR_LEN
|
||||||
from app.models import Formation, Matiere, Module, UniteEns
|
from app.models import Formation, Matiere, Module, UniteEns
|
||||||
from app.models import FormSemestre, ModuleImpl
|
from app.models import FormSemestre, ModuleImpl
|
||||||
|
from app.models import ScolarNews
|
||||||
|
|
||||||
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
|
||||||
@ -53,7 +54,6 @@ 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_edit_matiere
|
from app.scodoc import sco_edit_matiere
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
from app.scodoc import sco_news
|
|
||||||
|
|
||||||
_moduleEditor = ndb.EditableTable(
|
_moduleEditor = ndb.EditableTable(
|
||||||
"notes_modules",
|
"notes_modules",
|
||||||
@ -98,18 +98,16 @@ def module_list(*args, **kw):
|
|||||||
def do_module_create(args) -> int:
|
def do_module_create(args) -> int:
|
||||||
"Create a module. Returns id of new object."
|
"Create a module. Returns id of new object."
|
||||||
# create
|
# create
|
||||||
from app.scodoc import sco_formations
|
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
r = _moduleEditor.create(cnx, args)
|
r = _moduleEditor.create(cnx, args)
|
||||||
|
|
||||||
# news
|
# news
|
||||||
formation = Formation.query.get(args["formation_id"])
|
formation = Formation.query.get(args["formation_id"])
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_FORM,
|
typ=ScolarNews.NEWS_FORM,
|
||||||
object=formation.id,
|
obj=formation.id,
|
||||||
text=f"Modification de la formation {formation.acronyme}",
|
text=f"Modification de la formation {formation.acronyme}",
|
||||||
max_frequency=3,
|
max_frequency=10 * 60,
|
||||||
)
|
)
|
||||||
formation.invalidate_cached_sems()
|
formation.invalidate_cached_sems()
|
||||||
return r
|
return r
|
||||||
@ -396,11 +394,11 @@ def do_module_delete(oid):
|
|||||||
|
|
||||||
# news
|
# news
|
||||||
formation = module.formation
|
formation = module.formation
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_FORM,
|
typ=ScolarNews.NEWS_FORM,
|
||||||
object=mod["formation_id"],
|
obj=mod["formation_id"],
|
||||||
text=f"Modification de la formation {formation.acronyme}",
|
text=f"Modification de la formation {formation.acronyme}",
|
||||||
max_frequency=3,
|
max_frequency=10 * 60,
|
||||||
)
|
)
|
||||||
formation.invalidate_cached_sems()
|
formation.invalidate_cached_sems()
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ from app import db
|
|||||||
from app import log
|
from app import log
|
||||||
from app.models import APO_CODE_STR_LEN, SHORT_STR_LEN
|
from app.models import APO_CODE_STR_LEN, SHORT_STR_LEN
|
||||||
from app.models import Formation, UniteEns, ModuleImpl, Module
|
from app.models import Formation, UniteEns, ModuleImpl, Module
|
||||||
|
from app.models import ScolarNews
|
||||||
from app.models.formations import Matiere
|
from app.models.formations import Matiere
|
||||||
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
|
||||||
@ -55,15 +56,11 @@ from app.scodoc import html_sco_header
|
|||||||
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_edit_apc
|
from app.scodoc import sco_edit_apc
|
||||||
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
|
||||||
from app.scodoc import sco_news
|
|
||||||
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
|
||||||
|
|
||||||
@ -138,11 +135,11 @@ def do_ue_create(args):
|
|||||||
ue = UniteEns.query.get(ue_id)
|
ue = UniteEns.query.get(ue_id)
|
||||||
flash(f"UE créée (code {ue.ue_code})")
|
flash(f"UE créée (code {ue.ue_code})")
|
||||||
formation = Formation.query.get(args["formation_id"])
|
formation = Formation.query.get(args["formation_id"])
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_FORM,
|
typ=ScolarNews.NEWS_FORM,
|
||||||
object=args["formation_id"],
|
obj=args["formation_id"],
|
||||||
text=f"Modification de la formation {formation.acronyme}",
|
text=f"Modification de la formation {formation.acronyme}",
|
||||||
max_frequency=3,
|
max_frequency=10 * 60,
|
||||||
)
|
)
|
||||||
formation.invalidate_cached_sems()
|
formation.invalidate_cached_sems()
|
||||||
return ue_id
|
return ue_id
|
||||||
@ -222,11 +219,11 @@ def do_ue_delete(ue_id, delete_validations=False, force=False):
|
|||||||
sco_cache.invalidate_formsemestre()
|
sco_cache.invalidate_formsemestre()
|
||||||
# news
|
# news
|
||||||
F = sco_formations.formation_list(args={"formation_id": ue.formation_id})[0]
|
F = sco_formations.formation_list(args={"formation_id": ue.formation_id})[0]
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_FORM,
|
typ=ScolarNews.NEWS_FORM,
|
||||||
object=ue.formation_id,
|
obj=ue.formation_id,
|
||||||
text="Modification de la formation %(acronyme)s" % F,
|
text="Modification de la formation %(acronyme)s" % F,
|
||||||
max_frequency=3,
|
max_frequency=10 * 60,
|
||||||
)
|
)
|
||||||
#
|
#
|
||||||
if not force:
|
if not force:
|
||||||
|
@ -637,7 +637,7 @@ def create_etud(cnx, args={}):
|
|||||||
Returns:
|
Returns:
|
||||||
etud, l'étudiant créé.
|
etud, l'étudiant créé.
|
||||||
"""
|
"""
|
||||||
from app.scodoc import sco_news
|
from app.models import ScolarNews
|
||||||
|
|
||||||
# creation d'un etudiant
|
# creation d'un etudiant
|
||||||
etudid = etudident_create(cnx, args)
|
etudid = etudident_create(cnx, args)
|
||||||
@ -671,9 +671,8 @@ def create_etud(cnx, args={}):
|
|||||||
etud = etudident_list(cnx, {"etudid": etudid})[0]
|
etud = etudident_list(cnx, {"etudid": etudid})[0]
|
||||||
fill_etuds_info([etud])
|
fill_etuds_info([etud])
|
||||||
etud["url"] = url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
etud["url"] = url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_INSCR,
|
typ=ScolarNews.NEWS_INSCR,
|
||||||
object=None, # pas d'object pour ne montrer qu'un etudiant
|
|
||||||
text='Nouvel étudiant <a href="%(url)s">%(nomprenom)s</a>' % etud,
|
text='Nouvel étudiant <a href="%(url)s">%(nomprenom)s</a>' % etud,
|
||||||
url=etud["url"],
|
url=etud["url"],
|
||||||
)
|
)
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
"""Gestion evaluations (ScoDoc7, sans SQlAlchemy)
|
"""Gestion evaluations (ScoDoc7, sans SQlAlchemy)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import datetime
|
|
||||||
import pprint
|
import pprint
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
@ -37,6 +36,7 @@ from flask_login import current_user
|
|||||||
|
|
||||||
from app import log
|
from app import log
|
||||||
|
|
||||||
|
from app.models import ScolarNews
|
||||||
from app.models.evaluations import evaluation_enrich_dict, check_evaluation_args
|
from app.models.evaluations import evaluation_enrich_dict, check_evaluation_args
|
||||||
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
|
||||||
@ -44,9 +44,7 @@ from app.scodoc.sco_exceptions import AccessDenied, ScoValueError
|
|||||||
|
|
||||||
from app.scodoc import sco_cache
|
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_formsemestre
|
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
from app.scodoc import sco_news
|
|
||||||
from app.scodoc import sco_permissions_check
|
from app.scodoc import sco_permissions_check
|
||||||
|
|
||||||
|
|
||||||
@ -179,9 +177,9 @@ def do_evaluation_create(
|
|||||||
mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0]
|
mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0]
|
||||||
mod["moduleimpl_id"] = M["moduleimpl_id"]
|
mod["moduleimpl_id"] = M["moduleimpl_id"]
|
||||||
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
|
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_NOTE,
|
typ=ScolarNews.NEWS_NOTE,
|
||||||
object=moduleimpl_id,
|
obj=moduleimpl_id,
|
||||||
text='Création d\'une évaluation dans <a href="%(url)s">%(titre)s</a>' % mod,
|
text='Création d\'une évaluation dans <a href="%(url)s">%(titre)s</a>' % mod,
|
||||||
url=mod["url"],
|
url=mod["url"],
|
||||||
)
|
)
|
||||||
@ -240,9 +238,9 @@ def do_evaluation_delete(evaluation_id):
|
|||||||
mod["url"] = (
|
mod["url"] = (
|
||||||
scu.NotesURL() + "/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
|
scu.NotesURL() + "/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
|
||||||
)
|
)
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_NOTE,
|
typ=ScolarNews.NEWS_NOTE,
|
||||||
object=moduleimpl_id,
|
obj=moduleimpl_id,
|
||||||
text='Suppression d\'une évaluation dans <a href="%(url)s">%(titre)s</a>' % mod,
|
text='Suppression d\'une évaluation dans <a href="%(url)s">%(titre)s</a>' % mod,
|
||||||
url=mod["url"],
|
url=mod["url"],
|
||||||
)
|
)
|
||||||
|
@ -53,7 +53,11 @@ def evaluations_recap(formsemestre_id: int) -> str:
|
|||||||
for row in rows:
|
for row in rows:
|
||||||
H.append(f"{scu.gen_row(column_ids, row, with_col_classes=True)}\n")
|
H.append(f"{scu.gen_row(column_ids, row, with_col_classes=True)}\n")
|
||||||
|
|
||||||
H.append("""</tbody></table></div>""")
|
H.append(
|
||||||
|
"""</tbody></table></div>
|
||||||
|
<div class="help">Les étudiants démissionnaires ou défaillants ne sont pas pris en compte dans cette table.</div>
|
||||||
|
"""
|
||||||
|
)
|
||||||
H.append(
|
H.append(
|
||||||
html_sco_header.sco_footer(),
|
html_sco_header.sco_footer(),
|
||||||
)
|
)
|
||||||
|
@ -36,32 +36,27 @@ from flask import g
|
|||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from app import log
|
|
||||||
|
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
from app.models import FormSemestre
|
from app.models import FormSemestre
|
||||||
|
from app.models import ScolarNews
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc.sco_utils import ModuleType
|
from app.scodoc.sco_utils import ModuleType
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc.sco_exceptions import AccessDenied, ScoValueError
|
|
||||||
import sco_version
|
|
||||||
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_evaluation_db
|
from app.scodoc import sco_evaluation_db
|
||||||
from app.scodoc import sco_abs
|
from app.scodoc import sco_abs
|
||||||
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_inscriptions
|
from app.scodoc import sco_formsemestre_inscriptions
|
||||||
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_news
|
|
||||||
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_users
|
from app.scodoc import sco_users
|
||||||
|
import sco_version
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
@ -633,7 +628,9 @@ def evaluation_describe(evaluation_id="", edit_in_place=True):
|
|||||||
'<span class="evallink"><a class="stdlink" href="evaluation_listenotes?moduleimpl_id=%s">voir toutes les notes du module</a></span>'
|
'<span class="evallink"><a class="stdlink" href="evaluation_listenotes?moduleimpl_id=%s">voir toutes les notes du module</a></span>'
|
||||||
% moduleimpl_id
|
% moduleimpl_id
|
||||||
)
|
)
|
||||||
mod_descr = '<a href="moduleimpl_status?moduleimpl_id=%s">%s %s</a> <span class="resp">(resp. <a title="%s">%s</a>)</span> %s' % (
|
mod_descr = (
|
||||||
|
'<a href="moduleimpl_status?moduleimpl_id=%s">%s %s</a> <span class="resp">(resp. <a title="%s">%s</a>)</span> %s'
|
||||||
|
% (
|
||||||
moduleimpl_id,
|
moduleimpl_id,
|
||||||
Mod["code"] or "",
|
Mod["code"] or "",
|
||||||
Mod["titre"] or "?",
|
Mod["titre"] or "?",
|
||||||
@ -641,6 +638,7 @@ def evaluation_describe(evaluation_id="", edit_in_place=True):
|
|||||||
resp,
|
resp,
|
||||||
link,
|
link,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
etit = E["description"] or ""
|
etit = E["description"] or ""
|
||||||
if etit:
|
if etit:
|
||||||
|
@ -63,6 +63,17 @@ class ScoFormatError(ScoValueError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ScoInvalidParamError(ScoValueError):
|
||||||
|
"""Paramètres requete invalides.
|
||||||
|
A utilisée lorsqu'une route est appelée avec des paramètres invalides
|
||||||
|
(id strings, ...)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, msg=None, dest_url=None):
|
||||||
|
msg = msg or "Adresse invalide. Vérifiez vos signets."
|
||||||
|
super().__init__(msg, dest_url=dest_url)
|
||||||
|
|
||||||
|
|
||||||
class ScoPDFFormatError(ScoValueError):
|
class ScoPDFFormatError(ScoValueError):
|
||||||
"erreur génération PDF (templates platypus, ...)"
|
"erreur génération PDF (templates platypus, ...)"
|
||||||
|
|
||||||
|
@ -39,12 +39,12 @@ import app.scodoc.notesdb as ndb
|
|||||||
from app import db
|
from app import db
|
||||||
from app import log
|
from app import log
|
||||||
from app.models import Formation, Module
|
from app.models import Formation, Module
|
||||||
|
from app.models import ScolarNews
|
||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
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
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_news
|
|
||||||
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_xml
|
from app.scodoc import sco_xml
|
||||||
@ -351,11 +351,14 @@ def formation_list_table(formation_id=None, args={}):
|
|||||||
else:
|
else:
|
||||||
but_locked = '<span class="but_placeholder"></span>'
|
but_locked = '<span class="but_placeholder"></span>'
|
||||||
if editable and not locked:
|
if editable and not locked:
|
||||||
but_suppr = '<a class="stdlink" href="formation_delete?formation_id=%s" id="delete-formation-%s">%s</a>' % (
|
but_suppr = (
|
||||||
|
'<a class="stdlink" href="formation_delete?formation_id=%s" id="delete-formation-%s">%s</a>'
|
||||||
|
% (
|
||||||
f["formation_id"],
|
f["formation_id"],
|
||||||
f["acronyme"].lower().replace(" ", "-"),
|
f["acronyme"].lower().replace(" ", "-"),
|
||||||
suppricon,
|
suppricon,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
but_suppr = '<span class="but_placeholder"></span>'
|
but_suppr = '<span class="but_placeholder"></span>'
|
||||||
if editable:
|
if editable:
|
||||||
@ -422,9 +425,9 @@ def formation_create_new_version(formation_id, redirect=True):
|
|||||||
new_id, modules_old2new, ues_old2new = formation_import_xml(xml_data)
|
new_id, modules_old2new, ues_old2new = formation_import_xml(xml_data)
|
||||||
# news
|
# news
|
||||||
F = formation_list(args={"formation_id": new_id})[0]
|
F = formation_list(args={"formation_id": new_id})[0]
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_FORM,
|
typ=ScolarNews.NEWS_FORM,
|
||||||
object=new_id,
|
obj=new_id,
|
||||||
text="Nouvelle version de la formation %(acronyme)s" % F,
|
text="Nouvelle version de la formation %(acronyme)s" % F,
|
||||||
)
|
)
|
||||||
if redirect:
|
if redirect:
|
||||||
|
@ -229,7 +229,7 @@ def etapes_apo_str(etapes):
|
|||||||
def do_formsemestre_create(args, silent=False):
|
def do_formsemestre_create(args, silent=False):
|
||||||
"create a formsemestre"
|
"create a formsemestre"
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_news
|
from app.models import ScolarNews
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
formsemestre_id = _formsemestreEditor.create(cnx, args)
|
formsemestre_id = _formsemestreEditor.create(cnx, args)
|
||||||
@ -254,8 +254,8 @@ def do_formsemestre_create(args, silent=False):
|
|||||||
args["formsemestre_id"] = formsemestre_id
|
args["formsemestre_id"] = formsemestre_id
|
||||||
args["url"] = "Notes/formsemestre_status?formsemestre_id=%(formsemestre_id)s" % args
|
args["url"] = "Notes/formsemestre_status?formsemestre_id=%(formsemestre_id)s" % args
|
||||||
if not silent:
|
if not silent:
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_SEM,
|
typ=ScolarNews.NEWS_SEM,
|
||||||
text='Création du semestre <a href="%(url)s">%(titre)s</a>' % args,
|
text='Création du semestre <a href="%(url)s">%(titre)s</a>' % args,
|
||||||
url=args["url"],
|
url=args["url"],
|
||||||
)
|
)
|
||||||
|
@ -36,6 +36,7 @@ from app import db
|
|||||||
from app.auth.models import User
|
from app.auth.models import User
|
||||||
from app.models import APO_CODE_STR_LEN, SHORT_STR_LEN
|
from app.models import APO_CODE_STR_LEN, SHORT_STR_LEN
|
||||||
from app.models import Module, ModuleImpl, Evaluation, EvaluationUEPoids, UniteEns
|
from app.models import Module, ModuleImpl, Evaluation, EvaluationUEPoids, UniteEns
|
||||||
|
from app.models import ScolarNews
|
||||||
from app.models.formations import Formation
|
from app.models.formations import Formation
|
||||||
from app.models.formsemestre import FormSemestre
|
from app.models.formsemestre import FormSemestre
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
@ -191,7 +192,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
modimpl.responsable_id,
|
modimpl.responsable_id,
|
||||||
f"inconnu numéro {modimpl.responsable_id} resp. de {modimpl.id} !",
|
f"inconnu numéro {modimpl.responsable_id} resp. de {modimpl.id} !",
|
||||||
)
|
)
|
||||||
|
if sem["responsables"]:
|
||||||
initvalues["responsable_id"] = uid2display.get(
|
initvalues["responsable_id"] = uid2display.get(
|
||||||
sem["responsables"][0], sem["responsables"][0]
|
sem["responsables"][0], sem["responsables"][0]
|
||||||
)
|
)
|
||||||
@ -1493,11 +1494,9 @@ def do_formsemestre_delete(formsemestre_id):
|
|||||||
sco_formsemestre._formsemestreEditor.delete(cnx, formsemestre_id)
|
sco_formsemestre._formsemestreEditor.delete(cnx, formsemestre_id)
|
||||||
|
|
||||||
# news
|
# news
|
||||||
from app.scodoc import sco_news
|
ScolarNews.add(
|
||||||
|
typ=ScolarNews.NEWS_SEM,
|
||||||
sco_news.add(
|
obj=formsemestre_id,
|
||||||
typ=sco_news.NEWS_SEM,
|
|
||||||
object=formsemestre_id,
|
|
||||||
text="Suppression du semestre %(titre)s" % sem,
|
text="Suppression du semestre %(titre)s" % sem,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1186,6 +1186,7 @@ def formsemestre_tableau_modules(
|
|||||||
H.append("<td>")
|
H.append("<td>")
|
||||||
if mod.module_type in (ModuleType.RESSOURCE, ModuleType.SAE):
|
if mod.module_type in (ModuleType.RESSOURCE, ModuleType.SAE):
|
||||||
coefs = mod.ue_coefs_list()
|
coefs = mod.ue_coefs_list()
|
||||||
|
H.append(f'<a class="invisible_link" href="#" title="{mod_descr}">')
|
||||||
for coef in coefs:
|
for coef in coefs:
|
||||||
if coef[1] > 0:
|
if coef[1] > 0:
|
||||||
H.append(
|
H.append(
|
||||||
@ -1197,6 +1198,7 @@ def formsemestre_tableau_modules(
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
H.append(f"""<span class="mod_coef_indicator_zero"></span>""")
|
H.append(f"""<span class="mod_coef_indicator_zero"></span>""")
|
||||||
|
H.append("</a>")
|
||||||
H.append("</td>")
|
H.append("</td>")
|
||||||
if mod.module_type in (
|
if mod.module_type in (
|
||||||
None, # ne devrait pas être nécessaire car la migration a remplacé les NULLs
|
None, # ne devrait pas être nécessaire car la migration a remplacé les NULLs
|
||||||
|
@ -40,6 +40,8 @@ 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 import log
|
from app import log
|
||||||
|
from app.models import ScolarNews
|
||||||
|
|
||||||
from app.scodoc.sco_excel import COLORS
|
from app.scodoc.sco_excel import COLORS
|
||||||
from app.scodoc.sco_formsemestre_inscriptions import (
|
from app.scodoc.sco_formsemestre_inscriptions import (
|
||||||
do_formsemestre_inscription_with_modules,
|
do_formsemestre_inscription_with_modules,
|
||||||
@ -54,14 +56,13 @@ from app.scodoc.sco_exceptions import (
|
|||||||
ScoLockedFormError,
|
ScoLockedFormError,
|
||||||
ScoGenError,
|
ScoGenError,
|
||||||
)
|
)
|
||||||
|
|
||||||
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_cache
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_formsemestre
|
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_excel
|
from app.scodoc import sco_excel
|
||||||
from app.scodoc import sco_groups_view
|
from app.scodoc import sco_groups_view
|
||||||
from app.scodoc import sco_news
|
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
|
|
||||||
# format description (in tools/)
|
# format description (in tools/)
|
||||||
@ -472,11 +473,11 @@ def scolars_import_excel_file(
|
|||||||
|
|
||||||
diag.append("Import et inscription de %s étudiants" % len(created_etudids))
|
diag.append("Import et inscription de %s étudiants" % len(created_etudids))
|
||||||
|
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_INSCR,
|
typ=ScolarNews.NEWS_INSCR,
|
||||||
text="Inscription de %d étudiants" # peuvent avoir ete inscrits a des semestres differents
|
text="Inscription de %d étudiants" # peuvent avoir ete inscrits a des semestres differents
|
||||||
% len(created_etudids),
|
% len(created_etudids),
|
||||||
object=formsemestre_id,
|
obj=formsemestre_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
log("scolars_import_excel_file: completing transaction")
|
log("scolars_import_excel_file: completing transaction")
|
||||||
|
@ -1,276 +0,0 @@
|
|||||||
# -*- mode: python -*-
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Gestion scolarite IUT
|
|
||||||
#
|
|
||||||
# Copyright (c) 1999 - 2022 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 des "nouvelles"
|
|
||||||
"""
|
|
||||||
import re
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
from operator import itemgetter
|
|
||||||
|
|
||||||
from flask import g
|
|
||||||
from flask_login import current_user
|
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
|
||||||
import app.scodoc.notesdb as ndb
|
|
||||||
from app import log
|
|
||||||
from app.scodoc import sco_formsemestre
|
|
||||||
from app.scodoc import sco_moduleimpl
|
|
||||||
from app.scodoc import sco_preferences
|
|
||||||
from app import email
|
|
||||||
|
|
||||||
|
|
||||||
_scolar_news_editor = ndb.EditableTable(
|
|
||||||
"scolar_news",
|
|
||||||
"news_id",
|
|
||||||
("date", "authenticated_user", "type", "object", "text", "url"),
|
|
||||||
filter_dept=True,
|
|
||||||
sortkey="date desc",
|
|
||||||
output_formators={"date": ndb.DateISOtoDMY},
|
|
||||||
input_formators={"date": ndb.DateDMYtoISO},
|
|
||||||
html_quote=False, # no user supplied data, needed to store html links
|
|
||||||
)
|
|
||||||
|
|
||||||
NEWS_INSCR = "INSCR" # inscription d'étudiants (object=None ou formsemestre_id)
|
|
||||||
NEWS_NOTE = "NOTES" # saisie note (object=moduleimpl_id)
|
|
||||||
NEWS_FORM = "FORM" # modification formation (object=formation_id)
|
|
||||||
NEWS_SEM = "SEM" # creation semestre (object=None)
|
|
||||||
NEWS_MISC = "MISC" # unused
|
|
||||||
NEWS_MAP = {
|
|
||||||
NEWS_INSCR: "inscription d'étudiants",
|
|
||||||
NEWS_NOTE: "saisie note",
|
|
||||||
NEWS_FORM: "modification formation",
|
|
||||||
NEWS_SEM: "création semestre",
|
|
||||||
NEWS_MISC: "opération", # unused
|
|
||||||
}
|
|
||||||
NEWS_TYPES = list(NEWS_MAP.keys())
|
|
||||||
|
|
||||||
scolar_news_create = _scolar_news_editor.create
|
|
||||||
scolar_news_list = _scolar_news_editor.list
|
|
||||||
|
|
||||||
_LAST_NEWS = {} # { (authuser_name, type, object) : time }
|
|
||||||
|
|
||||||
|
|
||||||
def add(typ, object=None, text="", url=None, max_frequency=False):
|
|
||||||
"""Ajoute une nouvelle.
|
|
||||||
Si max_frequency, ne genere pas 2 nouvelles identiques à moins de max_frequency
|
|
||||||
secondes d'intervalle.
|
|
||||||
"""
|
|
||||||
from app.scodoc import sco_users
|
|
||||||
|
|
||||||
authuser_name = current_user.user_name
|
|
||||||
cnx = ndb.GetDBConnexion()
|
|
||||||
args = {
|
|
||||||
"authenticated_user": authuser_name,
|
|
||||||
"user_info": sco_users.user_info(authuser_name),
|
|
||||||
"type": typ,
|
|
||||||
"object": object,
|
|
||||||
"text": text,
|
|
||||||
"url": url,
|
|
||||||
}
|
|
||||||
t = time.time()
|
|
||||||
if max_frequency:
|
|
||||||
last_news_time = _LAST_NEWS.get((authuser_name, typ, object), False)
|
|
||||||
if last_news_time and (t - last_news_time < max_frequency):
|
|
||||||
# log("not recording")
|
|
||||||
return
|
|
||||||
|
|
||||||
log("news: %s" % args)
|
|
||||||
|
|
||||||
_LAST_NEWS[(authuser_name, typ, object)] = t
|
|
||||||
|
|
||||||
_send_news_by_mail(args)
|
|
||||||
return scolar_news_create(cnx, args)
|
|
||||||
|
|
||||||
|
|
||||||
def scolar_news_summary(n=5):
|
|
||||||
"""Return last n news.
|
|
||||||
News are "compressed", ie redondant events are joined.
|
|
||||||
"""
|
|
||||||
from app.scodoc import sco_etud
|
|
||||||
from app.scodoc import sco_users
|
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
|
||||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
|
||||||
cursor.execute(
|
|
||||||
"""SELECT id AS news_id, *
|
|
||||||
FROM scolar_news
|
|
||||||
WHERE dept_id=%(dept_id)s
|
|
||||||
ORDER BY date DESC LIMIT 100
|
|
||||||
""",
|
|
||||||
{"dept_id": g.scodoc_dept_id},
|
|
||||||
)
|
|
||||||
selected_news = {} # (type,object) : news dict
|
|
||||||
news = cursor.dictfetchall() # la plus récente d'abord
|
|
||||||
|
|
||||||
for r in reversed(news): # la plus ancienne d'abord
|
|
||||||
# si on a deja une news avec meme (type,object)
|
|
||||||
# et du meme jour, on la remplace
|
|
||||||
dmy = ndb.DateISOtoDMY(r["date"]) # round
|
|
||||||
key = (r["type"], r["object"], dmy)
|
|
||||||
selected_news[key] = r
|
|
||||||
|
|
||||||
news = list(selected_news.values())
|
|
||||||
# sort by date, descending
|
|
||||||
news.sort(key=itemgetter("date"), reverse=True)
|
|
||||||
news = news[:n]
|
|
||||||
# mimic EditableTable.list output formatting:
|
|
||||||
for n in news:
|
|
||||||
n["date822"] = n["date"].strftime("%a, %d %b %Y %H:%M:%S %z")
|
|
||||||
# heure
|
|
||||||
n["hm"] = n["date"].strftime("%Hh%M")
|
|
||||||
for k in n.keys():
|
|
||||||
if n[k] is None:
|
|
||||||
n[k] = ""
|
|
||||||
if k in _scolar_news_editor.output_formators:
|
|
||||||
n[k] = _scolar_news_editor.output_formators[k](n[k])
|
|
||||||
# date resumee
|
|
||||||
j, m = n["date"].split("/")[:2]
|
|
||||||
mois = scu.MONTH_NAMES_ABBREV[int(m) - 1]
|
|
||||||
n["formatted_date"] = "%s %s %s" % (j, mois, n["hm"])
|
|
||||||
# indication semestre si ajout notes:
|
|
||||||
infos = _get_formsemestre_infos_from_news(n)
|
|
||||||
if infos:
|
|
||||||
n["text"] += (
|
|
||||||
' (<a href="Notes/formsemestre_status?formsemestre_id=%(formsemestre_id)s">%(descr_sem)s</a>)'
|
|
||||||
% infos
|
|
||||||
)
|
|
||||||
n["text"] += (
|
|
||||||
" par " + sco_users.user_info(n["authenticated_user"])["nomcomplet"]
|
|
||||||
)
|
|
||||||
return news
|
|
||||||
|
|
||||||
|
|
||||||
def _get_formsemestre_infos_from_news(n):
|
|
||||||
"""Informations sur le semestre concerné par la nouvelle n
|
|
||||||
{} si inexistant
|
|
||||||
"""
|
|
||||||
formsemestre_id = None
|
|
||||||
if n["type"] == NEWS_INSCR:
|
|
||||||
formsemestre_id = n["object"]
|
|
||||||
elif n["type"] == NEWS_NOTE:
|
|
||||||
moduleimpl_id = n["object"]
|
|
||||||
if n["object"]:
|
|
||||||
mods = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)
|
|
||||||
if not mods:
|
|
||||||
return {} # module does not exists anymore
|
|
||||||
return {} # pas d'indication du module
|
|
||||||
mod = mods[0]
|
|
||||||
formsemestre_id = mod["formsemestre_id"]
|
|
||||||
|
|
||||||
if not formsemestre_id:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
try:
|
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
|
||||||
except:
|
|
||||||
# semestre n'existe plus
|
|
||||||
return {}
|
|
||||||
|
|
||||||
if sem["semestre_id"] > 0:
|
|
||||||
descr_sem = "S%d" % sem["semestre_id"]
|
|
||||||
else:
|
|
||||||
descr_sem = ""
|
|
||||||
if sem["modalite"]:
|
|
||||||
descr_sem += " " + sem["modalite"]
|
|
||||||
return {"formsemestre_id": formsemestre_id, "sem": sem, "descr_sem": descr_sem}
|
|
||||||
|
|
||||||
|
|
||||||
def scolar_news_summary_html(n=5):
|
|
||||||
"""News summary, formated in HTML"""
|
|
||||||
news = scolar_news_summary(n=n)
|
|
||||||
if not news:
|
|
||||||
return ""
|
|
||||||
H = ['<div class="news"><span class="newstitle">Dernières opérations']
|
|
||||||
H.append('</span><ul class="newslist">')
|
|
||||||
|
|
||||||
for n in news:
|
|
||||||
H.append(
|
|
||||||
'<li class="newslist"><span class="newsdate">%(formatted_date)s</span><span class="newstext">%(text)s</span></li>'
|
|
||||||
% n
|
|
||||||
)
|
|
||||||
H.append("</ul>")
|
|
||||||
|
|
||||||
# Informations générales
|
|
||||||
H.append(
|
|
||||||
"""<div>
|
|
||||||
Pour être informé des évolutions de ScoDoc,
|
|
||||||
vous pouvez vous
|
|
||||||
<a class="stdlink" href="%s">
|
|
||||||
abonner à la liste de diffusion</a>.
|
|
||||||
</div>
|
|
||||||
"""
|
|
||||||
% scu.SCO_ANNONCES_WEBSITE
|
|
||||||
)
|
|
||||||
|
|
||||||
H.append("</div>")
|
|
||||||
return "\n".join(H)
|
|
||||||
|
|
||||||
|
|
||||||
def _send_news_by_mail(n):
|
|
||||||
"""Notify by email"""
|
|
||||||
infos = _get_formsemestre_infos_from_news(n)
|
|
||||||
formsemestre_id = infos.get("formsemestre_id", None)
|
|
||||||
prefs = sco_preferences.SemPreferences(formsemestre_id=formsemestre_id)
|
|
||||||
destinations = prefs["emails_notifications"] or ""
|
|
||||||
destinations = [x.strip() for x in destinations.split(",")]
|
|
||||||
destinations = [x for x in destinations if x]
|
|
||||||
if not destinations:
|
|
||||||
return
|
|
||||||
#
|
|
||||||
txt = n["text"]
|
|
||||||
if infos:
|
|
||||||
txt += "\n\nSemestre %(titremois)s\n\n" % infos["sem"]
|
|
||||||
txt += (
|
|
||||||
"""<a href="Notes/formsemestre_status?formsemestre_id=%(formsemestre_id)s">%(descr_sem)s</a>
|
|
||||||
"""
|
|
||||||
% infos
|
|
||||||
)
|
|
||||||
txt += "\n\nEffectué par: %(nomcomplet)s\n" % n["user_info"]
|
|
||||||
|
|
||||||
txt = (
|
|
||||||
"\n"
|
|
||||||
+ txt
|
|
||||||
+ """\n
|
|
||||||
--- Ceci est un message de notification automatique issu de ScoDoc
|
|
||||||
--- vous recevez ce message car votre adresse est indiquée dans les paramètres de ScoDoc.
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
# Transforme les URL en URL absolue
|
|
||||||
base = scu.ScoURL()
|
|
||||||
txt = re.sub('href=.*?"', 'href="' + base + "/", txt)
|
|
||||||
|
|
||||||
# Transforme les liens HTML en texte brut: '<a href="url">texte</a>' devient 'texte: url'
|
|
||||||
# (si on veut des messages non html)
|
|
||||||
txt = re.sub(r'<a.*?href\s*=\s*"(.*?)".*?>(.*?)</a>', r"\2: \1", txt)
|
|
||||||
|
|
||||||
subject = "[ScoDoc] " + NEWS_MAP.get(n["type"], "?")
|
|
||||||
sender = prefs["email_from_addr"]
|
|
||||||
|
|
||||||
email.send_email(subject, sender, destinations, txt)
|
|
@ -350,7 +350,7 @@ class BasePreferences(object):
|
|||||||
"initvalue": "",
|
"initvalue": "",
|
||||||
"title": "e-mails à qui notifier les opérations",
|
"title": "e-mails à qui notifier les opérations",
|
||||||
"size": 70,
|
"size": 70,
|
||||||
"explanation": "adresses séparées par des virgules; notifie les opérations (saisies de notes, etc). (vous pouvez préférer utiliser le flux rss)",
|
"explanation": "adresses séparées par des virgules; notifie les opérations (saisies de notes, etc).",
|
||||||
"category": "general",
|
"category": "general",
|
||||||
"only_global": False, # peut être spécifique à un semestre
|
"only_global": False, # peut être spécifique à un semestre
|
||||||
},
|
},
|
||||||
|
@ -39,6 +39,7 @@ from flask_login import current_user
|
|||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
from app.models import FormSemestre
|
from app.models import FormSemestre
|
||||||
|
from app.models import ScolarNews
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc.sco_utils import ModuleType
|
from app.scodoc.sco_utils import ModuleType
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
@ -48,6 +49,7 @@ from app.scodoc.sco_exceptions import (
|
|||||||
InvalidNoteValue,
|
InvalidNoteValue,
|
||||||
NoteProcessError,
|
NoteProcessError,
|
||||||
ScoGenError,
|
ScoGenError,
|
||||||
|
ScoInvalidParamError,
|
||||||
ScoValueError,
|
ScoValueError,
|
||||||
)
|
)
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator, TF
|
from app.scodoc.TrivialFormulator import TrivialFormulator, TF
|
||||||
@ -64,7 +66,6 @@ from app.scodoc import sco_formsemestre_inscriptions
|
|||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_groups_view
|
from app.scodoc import sco_groups_view
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
from app.scodoc import sco_news
|
|
||||||
from app.scodoc import sco_permissions_check
|
from app.scodoc import sco_permissions_check
|
||||||
from app.scodoc import sco_undo_notes
|
from app.scodoc import sco_undo_notes
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
@ -274,11 +275,12 @@ def do_evaluation_upload_xls():
|
|||||||
moduleimpl_id=mod["moduleimpl_id"],
|
moduleimpl_id=mod["moduleimpl_id"],
|
||||||
_external=True,
|
_external=True,
|
||||||
)
|
)
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_NOTE,
|
typ=ScolarNews.NEWS_NOTE,
|
||||||
object=M["moduleimpl_id"],
|
obj=M["moduleimpl_id"],
|
||||||
text='Chargement notes dans <a href="%(url)s">%(titre)s</a>' % mod,
|
text='Chargement notes dans <a href="%(url)s">%(titre)s</a>' % mod,
|
||||||
url=mod["url"],
|
url=mod["url"],
|
||||||
|
max_frequency=30 * 60, # 30 minutes
|
||||||
)
|
)
|
||||||
|
|
||||||
msg = (
|
msg = (
|
||||||
@ -359,11 +361,12 @@ def do_evaluation_set_missing(evaluation_id, value, dialog_confirmed=False):
|
|||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
moduleimpl_id=mod["moduleimpl_id"],
|
moduleimpl_id=mod["moduleimpl_id"],
|
||||||
)
|
)
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_NOTE,
|
typ=ScolarNews.NEWS_NOTE,
|
||||||
object=M["moduleimpl_id"],
|
obj=M["moduleimpl_id"],
|
||||||
text='Initialisation notes dans <a href="%(url)s">%(titre)s</a>' % mod,
|
text='Initialisation notes dans <a href="%(url)s">%(titre)s</a>' % mod,
|
||||||
url=mod["url"],
|
url=mod["url"],
|
||||||
|
max_frequency=30 * 60,
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
html_sco_header.sco_header()
|
html_sco_header.sco_header()
|
||||||
@ -451,9 +454,9 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
|
|||||||
mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0]
|
mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0]
|
||||||
mod["moduleimpl_id"] = M["moduleimpl_id"]
|
mod["moduleimpl_id"] = M["moduleimpl_id"]
|
||||||
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
|
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_NOTE,
|
typ=ScolarNews.NEWS_NOTE,
|
||||||
object=M["moduleimpl_id"],
|
obj=M["moduleimpl_id"],
|
||||||
text='Suppression des notes d\'une évaluation dans <a href="%(url)s">%(titre)s</a>'
|
text='Suppression des notes d\'une évaluation dans <a href="%(url)s">%(titre)s</a>'
|
||||||
% mod,
|
% mod,
|
||||||
url=mod["url"],
|
url=mod["url"],
|
||||||
@ -893,10 +896,12 @@ def has_existing_decision(M, E, etudid):
|
|||||||
|
|
||||||
def saisie_notes(evaluation_id, group_ids=[]):
|
def saisie_notes(evaluation_id, group_ids=[]):
|
||||||
"""Formulaire saisie notes d'une évaluation pour un groupe"""
|
"""Formulaire saisie notes d'une évaluation pour un groupe"""
|
||||||
|
if not isinstance(evaluation_id, int):
|
||||||
|
raise ScoInvalidParamError()
|
||||||
group_ids = [int(group_id) for group_id in group_ids]
|
group_ids = [int(group_id) for group_id in group_ids]
|
||||||
evals = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})
|
evals = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})
|
||||||
if not evals:
|
if not evals:
|
||||||
raise ScoValueError("invalid evaluation_id")
|
raise ScoValueError("évaluation inexistante")
|
||||||
E = evals[0]
|
E = evals[0]
|
||||||
M = sco_moduleimpl.moduleimpl_withmodule_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
M = sco_moduleimpl.moduleimpl_withmodule_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
||||||
formsemestre_id = M["formsemestre_id"]
|
formsemestre_id = M["formsemestre_id"]
|
||||||
@ -1283,9 +1288,9 @@ def save_note(etudid=None, evaluation_id=None, value=None, comment=""):
|
|||||||
nbchanged, _, existing_decisions = notes_add(
|
nbchanged, _, existing_decisions = notes_add(
|
||||||
authuser, evaluation_id, L, comment=comment, do_it=True
|
authuser, evaluation_id, L, comment=comment, do_it=True
|
||||||
)
|
)
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_NOTE,
|
typ=ScolarNews.NEWS_NOTE,
|
||||||
object=M["moduleimpl_id"],
|
obj=M["moduleimpl_id"],
|
||||||
text='Chargement notes dans <a href="%(url)s">%(titre)s</a>' % Mod,
|
text='Chargement notes dans <a href="%(url)s">%(titre)s</a>' % Mod,
|
||||||
url=Mod["url"],
|
url=Mod["url"],
|
||||||
max_frequency=30 * 60, # 30 minutes
|
max_frequency=30 * 60, # 30 minutes
|
||||||
|
@ -29,12 +29,14 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import pprint
|
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
from flask import g, url_for
|
from flask import g, url_for
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
|
from app import log
|
||||||
|
from app.models import ScolarNews
|
||||||
|
|
||||||
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
|
||||||
@ -43,11 +45,8 @@ 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
|
||||||
from app.scodoc import sco_inscr_passage
|
from app.scodoc import sco_inscr_passage
|
||||||
from app.scodoc import sco_news
|
|
||||||
from app.scodoc import sco_excel
|
|
||||||
from app.scodoc import sco_portal_apogee
|
from app.scodoc import sco_portal_apogee
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app import log
|
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
@ -701,10 +700,10 @@ def do_import_etuds_from_portal(sem, a_importer, etudsapo_ident):
|
|||||||
sco_cache.invalidate_formsemestre()
|
sco_cache.invalidate_formsemestre()
|
||||||
raise
|
raise
|
||||||
|
|
||||||
sco_news.add(
|
ScolarNews.add(
|
||||||
typ=sco_news.NEWS_INSCR,
|
typ=ScolarNews.NEWS_INSCR,
|
||||||
text="Import Apogée de %d étudiants en " % len(created_etudids),
|
text="Import Apogée de %d étudiants en " % len(created_etudids),
|
||||||
object=sem["formsemestre_id"],
|
obj=sem["formsemestre_id"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -487,6 +487,16 @@ div.news {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.news a {
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.news a:hover {
|
||||||
|
color: rgb(153, 51, 51);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
span.newstitle {
|
span.newstitle {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
@ -987,9 +997,34 @@ span.wtf-field ul.errors li {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.configuration_logo div.img {}
|
.configuration_logo summary {
|
||||||
|
display: list-item !important;
|
||||||
|
}
|
||||||
|
|
||||||
.configuration_logo div.img-container {
|
.configuration_logo h1 {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.configuration_logo h2 {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.configuration_logo h3 {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.configuration_logo details>*:not(summary) {
|
||||||
|
margin-left: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.configuration_logo .content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.configuration_logo .image_logo {
|
||||||
|
vertical-align: top;
|
||||||
|
grid-column: 1/2;
|
||||||
width: 256px;
|
width: 256px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,8 +1032,27 @@ span.wtf-field ul.errors li {
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.configuration_logo div.img-data {
|
.configuration_logo .infos_logo {
|
||||||
vertical-align: top;
|
grid-column: 2/3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.configuration_logo .actions_logo {
|
||||||
|
grid-column: 3/5;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto;
|
||||||
|
grid-column-gap: 10px;
|
||||||
|
align-self: start;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.configuration_logo .actions_logo .action_label {
|
||||||
|
grid-column: 1/2;
|
||||||
|
grid-template-columns: auto auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.configuration_logo .actions_logo .action_button {
|
||||||
|
grid-column: 2/3;
|
||||||
|
align-self: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.configuration_logo logo-edit titre {
|
.configuration_logo logo-edit titre {
|
||||||
@ -2432,6 +2486,12 @@ span.bul_minmax:before {
|
|||||||
content: " ";
|
content: " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.invisible_link,
|
||||||
|
a.invisible_link:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: rgb(20, 30, 30);
|
||||||
|
}
|
||||||
|
|
||||||
a.bull_link {
|
a.bull_link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: rgb(20, 30, 30);
|
color: rgb(20, 30, 30);
|
||||||
@ -3842,3 +3902,11 @@ table.evaluations_recap tr.evaluation.incomplete td a {
|
|||||||
table.evaluations_recap tr.evaluation.incomplete td a.incomplete {
|
table.evaluations_recap tr.evaluation.incomplete td a.incomplete {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.evaluations_recap td.inscrits,
|
||||||
|
table.evaluations_recap td.manquantes,
|
||||||
|
table.evaluations_recap td.nb_abs,
|
||||||
|
table.evaluations_recap td.nb_att,
|
||||||
|
table.evaluations_recap td.nb_exc {
|
||||||
|
text-align: center;
|
||||||
|
}
|
@ -20,73 +20,70 @@
|
|||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro render_add_logo(add_logo_form) %}
|
{% macro render_add_logo(add_logo_form) %}
|
||||||
<div class="logo-add">
|
<details>
|
||||||
|
<summary>
|
||||||
<h3>Ajouter un logo</h3>
|
<h3>Ajouter un logo</h3>
|
||||||
{{ add_logo_form.hidden_tag() }}
|
</summary>
|
||||||
|
<div>
|
||||||
{{ render_field(add_logo_form.name) }}
|
{{ render_field(add_logo_form.name) }}
|
||||||
{{ render_field(add_logo_form.upload) }}
|
{{ render_field(add_logo_form.upload) }}
|
||||||
{{ render_field(add_logo_form.do_insert, False, onSubmit="submit_form") }}
|
{{ render_field(add_logo_form.do_insert, False, onSubmit="submit_form") }}
|
||||||
</div>
|
</div>
|
||||||
|
</details>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro render_logo(dept_form, logo_form) %}
|
{% macro render_logo(dept_form, logo_form) %}
|
||||||
<div class="logo-edit">
|
<details>
|
||||||
{{ logo_form.hidden_tag() }}
|
{{ logo_form.hidden_tag() }}
|
||||||
|
<summary>
|
||||||
{% if logo_form.titre %}
|
{% if logo_form.titre %}
|
||||||
<tr class="logo-edit">
|
<h3 class="titre_logo">{{ logo_form.titre }}</h3>
|
||||||
<td colspan="3" class="titre">
|
{% if logo_form.description %}
|
||||||
<div class="nom">
|
<div class="sco_help">{{ logo_form.description }}</div>
|
||||||
<h3>{{ logo_form.titre }}</h3>
|
|
||||||
</div>
|
|
||||||
<div class="description">{{ logo_form.description or "" }}</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% else %}
|
|
||||||
<tr class="logo-edit">
|
|
||||||
<td colspan="3" class="titre">
|
|
||||||
<span class="nom">
|
|
||||||
<h3>Logo personalisé: {{ logo_form.logo_id.data }}</h3>
|
|
||||||
</span>
|
|
||||||
<span class="description">{{ logo_form.description or "" }}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<tr>
|
{% else %}
|
||||||
<td style="padding-right: 20px; ">
|
<h3 class="titre_logo">Logo personalisé: {{ logo_form.logo_id.data }}</h3>
|
||||||
<div class="img-container">
|
{% if logo_form.description %}
|
||||||
|
<div class="sco_help">{{ logo_form.description }}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</summary>
|
||||||
|
<div class="content">
|
||||||
|
<div class="image_logo">
|
||||||
<img src="{{ logo_form.logo.get_url_small() }}" alt="pas de logo chargé" />
|
<img src="{{ logo_form.logo.get_url_small() }}" alt="pas de logo chargé" />
|
||||||
</div>
|
</div>
|
||||||
</td>
|
<div class="infos_logo">
|
||||||
<td class="img-data">
|
<h4>{{ logo_form.logo.logoname }} (Format: {{ logo_form.logo.suffix }})</h4>
|
||||||
<h3>{{ logo_form.logo.logoname }} (Format: {{ logo_form.logo.suffix }})</h3>
|
|
||||||
Taille: {{ logo_form.logo.size }} px
|
Taille: {{ logo_form.logo.size }} px
|
||||||
{% if logo_form.logo.mm %} / {{ logo_form.logo.mm }} mm {% endif %}<br />
|
{% if logo_form.logo.mm %} / {{ logo_form.logo.mm }} mm {% endif %}<br />
|
||||||
Aspect ratio: {{ logo_form.logo.aspect_ratio }}<br />
|
Aspect ratio: {{ logo_form.logo.aspect_ratio }}<br />
|
||||||
Usage: <span style="font-family: system-ui">{{ logo_form.logo.get_usage() }}</span>
|
Usage: <span style="font-family: system-ui">{{ logo_form.logo.get_usage() }}</span>
|
||||||
</td>
|
|
||||||
<td class="" img-action">
|
|
||||||
<p>Modifier l'image</p>
|
|
||||||
<span class="wtf-field">{{ render_field(logo_form.upload, False, onchange="submit_form()") }}</span>
|
|
||||||
{% if logo_form.can_delete %}
|
|
||||||
<p>Supprimer l'image</p>
|
|
||||||
{{ render_field(logo_form.do_delete, False, onSubmit="submit_form()") }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="actions_logo">
|
||||||
|
<div class="action_label">Modifier l'image</div>
|
||||||
|
<div class="action_button">
|
||||||
|
<span class="wtf-field">{{ render_field(logo_form.upload, False, onchange="submit_form()") }}</span>
|
||||||
|
</div>
|
||||||
|
{% if logo_form.can_delete %}
|
||||||
|
<div class="action_label">Supprimer l'image</div>
|
||||||
|
<div class="action_button">
|
||||||
|
{{ render_field(logo_form.do_delete, False, onSubmit="submit_form()") }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro render_logos(dept_form) %}
|
{% macro render_logos(dept_form) %}
|
||||||
<table>
|
|
||||||
{% for logo_entry in dept_form.logos.entries %}
|
{% for logo_entry in dept_form.logos.entries %}
|
||||||
{% set logo_form = logo_entry.form %}
|
{% set logo_form = logo_entry.form %}
|
||||||
{{ render_logo(dept_form, logo_form) }}
|
{{ render_logo(dept_form, logo_form) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="logo-edit">
|
<p class="logo-titre_logo">
|
||||||
<h3>Aucun logo défini en propre à ce département</h3>
|
<h3 class="titre_logo">Aucun logo défini en propre à ce département</h3>
|
||||||
</p>
|
</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
@ -100,25 +97,26 @@
|
|||||||
<div class="configuration_logo">
|
<div class="configuration_logo">
|
||||||
<h1>Bibliothèque de logos</h1>
|
<h1>Bibliothèque de logos</h1>
|
||||||
{% for dept_entry in form.depts.entries %}
|
{% for dept_entry in form.depts.entries %}
|
||||||
|
<details>
|
||||||
{% set dept_form = dept_entry.form %}
|
{% set dept_form = dept_entry.form %}
|
||||||
{{ dept_entry.form.hidden_tag() }}
|
{{ dept_entry.form.hidden_tag() }}
|
||||||
|
<summary>
|
||||||
{% if dept_entry.form.is_local() %}
|
{% if dept_entry.form.is_local() %}
|
||||||
<div class="departement">
|
|
||||||
<h2>Département {{ dept_form.dept_name.data }}</h2>
|
<h2>Département {{ dept_form.dept_name.data }}</h2>
|
||||||
<h3>Logos locaux</h3>
|
|
||||||
<div class="sco_help">Les paramètres donnés sont spécifiques à ce département.<br />
|
<div class="sco_help">Les paramètres donnés sont spécifiques à ce département.<br />
|
||||||
Les logos du département se substituent aux logos de même nom définis globalement:</div>
|
Les logos du département se substituent aux logos de même nom définis globalement:</div>
|
||||||
</div>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="departement">
|
|
||||||
<h2>Logos généraux</h2>
|
<h2>Logos généraux</h2>
|
||||||
<div class="sco_help">Les images de cette section sont utilisé pour tous les départements,
|
<div class="sco_help">Les images de cette section sont utilisé pour tous les départements,
|
||||||
mais peuvent être redéfinies localement au niveau de chaque département
|
mais peuvent être redéfinies localement au niveau de chaque département
|
||||||
(il suffit de définir un logo local de même nom)</div>
|
(il suffit de définir un logo local de même nom)</div>
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</summary>
|
||||||
|
<div>
|
||||||
{{ render_logos(dept_form) }}
|
{{ render_logos(dept_form) }}
|
||||||
{{ render_add_logo(dept_form.add_logo.form) }}
|
{{ render_add_logo(dept_form.add_logo.form) }}
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
47
app/templates/dept_news.html
Normal file
47
app/templates/dept_news.html
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{# -*- mode: jinja-html -*- #}
|
||||||
|
{% extends "sco_page.html" %}
|
||||||
|
{% block styles %}
|
||||||
|
{{super()}}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block app_content %}
|
||||||
|
<h2>Opérations dans le département {{g.scodoc_dept}}</h2>
|
||||||
|
|
||||||
|
<table id="dept_news" class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Auteur</th>
|
||||||
|
<th>Détail</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{super()}}
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('#dept_news').DataTable({
|
||||||
|
ajax: '{{url_for("scolar.dept_news_json", scodoc_dept=g.scodoc_dept)}}',
|
||||||
|
serverSide: true,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
_: "date.display",
|
||||||
|
sort: "date.timestamp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{data: 'type', searchable: false},
|
||||||
|
{data: 'authenticated_user', orderable: false, searchable: true},
|
||||||
|
{data: 'text', orderable: false, searchable: true}
|
||||||
|
],
|
||||||
|
"order": [[ 0, "desc" ]]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
@ -1738,12 +1738,13 @@ def evaluation_listenotes():
|
|||||||
evaluation_id = None
|
evaluation_id = None
|
||||||
moduleimpl_id = None
|
moduleimpl_id = None
|
||||||
vals = scu.get_request_args()
|
vals = scu.get_request_args()
|
||||||
|
try:
|
||||||
if "evaluation_id" in vals:
|
if "evaluation_id" in vals:
|
||||||
evaluation_id = int(vals["evaluation_id"])
|
evaluation_id = int(vals["evaluation_id"])
|
||||||
mode = "eval"
|
|
||||||
if "moduleimpl_id" in vals and vals["moduleimpl_id"]:
|
if "moduleimpl_id" in vals and vals["moduleimpl_id"]:
|
||||||
moduleimpl_id = int(vals["moduleimpl_id"])
|
moduleimpl_id = int(vals["moduleimpl_id"])
|
||||||
mode = "module"
|
except ValueError as exc:
|
||||||
|
raise ScoValueError("adresse invalide !") from exc
|
||||||
|
|
||||||
format = vals.get("format", "html")
|
format = vals.get("format", "html")
|
||||||
html_content, page_title = sco_liste_notes.do_evaluation_listenotes(
|
html_content, page_title = sco_liste_notes.do_evaluation_listenotes(
|
||||||
|
@ -41,6 +41,7 @@ from flask_wtf import FlaskForm
|
|||||||
from flask_wtf.file import FileField, FileAllowed
|
from flask_wtf.file import FileField, FileAllowed
|
||||||
from wtforms import SubmitField
|
from wtforms import SubmitField
|
||||||
|
|
||||||
|
from app import db
|
||||||
from app import log
|
from app import log
|
||||||
from app.decorators import (
|
from app.decorators import (
|
||||||
scodoc,
|
scodoc,
|
||||||
@ -52,8 +53,10 @@ from app.decorators import (
|
|||||||
)
|
)
|
||||||
from app.models.etudiants import Identite
|
from app.models.etudiants import Identite
|
||||||
from app.models.etudiants import make_etud_args
|
from app.models.etudiants import make_etud_args
|
||||||
|
from app.models.events import ScolarNews
|
||||||
|
|
||||||
from app.views import scolar_bp as bp
|
from app.views import scolar_bp as bp
|
||||||
|
from app.views import ScoData
|
||||||
|
|
||||||
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
|
||||||
@ -339,6 +342,67 @@ def install_info():
|
|||||||
return sco_up_to_date.is_up_to_date()
|
return sco_up_to_date.is_up_to_date()
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/dept_news")
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoView)
|
||||||
|
def dept_news():
|
||||||
|
"Affiche table des dernières opérations"
|
||||||
|
return render_template(
|
||||||
|
"dept_news.html", title=f"Opérations {g.scodoc_dept}", sco=ScoData()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/dept_news_json")
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoView)
|
||||||
|
def dept_news_json():
|
||||||
|
"Table des news du département"
|
||||||
|
start = request.args.get("start", type=int)
|
||||||
|
length = request.args.get("length", type=int)
|
||||||
|
|
||||||
|
log(f"dept_news_json( start={start}, length={length})")
|
||||||
|
query = ScolarNews.query.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
|
# search
|
||||||
|
search = request.args.get("search[value]")
|
||||||
|
if search:
|
||||||
|
query = query.filter(
|
||||||
|
db.or_(
|
||||||
|
ScolarNews.authenticated_user.like(f"%{search}%"),
|
||||||
|
ScolarNews.text.like(f"%{search}%"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
total_filtered = query.count()
|
||||||
|
# sorting
|
||||||
|
order = []
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
col_index = request.args.get(f"order[{i}][column]")
|
||||||
|
if col_index is None:
|
||||||
|
break
|
||||||
|
col_name = request.args.get(f"columns[{col_index}][data]")
|
||||||
|
if col_name not in ["date", "type", "authenticated_user"]:
|
||||||
|
col_name = "date"
|
||||||
|
descending = request.args.get(f"order[{i}][dir]") == "desc"
|
||||||
|
col = getattr(ScolarNews, col_name)
|
||||||
|
if descending:
|
||||||
|
col = col.desc()
|
||||||
|
order.append(col)
|
||||||
|
i += 1
|
||||||
|
if order:
|
||||||
|
query = query.order_by(*order)
|
||||||
|
|
||||||
|
# pagination
|
||||||
|
query = query.offset(start).limit(length)
|
||||||
|
data = [news.to_dict() for news in query]
|
||||||
|
# response
|
||||||
|
return {
|
||||||
|
"data": data,
|
||||||
|
"recordsFiltered": total_filtered,
|
||||||
|
"recordsTotal": ScolarNews.query.count(),
|
||||||
|
"draw": request.args.get("draw", type=int),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sco_publish(
|
sco_publish(
|
||||||
"/trombino", sco_trombino.trombino, Permission.ScoView, methods=["GET", "POST"]
|
"/trombino", sco_trombino.trombino, Permission.ScoView, methods=["GET", "POST"]
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
alembic==1.7.5
|
alembic==1.7.5
|
||||||
astroid==2.9.1
|
astroid==2.11.2
|
||||||
attrs==21.4.0
|
attrs==21.4.0
|
||||||
Babel==2.9.1
|
Babel==2.9.1
|
||||||
blinker==1.4
|
blinker==1.4
|
||||||
@ -35,6 +35,7 @@ isort==5.10.1
|
|||||||
itsdangerous==2.0.1
|
itsdangerous==2.0.1
|
||||||
Jinja2==3.0.3
|
Jinja2==3.0.3
|
||||||
lazy-object-proxy==1.7.1
|
lazy-object-proxy==1.7.1
|
||||||
|
lxml==4.8.0
|
||||||
Mako==1.1.6
|
Mako==1.1.6
|
||||||
MarkupSafe==2.0.1
|
MarkupSafe==2.0.1
|
||||||
mccabe==0.6.1
|
mccabe==0.6.1
|
||||||
@ -53,6 +54,7 @@ pyOpenSSL==21.0.0
|
|||||||
pyparsing==3.0.6
|
pyparsing==3.0.6
|
||||||
pytest==6.2.5
|
pytest==6.2.5
|
||||||
python-dateutil==2.8.2
|
python-dateutil==2.8.2
|
||||||
|
python-docx==0.8.11
|
||||||
python-dotenv==0.19.2
|
python-dotenv==0.19.2
|
||||||
python-editor==1.0.4
|
python-editor==1.0.4
|
||||||
pytz==2021.3
|
pytz==2021.3
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.2.0a"
|
SCOVERSION = "9.2.1"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
SCONEWS = """
|
SCONEWS = """
|
||||||
<h4>Année 2021</h4>
|
<h4>Année 2021</h4>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>ScoDoc 9.2:
|
||||||
|
<ul>
|
||||||
|
<li>Tableau récap. complet pour BUT et autres formations.</li>
|
||||||
|
<li>Tableau état évaluations</li>
|
||||||
|
<li>Version alpha du module "relations entreprises"</li>
|
||||||
|
<li>Export des trombinoscope en document docx</li>
|
||||||
|
<li>Très nombreux correctifs</li>
|
||||||
|
</ul>
|
||||||
<li>ScoDoc 9.1.75: bulletins BUT pdf</li>
|
<li>ScoDoc 9.1.75: bulletins BUT pdf</li>
|
||||||
<li>ScoDoc 9.1.50: nombreuses amélioration gestion BUT</li>
|
<li>ScoDoc 9.1.50: nombreuses amélioration gestion BUT</li>
|
||||||
<li>ScoDoc 9.1: gestion des formations par compétences, type BUT.</li>
|
<li>ScoDoc 9.1: gestion des formations par compétences, type BUT.</li>
|
||||||
|
@ -77,6 +77,7 @@ def make_shell_context():
|
|||||||
"pp": pp,
|
"pp": pp,
|
||||||
"Role": Role,
|
"Role": Role,
|
||||||
"scolar": scolar,
|
"scolar": scolar,
|
||||||
|
"ScolarNews": models.ScolarNews,
|
||||||
"scu": scu,
|
"scu": scu,
|
||||||
"UniteEns": UniteEns,
|
"UniteEns": UniteEns,
|
||||||
"User": User,
|
"User": User,
|
||||||
|
@ -73,7 +73,9 @@ token = r.json()["token"]
|
|||||||
HEADERS = {"Authorization": f"Bearer {token}"}
|
HEADERS = {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/list_depts", headers=HEADERS, verify=CHECK_CERTIFICATE
|
SCODOC_URL + "/ScoDoc/api/list_depts",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
raise ScoError("erreur de connexion: vérifier adresse et identifiants")
|
raise ScoError("erreur de connexion: vérifier adresse et identifiants")
|
||||||
|
@ -16,25 +16,22 @@ Utilisation :
|
|||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
SCODOC_USER = "test"
|
|
||||||
SCODOC_PASSWORD = "test"
|
SCODOC_USER = "api_tester"
|
||||||
SCODOC_URL = "http://192.168.1.12:5000"
|
SCODOC_PASSWORD = "api_tester"
|
||||||
|
SCODOC_URL = "http://deb11.viennet.net:5000"
|
||||||
CHECK_CERTIFICATE = bool(int(os.environ.get("CHECK_CERTIFICATE", False)))
|
CHECK_CERTIFICATE = bool(int(os.environ.get("CHECK_CERTIFICATE", False)))
|
||||||
|
|
||||||
HEADERS = None
|
|
||||||
|
|
||||||
def get_token():
|
def get_token():
|
||||||
"""
|
"""
|
||||||
Permet de set le token dans le header
|
Permet de set le token dans le header
|
||||||
"""
|
"""
|
||||||
global HEADERS
|
|
||||||
global SCODOC_USER
|
|
||||||
global SCODOC_PASSWORD
|
|
||||||
|
|
||||||
r0 = requests.post(
|
r0 = requests.post(
|
||||||
SCODOC_URL + "/ScoDoc/api/tokens", auth=(SCODOC_USER, SCODOC_PASSWORD)
|
SCODOC_URL + "/ScoDoc/api/tokens", auth=(SCODOC_USER, SCODOC_PASSWORD)
|
||||||
)
|
)
|
||||||
token = r0.json()["token"]
|
token = r0.json()["token"]
|
||||||
HEADERS = {"Authorization": f"Bearer {token}"}
|
return {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
get_token()
|
|
||||||
|
HEADERS = get_token()
|
||||||
|
@ -18,26 +18,29 @@ Utilisation :
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from tests.api.setup_test_api import SCODOC_URL, HEADERS, CHECK_CERTIFICATE
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
|
|
||||||
# absences
|
# absences
|
||||||
def test_absences():
|
def test_absences():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/etudid/<int:etudid>",
|
SCODOC_URL + "/ScoDoc/api/absences/etudid/<int:etudid>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/nip/<int:nip>",
|
SCODOC_URL + "/ScoDoc/api/absences/nip/<int:nip>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/ine/<int:ine>",
|
SCODOC_URL + "/ScoDoc/api/absences/ine/<int:ine>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
@ -46,49 +49,61 @@ def test_absences():
|
|||||||
def test_absences_justify():
|
def test_absences_justify():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/etudid/<int:etudid>/abs_just_only",
|
SCODOC_URL + "/ScoDoc/api/absences/etudid/<int:etudid>/abs_just_only",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/nip/<int:nip>/abs_just_only",
|
SCODOC_URL + "/ScoDoc/api/absences/nip/<int:nip>/abs_just_only",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/ine/<int:ine>/abs_just_only",
|
SCODOC_URL + "/ScoDoc/api/absences/ine/<int:ine>/abs_just_only",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# abs_signale
|
# abs_signale
|
||||||
def test_abs_signale():
|
def test_abs_signale():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_signale?etudid=<int:etudid>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/absences/abs_signale?etudid=<int:etudid>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
||||||
"&description=<string:description>",
|
"&description=<string:description>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_signale?nip=<int:nip>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/absences/abs_signale?nip=<int:nip>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
||||||
"&description=<string:description>",
|
"&description=<string:description>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_signale?ine=<int:ine>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/absences/abs_signale?ine=<int:ine>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
||||||
"&description=<string:description>",
|
"&description=<string:description>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_signale?ine=<int:ine>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/absences/abs_signale?ine=<int:ine>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
||||||
"&description=<string:description>&moduleimpl_id=<int:moduleimpl_id>",
|
"&description=<string:description>&moduleimpl_id=<int:moduleimpl_id>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
@ -96,20 +111,26 @@ def test_abs_signale():
|
|||||||
# abs_annule
|
# abs_annule
|
||||||
def test_abs_annule():
|
def test_abs_annule():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_annule?etudid=<int:etudid>&jour=<string:jour>&matin=<string:matin>",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/absences/abs_annule?etudid=<int:etudid>&jour=<string:jour>&matin=<string:matin>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_annule?nip=<int:nip>&jour=<string:jour>&matin=<string:matin>",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/absences/abs_annule?nip=<int:nip>&jour=<string:jour>&matin=<string:matin>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_annule?ine=<int:ine>&jour=<string:jour>&matin=<string:matin>",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/absences/abs_annule?ine=<int:ine>&jour=<string:jour>&matin=<string:matin>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
@ -117,27 +138,36 @@ def test_abs_annule():
|
|||||||
# abs_annule_justif
|
# abs_annule_justif
|
||||||
def test_abs_annule_justif():
|
def test_abs_annule_justif():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_annule_justif?etudid=<int:etudid>&jour=<string:jour>&matin=<string:matin>",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/absences/abs_annule_justif?etudid=<int:etudid>&jour=<string:jour>&matin=<string:matin>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_annule_justif?nip=<int:nip>&jour=<string:jour>&matin=<string:matin>",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/absences/abs_annule_justif?nip=<int:nip>&jour=<string:jour>&matin=<string:matin>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_annule_justif?ine=<int:ine>&jour=<string:jour>&matin=<string:matin>",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/absences/abs_annule_justif?ine=<int:ine>&jour=<string:jour>&matin=<string:matin>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# abs_groupe_etat
|
# abs_groupe_etat
|
||||||
def test_abs_groupe_etat():
|
def test_abs_groupe_etat():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/absences/abs_group_etat/?group_id=<int:group_id>&date_debut=date_debut&date_fin=date_fin",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/absences/abs_group_etat/?group_id=<int:group_id>&date_debut=date_debut&date_fin=date_fin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
@ -18,14 +18,16 @@ Utilisation :
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from tests.api.setup_test_api import SCODOC_URL, HEADERS, CHECK_CERTIFICATE
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
|
|
||||||
# departements
|
# departements
|
||||||
def test_departements():
|
def test_departements():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements",
|
SCODOC_URL + "/ScoDoc/api/departements",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert len(r.json()) == 1
|
assert len(r.json()) == 1
|
||||||
@ -35,14 +37,16 @@ def test_departements():
|
|||||||
def test_liste_etudiants():
|
def test_liste_etudiants():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements/TAPI/etudiants/liste",
|
SCODOC_URL + "/ScoDoc/api/departements/TAPI/etudiants/liste",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert len(r.json()) == 16
|
assert len(r.json()) == 16
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements/TAPI/etudiants/liste/1",
|
SCODOC_URL + "/ScoDoc/api/departements/TAPI/etudiants/liste/1",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert len(r.json()) == 16
|
assert len(r.json()) == 16
|
||||||
@ -52,7 +56,8 @@ def test_liste_etudiants():
|
|||||||
def test_semestres_courant():
|
def test_semestres_courant():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements/TAPI/semestres_courants",
|
SCODOC_URL + "/ScoDoc/api/departements/TAPI/semestres_courants",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert len(r.json()) == 1
|
assert len(r.json()) == 1
|
||||||
@ -61,8 +66,10 @@ def test_semestres_courant():
|
|||||||
# referenciel_competences
|
# referenciel_competences
|
||||||
def test_referenciel_competences():
|
def test_referenciel_competences():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/departements/TAPI/formations/1/referentiel_competences",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/departements/TAPI/formations/1/referentiel_competences",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200 or 204
|
assert r.status_code == 200 or 204
|
||||||
|
|
||||||
@ -74,21 +81,3 @@ def test_referenciel_competences():
|
|||||||
# headers=HEADERS, verify=CHECK_CERTIFICATE
|
# headers=HEADERS, verify=CHECK_CERTIFICATE
|
||||||
# )
|
# )
|
||||||
# assert r.status_code == 200
|
# assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,14 +19,15 @@ Utilisation :
|
|||||||
from random import randint
|
from random import randint
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from tests.api.setup_test_api import SCODOC_URL, HEADERS, CHECK_CERTIFICATE
|
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
# etudiants
|
# etudiants
|
||||||
def test_etudiants():
|
def test_etudiants():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/etudiants",
|
SCODOC_URL + "/ScoDoc/api/etudiants",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert len(r.json()) == 16
|
assert len(r.json()) == 16
|
||||||
@ -34,8 +35,18 @@ def test_etudiants():
|
|||||||
# Choisis aléatoirement un étudiant dans la liste des étudiants
|
# Choisis aléatoirement un étudiant dans la liste des étudiants
|
||||||
etu = r.json()[randint(0, len(r.json())) - 1]
|
etu = r.json()[randint(0, len(r.json())) - 1]
|
||||||
|
|
||||||
fields = ["civilite", "code_ine", "code_nip", "date_naissance", "email", "emailperso", "etudid", "nom",
|
fields = [
|
||||||
"prenom", "nomprenom"]
|
"civilite",
|
||||||
|
"code_ine",
|
||||||
|
"code_nip",
|
||||||
|
"date_naissance",
|
||||||
|
"email",
|
||||||
|
"emailperso",
|
||||||
|
"etudid",
|
||||||
|
"nom",
|
||||||
|
"prenom",
|
||||||
|
"nomprenom",
|
||||||
|
]
|
||||||
|
|
||||||
fields_OK = True
|
fields_OK = True
|
||||||
|
|
||||||
@ -51,7 +62,8 @@ def test_etudiants():
|
|||||||
def test_etudiants_courant():
|
def test_etudiants_courant():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/etudiants/courant",
|
SCODOC_URL + "/ScoDoc/api/etudiants/courant",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert len(r.json()) == 0
|
assert len(r.json()) == 0
|
||||||
@ -61,7 +73,8 @@ def test_etudiants_courant():
|
|||||||
def test_etudiant():
|
def test_etudiant():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1",
|
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert len(r.json()) == 10
|
assert len(r.json()) == 10
|
||||||
@ -82,7 +95,8 @@ def test_etudiant():
|
|||||||
def test_etudiant_formsemestres():
|
def test_etudiant_formsemestres():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1/formsemestres",
|
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1/formsemestres",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert len(r.json()) == 1
|
assert len(r.json()) == 1
|
||||||
@ -127,12 +141,12 @@ def test_etudiant_formsemestres():
|
|||||||
def test_etudiant_groups():
|
def test_etudiant_groups():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1/semestre/1/groups",
|
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1/semestre/1/groups",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert len(r.json()) == 1
|
assert len(r.json()) == 1
|
||||||
|
|
||||||
|
|
||||||
# r = requests.get(
|
# r = requests.get(
|
||||||
# SCODOC_URL + "/ScoDoc/api/etudiant/nip/<int:nip>/semestre/<int:formsemestre_id>/groups",
|
# SCODOC_URL + "/ScoDoc/api/etudiant/nip/<int:nip>/semestre/<int:formsemestre_id>/groups",
|
||||||
# headers=HEADERS, verify=CHECK_CERTIFICATE
|
# headers=HEADERS, verify=CHECK_CERTIFICATE
|
||||||
|
@ -18,41 +18,51 @@ Utilisation :
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from tests.api.setup_test_api import SCODOC_URL, HEADERS, CHECK_CERTIFICATE
|
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
# evaluations
|
# evaluations
|
||||||
def test_evaluations():
|
def test_evaluations():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/evaluations/<int:moduleimpl_id>",
|
SCODOC_URL + "/ScoDoc/api/evaluations/<int:moduleimpl_id>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# evaluation_notes
|
# evaluation_notes
|
||||||
def test_evaluation_notes():
|
def test_evaluation_notes():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/evaluations/eval_notes/<int:evaluation_id>",
|
SCODOC_URL + "/ScoDoc/api/evaluations/eval_notes/<int:evaluation_id>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# evaluation_set_notes
|
# evaluation_set_notes
|
||||||
def test_evaluation_set_notes():
|
def test_evaluation_set_notes():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/evaluations/eval_set_notes?eval_id=<int:eval_id>&etudid=<int:etudid>¬e=<float:note>",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/evaluations/eval_set_notes?eval_id=<int:eval_id>&etudid=<int:etudid>¬e=<float:note>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/evaluations/eval_set_notes?eval_id=<int:eval_id>&nip=<int:nip>¬e=<float:note>",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/evaluations/eval_set_notes?eval_id=<int:eval_id>&nip=<int:nip>¬e=<float:note>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/evaluations/eval_set_notes?eval_id=<int:eval_id>&ine=<int:ine>¬e=<float:note>",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/evaluations/eval_set_notes?eval_id=<int:eval_id>&ine=<int:ine>¬e=<float:note>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
@ -18,38 +18,45 @@ Utilisation :
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from tests.api.setup_test_api import SCODOC_URL, HEADERS, CHECK_CERTIFICATE
|
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
# formations
|
# formations
|
||||||
def test_formations():
|
def test_formations():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formations",
|
SCODOC_URL + "/ScoDoc/api/formations",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# formations_by_id
|
# formations_by_id
|
||||||
def test_formations_by_id():
|
def test_formations_by_id():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formations/<int:formation_id>",
|
SCODOC_URL + "/ScoDoc/api/formations/<int:formation_id>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# formation_export_by_formation_id
|
# formation_export_by_formation_id
|
||||||
def test_formation_export_by_formation_id():
|
def test_formation_export_by_formation_id():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formations/formation_export/<int:formation_id>",
|
SCODOC_URL + "/ScoDoc/api/formations/formation_export/<int:formation_id>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# formsemestre_apo
|
# formsemestre_apo
|
||||||
def test_formsemestre_apo():
|
def test_formsemestre_apo():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formations/apo/<string:etape_apo>",
|
SCODOC_URL + "/ScoDoc/api/formations/apo/<string:etape_apo>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
@ -58,7 +65,8 @@ def test_formsemestre_apo():
|
|||||||
def test_moduleimpls():
|
def test_moduleimpls():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formations/moduleimpl/<int:moduleimpl_id>",
|
SCODOC_URL + "/ScoDoc/api/formations/moduleimpl/<int:moduleimpl_id>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
@ -66,7 +74,9 @@ def test_moduleimpls():
|
|||||||
# moduleimpls_sem
|
# moduleimpls_sem
|
||||||
def test_moduleimpls_sem():
|
def test_moduleimpls_sem():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formations/moduleimpl/<int:moduleimpl_id>/formsemestre/<int:formsemestre_id>",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/formations/moduleimpl/<int:moduleimpl_id>/formsemestre/<int:formsemestre_id>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
@ -18,42 +18,52 @@ Utilisation :
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from tests.api.setup_test_api import SCODOC_URL, HEADERS, CHECK_CERTIFICATE
|
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
# formsemestre
|
# formsemestre
|
||||||
def test_formsemestre():
|
def test_formsemestre():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formations/formsemestre/<int:formsemestre_id>",
|
SCODOC_URL + "/ScoDoc/api/formations/formsemestre/<int:formsemestre_id>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# etudiant_bulletin
|
# etudiant_bulletin
|
||||||
def test_etudiant_bulletin():
|
def test_etudiant_bulletin():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/etudid/<int:etudid>/bulletin",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/etudid/<int:etudid>/bulletin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/nip/<int:nip>/bulletin",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/nip/<int:nip>/bulletin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/ine/<int:ine>/bulletin",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/ine/<int:ine>/bulletin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# bulletins
|
# bulletins
|
||||||
def test_bulletins():
|
def test_bulletins():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formsemestre/<int:formsemestre_id>/bulletins",
|
SCODOC_URL + "/ScoDoc/api/formsemestre/<int:formsemestre_id>/bulletins",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
@ -62,6 +72,7 @@ def test_bulletins():
|
|||||||
def test_jury():
|
def test_jury():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/formsemestre/<int:formsemestre_id>/jury",
|
SCODOC_URL + "/ScoDoc/api/formsemestre/<int:formsemestre_id>/jury",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
@ -18,45 +18,57 @@ Utilisation :
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from tests.api.setup_test_api import SCODOC_URL, HEADERS, CHECK_CERTIFICATE
|
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
# jury_preparation
|
# jury_preparation
|
||||||
def test_jury_preparation():
|
def test_jury_preparation():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/jury/formsemestre/<int:formsemestre_id>/preparation_jury",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/jury/formsemestre/<int:formsemestre_id>/preparation_jury",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# jury_decisions
|
# jury_decisions
|
||||||
def test_jury_decisions():
|
def test_jury_decisions():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/jury/formsemestre/<int:formsemestre_id>/decisions_jury",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/jury/formsemestre/<int:formsemestre_id>/decisions_jury",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# set_decision_jury
|
# set_decision_jury
|
||||||
def test_set_decision_jury():
|
def test_set_decision_jury():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/jury/set_decision/etudid?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/set_decision/etudid?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
||||||
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/jury/set_decision/nip?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/set_decision/nip?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
||||||
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/jury/set_decision/ine?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/set_decision/ine?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
||||||
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
@ -64,20 +76,25 @@ def test_set_decision_jury():
|
|||||||
# annule_decision_jury
|
# annule_decision_jury
|
||||||
def test_annule_decision_jury():
|
def test_annule_decision_jury():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/jury/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/annule_decision",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/jury/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||||
)
|
headers=HEADERS,
|
||||||
assert r.status_code == 200
|
verify=CHECK_CERTIFICATE,
|
||||||
|
|
||||||
|
|
||||||
r = requests.get(
|
|
||||||
SCODOC_URL + "/ScoDoc/api/jury/nip/<int:nip>/formsemestre/<int:formsemestre_id>/annule_decision",
|
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/jury/ine/<int:ine>/formsemestre/<int:formsemestre_id>/annule_decision",
|
SCODOC_URL
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
+ "/ScoDoc/api/jury/nip/<int:nip>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/ine/<int:ine>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
@ -9,7 +9,7 @@ utilisation:
|
|||||||
pytest tests/api/test_api_logos.py
|
pytest tests/api/test_api_logos.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pytest
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
from scodoc import app
|
from scodoc import app
|
||||||
from tests.unit.config_test_logos import (
|
from tests.unit.config_test_logos import (
|
||||||
|
@ -18,27 +18,31 @@ Utilisation :
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from tests.api.setup_test_api import SCODOC_URL, HEADERS, CHECK_CERTIFICATE
|
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
# partition
|
# partition
|
||||||
def test_partition():
|
def test_partition():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/partitions/<int:formsemestre_id>",
|
SCODOC_URL + "/ScoDoc/api/partitions/<int:formsemestre_id>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
# etud_in_group
|
# etud_in_group
|
||||||
def test_etud_in_group():
|
def test_etud_in_group():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/partitions/groups/<int:group_id>",
|
SCODOC_URL + "/ScoDoc/api/partitions/groups/<int:group_id>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/partitions/groups/<int:group_id>/etat/<string:etat>",
|
SCODOC_URL + "/ScoDoc/api/partitions/groups/<int:group_id>/etat/<string:etat>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
@ -46,8 +50,10 @@ def test_etud_in_group():
|
|||||||
# set_groups
|
# set_groups
|
||||||
def test_set_groups():
|
def test_set_groups():
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/partitions/set_groups?partition_id=<int:partition_id>&groups_lists=<int:groups_lists>&"
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/partitions/set_groups?partition_id=<int:partition_id>&groups_lists=<int:groups_lists>&"
|
||||||
"groups_to_create=<int:groups_to_create>&groups_to_delete=<int:groups_to_delete>",
|
"groups_to_create=<int:groups_to_create>&groups_to_delete=<int:groups_to_delete>",
|
||||||
headers=HEADERS, verify=CHECK_CERTIFICATE
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
Loading…
Reference in New Issue
Block a user