Génère JSON avec Flask-JSON. Abandonne jsonify.
This commit is contained in:
parent
03a330ae82
commit
6e86f7a9c4
@ -17,7 +17,7 @@ import warnings
|
|||||||
|
|
||||||
from flask import current_app, g, request
|
from flask import current_app, g, request
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask import abort, flash, has_request_context, jsonify
|
from flask import abort, flash, has_request_context
|
||||||
from flask import render_template
|
from flask import render_template
|
||||||
|
|
||||||
# from flask.json import JSONEncoder
|
# from flask.json import JSONEncoder
|
||||||
@ -25,6 +25,7 @@ from flask.logging import default_handler
|
|||||||
|
|
||||||
from flask_bootstrap import Bootstrap
|
from flask_bootstrap import Bootstrap
|
||||||
from flask_caching import Cache
|
from flask_caching import Cache
|
||||||
|
from flask_json import FlaskJSON, json_response
|
||||||
from flask_login import LoginManager, current_user
|
from flask_login import LoginManager, current_user
|
||||||
from flask_mail import Mail
|
from flask_mail import Mail
|
||||||
from flask_migrate import Migrate
|
from flask_migrate import Migrate
|
||||||
@ -139,12 +140,14 @@ def _async_dump(app, request_url: str):
|
|||||||
|
|
||||||
|
|
||||||
def handle_invalid_usage(error):
|
def handle_invalid_usage(error):
|
||||||
response = jsonify(error.to_dict())
|
response = json_response(data_=error.to_dict())
|
||||||
response.status_code = error.status_code
|
response.status_code = error.status_code
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
# JSON ENCODING
|
# JSON ENCODING
|
||||||
|
# used by some internal finctions
|
||||||
|
# the API is now using flask_son, NOT THIS ENCODER
|
||||||
class ScoDocJSONEncoder(json.JSONEncoder):
|
class ScoDocJSONEncoder(json.JSONEncoder):
|
||||||
def default(self, o): # pylint: disable=E0202
|
def default(self, o): # pylint: disable=E0202
|
||||||
if isinstance(o, (datetime.date, datetime.datetime)):
|
if isinstance(o, (datetime.date, datetime.datetime)):
|
||||||
@ -251,13 +254,13 @@ class ReverseProxied(object):
|
|||||||
|
|
||||||
def create_app(config_class=DevConfig):
|
def create_app(config_class=DevConfig):
|
||||||
app = Flask(__name__, static_url_path="/ScoDoc/static", static_folder="static")
|
app = Flask(__name__, static_url_path="/ScoDoc/static", static_folder="static")
|
||||||
|
app.config.from_object(config_class)
|
||||||
from app.auth import cas
|
from app.auth import cas
|
||||||
|
|
||||||
CAS(app, url_prefix="/cas", configuration_function=cas.set_cas_configuration)
|
CAS(app, url_prefix="/cas", configuration_function=cas.set_cas_configuration)
|
||||||
app.wsgi_app = ReverseProxied(app.wsgi_app)
|
app.wsgi_app = ReverseProxied(app.wsgi_app)
|
||||||
app.json_provider_class = ScoDocJSONEncoder
|
FlaskJSON(app)
|
||||||
|
|
||||||
app.config.from_object(config_class)
|
|
||||||
# Pour conserver l'ordre des objets dans les JSON:
|
# Pour conserver l'ordre des objets dans les JSON:
|
||||||
# e.g. l'ordre des UE dans les bulletins
|
# e.g. l'ordre des UE dans les bulletins
|
||||||
app.json.sort_keys = False
|
app.json.sort_keys = False
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
"""ScoDoc 9 API : Absences
|
"""ScoDoc 9 API : Absences
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from flask import jsonify
|
from flask_json import as_json
|
||||||
|
|
||||||
from app.api import api_bp as bp, API_CLIENT_ERROR
|
from app.api import api_bp as bp, API_CLIENT_ERROR
|
||||||
from app.scodoc.sco_utils import json_error
|
from app.scodoc.sco_utils import json_error
|
||||||
@ -19,10 +19,12 @@ from app.scodoc import sco_abs
|
|||||||
from app.scodoc.sco_groups import get_group_members
|
from app.scodoc.sco_groups import get_group_members
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
# TODO XXX revoir routes web API et calcul des droits
|
# TODO XXX revoir routes web API et calcul des droits
|
||||||
@bp.route("/absences/etudid/<int:etudid>", methods=["GET"])
|
@bp.route("/absences/etudid/<int:etudid>", methods=["GET"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def absences(etudid: int = None):
|
def absences(etudid: int = None):
|
||||||
"""
|
"""
|
||||||
Liste des absences de cet étudiant
|
Liste des absences de cet étudiant
|
||||||
@ -57,12 +59,13 @@ def absences(etudid: int = None):
|
|||||||
abs_list = sco_abs.list_abs_date(etud.id)
|
abs_list = sco_abs.list_abs_date(etud.id)
|
||||||
for absence in abs_list:
|
for absence in abs_list:
|
||||||
absence["jour"] = absence["jour"].isoformat()
|
absence["jour"] = absence["jour"].isoformat()
|
||||||
return jsonify(abs_list)
|
return abs_list
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/absences/etudid/<int:etudid>/just", methods=["GET"])
|
@bp.route("/absences/etudid/<int:etudid>/just", methods=["GET"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def absences_just(etudid: int = None):
|
def absences_just(etudid: int = None):
|
||||||
"""
|
"""
|
||||||
Retourne la liste des absences justifiées d'un étudiant donné
|
Retourne la liste des absences justifiées d'un étudiant donné
|
||||||
@ -103,7 +106,7 @@ def absences_just(etudid: int = None):
|
|||||||
]
|
]
|
||||||
for absence in abs_just:
|
for absence in abs_just:
|
||||||
absence["jour"] = absence["jour"].isoformat()
|
absence["jour"] = absence["jour"].isoformat()
|
||||||
return jsonify(abs_just)
|
return abs_just
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
@ -116,6 +119,7 @@ def absences_just(etudid: int = None):
|
|||||||
)
|
)
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def abs_groupe_etat(group_id: int, date_debut=None, date_fin=None):
|
def abs_groupe_etat(group_id: int, date_debut=None, date_fin=None):
|
||||||
"""
|
"""
|
||||||
Liste des absences d'un groupe (possibilité de choisir entre deux dates)
|
Liste des absences d'un groupe (possibilité de choisir entre deux dates)
|
||||||
@ -167,7 +171,7 @@ def abs_groupe_etat(group_id: int, date_debut=None, date_fin=None):
|
|||||||
}
|
}
|
||||||
data.append(absence)
|
data.append(absence)
|
||||||
|
|
||||||
return jsonify(data)
|
return data
|
||||||
|
|
||||||
|
|
||||||
# XXX TODO EV: A REVOIR (data json dans le POST + modifier les routes)
|
# XXX TODO EV: A REVOIR (data json dans le POST + modifier les routes)
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
API : billets d'absences
|
API : billets d'absences
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from flask import g, jsonify, request
|
from flask import g, request
|
||||||
|
from flask_json import as_json
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
@ -26,10 +27,11 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def billets_absence_etudiant(etudid: int):
|
def billets_absence_etudiant(etudid: int):
|
||||||
"""Liste des billets d'absence pour cet étudiant"""
|
"""Liste des billets d'absence pour cet étudiant"""
|
||||||
billets = sco_abs_billets.query_billets_etud(etudid)
|
billets = sco_abs_billets.query_billets_etud(etudid)
|
||||||
return jsonify([billet.to_dict() for billet in billets])
|
return [billet.to_dict() for billet in billets]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/billets_absence/create", methods=["POST"])
|
@bp.route("/billets_absence/create", methods=["POST"])
|
||||||
@ -37,6 +39,7 @@ def billets_absence_etudiant(etudid: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoAbsAddBillet)
|
@permission_required(Permission.ScoAbsAddBillet)
|
||||||
|
@as_json
|
||||||
def billets_absence_create():
|
def billets_absence_create():
|
||||||
"""Ajout d'un billet d'absence"""
|
"""Ajout d'un billet d'absence"""
|
||||||
data = request.get_json(force=True) # may raise 400 Bad Request
|
data = request.get_json(force=True) # may raise 400 Bad Request
|
||||||
@ -60,7 +63,7 @@ def billets_absence_create():
|
|||||||
)
|
)
|
||||||
db.session.add(billet)
|
db.session.add(billet)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(billet.to_dict())
|
return billet.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/billets_absence/<int:billet_id>/delete", methods=["POST"])
|
@bp.route("/billets_absence/<int:billet_id>/delete", methods=["POST"])
|
||||||
@ -68,6 +71,7 @@ def billets_absence_create():
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoAbsAddBillet)
|
@permission_required(Permission.ScoAbsAddBillet)
|
||||||
|
@as_json
|
||||||
def billets_absence_delete(billet_id: int):
|
def billets_absence_delete(billet_id: int):
|
||||||
"""Suppression d'un billet d'absence"""
|
"""Suppression d'un billet d'absence"""
|
||||||
query = BilletAbsence.query.filter_by(id=billet_id)
|
query = BilletAbsence.query.filter_by(id=billet_id)
|
||||||
@ -77,4 +81,4 @@ def billets_absence_delete(billet_id: int):
|
|||||||
billet = query.first_or_404()
|
billet = query.first_or_404()
|
||||||
db.session.delete(billet)
|
db.session.delete(billet)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify({"OK": True})
|
return {"OK": True}
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
"""
|
"""
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from flask import jsonify, request
|
from flask import request
|
||||||
|
from flask_json import as_json
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
import app
|
import app
|
||||||
@ -41,24 +42,27 @@ def get_departement(dept_ident: str) -> Departement:
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def departements_list():
|
def departements_list():
|
||||||
"""Liste les départements"""
|
"""Liste les départements"""
|
||||||
return jsonify([dept.to_dict(with_dept_name=True) for dept in Departement.query])
|
return [dept.to_dict(with_dept_name=True) for dept in Departement.query]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departements_ids")
|
@bp.route("/departements_ids")
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def departements_ids():
|
def departements_ids():
|
||||||
"""Liste des ids de départements"""
|
"""Liste des ids de départements"""
|
||||||
return jsonify([dept.id for dept in Departement.query])
|
return [dept.id for dept in Departement.query]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/<string:acronym>")
|
@bp.route("/departement/<string:acronym>")
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def departement(acronym: str):
|
def departement(acronym: str):
|
||||||
"""
|
"""
|
||||||
Info sur un département. Accès par acronyme.
|
Info sur un département. Accès par acronyme.
|
||||||
@ -74,25 +78,27 @@ def departement(acronym: str):
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
||||||
return jsonify(dept.to_dict(with_dept_name=True))
|
return dept.to_dict(with_dept_name=True)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/id/<int:dept_id>")
|
@bp.route("/departement/id/<int:dept_id>")
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def departement_by_id(dept_id: int):
|
def departement_by_id(dept_id: int):
|
||||||
"""
|
"""
|
||||||
Info sur un département. Accès par id.
|
Info sur un département. Accès par id.
|
||||||
"""
|
"""
|
||||||
dept = Departement.query.get_or_404(dept_id)
|
dept = Departement.query.get_or_404(dept_id)
|
||||||
return jsonify(dept.to_dict())
|
return dept.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/create", methods=["POST"])
|
@bp.route("/departement/create", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def departement_create():
|
def departement_create():
|
||||||
"""
|
"""
|
||||||
Création d'un département.
|
Création d'un département.
|
||||||
@ -111,13 +117,14 @@ def departement_create():
|
|||||||
dept = departements.create_dept(acronym, visible=visible)
|
dept = departements.create_dept(acronym, visible=visible)
|
||||||
except ScoValueError as exc:
|
except ScoValueError as exc:
|
||||||
return json_error(500, exc.args[0] if exc.args else "")
|
return json_error(500, exc.args[0] if exc.args else "")
|
||||||
return jsonify(dept.to_dict())
|
return dept.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/<string:acronym>/edit", methods=["POST"])
|
@bp.route("/departement/<string:acronym>/edit", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def departement_edit(acronym):
|
def departement_edit(acronym):
|
||||||
"""
|
"""
|
||||||
Edition d'un département: seul visible peut être modifié
|
Edition d'un département: seul visible peut être modifié
|
||||||
@ -135,7 +142,7 @@ def departement_edit(acronym):
|
|||||||
dept.visible = visible
|
dept.visible = visible
|
||||||
db.session.add(dept)
|
db.session.add(dept)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(dept.to_dict())
|
return dept.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/<string:acronym>/delete", methods=["POST"])
|
@bp.route("/departement/<string:acronym>/delete", methods=["POST"])
|
||||||
@ -149,13 +156,14 @@ def departement_delete(acronym):
|
|||||||
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
||||||
db.session.delete(dept)
|
db.session.delete(dept)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify({"OK": True})
|
return {"OK": True}
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/<string:acronym>/etudiants", methods=["GET"])
|
@bp.route("/departement/<string:acronym>/etudiants", methods=["GET"])
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def dept_etudiants(acronym: str):
|
def dept_etudiants(acronym: str):
|
||||||
"""
|
"""
|
||||||
Retourne la liste des étudiants d'un département
|
Retourne la liste des étudiants d'un département
|
||||||
@ -179,45 +187,49 @@ def dept_etudiants(acronym: str):
|
|||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
||||||
return jsonify([etud.to_dict_short() for etud in dept.etudiants])
|
return [etud.to_dict_short() for etud in dept.etudiants]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/id/<int:dept_id>/etudiants")
|
@bp.route("/departement/id/<int:dept_id>/etudiants")
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def dept_etudiants_by_id(dept_id: int):
|
def dept_etudiants_by_id(dept_id: int):
|
||||||
"""
|
"""
|
||||||
Retourne la liste des étudiants d'un département d'id donné.
|
Retourne la liste des étudiants d'un département d'id donné.
|
||||||
"""
|
"""
|
||||||
dept = Departement.query.get_or_404(dept_id)
|
dept = Departement.query.get_or_404(dept_id)
|
||||||
return jsonify([etud.to_dict_short() for etud in dept.etudiants])
|
return [etud.to_dict_short() for etud in dept.etudiants]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/<string:acronym>/formsemestres_ids")
|
@bp.route("/departement/<string:acronym>/formsemestres_ids")
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def dept_formsemestres_ids(acronym: str):
|
def dept_formsemestres_ids(acronym: str):
|
||||||
"""liste des ids formsemestre du département"""
|
"""liste des ids formsemestre du département"""
|
||||||
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
||||||
return jsonify([formsemestre.id for formsemestre in dept.formsemestres])
|
return [formsemestre.id for formsemestre in dept.formsemestres]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/id/<int:dept_id>/formsemestres_ids")
|
@bp.route("/departement/id/<int:dept_id>/formsemestres_ids")
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def dept_formsemestres_ids_by_id(dept_id: int):
|
def dept_formsemestres_ids_by_id(dept_id: int):
|
||||||
"""liste des ids formsemestre du département"""
|
"""liste des ids formsemestre du département"""
|
||||||
dept = Departement.query.get_or_404(dept_id)
|
dept = Departement.query.get_or_404(dept_id)
|
||||||
return jsonify([formsemestre.id for formsemestre in dept.formsemestres])
|
return [formsemestre.id for formsemestre in dept.formsemestres]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/<string:acronym>/formsemestres_courants")
|
@bp.route("/departement/<string:acronym>/formsemestres_courants")
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def dept_formsemestres_courants(acronym: str):
|
def dept_formsemestres_courants(acronym: str):
|
||||||
"""
|
"""
|
||||||
Liste des semestres actifs d'un département d'acronyme donné
|
Liste des semestres actifs d'un département d'acronyme donné
|
||||||
@ -269,13 +281,14 @@ def dept_formsemestres_courants(acronym: str):
|
|||||||
FormSemestre.date_debut <= test_date,
|
FormSemestre.date_debut <= test_date,
|
||||||
FormSemestre.date_fin >= test_date,
|
FormSemestre.date_fin >= test_date,
|
||||||
)
|
)
|
||||||
return jsonify([d.to_dict_api() for d in formsemestres])
|
return [d.to_dict_api() for d in formsemestres]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/id/<int:dept_id>/formsemestres_courants")
|
@bp.route("/departement/id/<int:dept_id>/formsemestres_courants")
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def dept_formsemestres_courants_by_id(dept_id: int):
|
def dept_formsemestres_courants_by_id(dept_id: int):
|
||||||
"""
|
"""
|
||||||
Liste des semestres actifs d'un département d'id donné
|
Liste des semestres actifs d'un département d'id donné
|
||||||
@ -294,4 +307,4 @@ def dept_formsemestres_courants_by_id(dept_id: int):
|
|||||||
FormSemestre.date_fin >= test_date,
|
FormSemestre.date_fin >= test_date,
|
||||||
)
|
)
|
||||||
|
|
||||||
return jsonify([d.to_dict_api() for d in formsemestres])
|
return [d.to_dict_api() for d in formsemestres]
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"""
|
"""
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from flask import abort, g, jsonify, request
|
from flask import g, request
|
||||||
|
from flask_json import as_json
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
from sqlalchemy import desc, or_
|
from sqlalchemy import desc, or_
|
||||||
@ -37,11 +38,11 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
# @login_required
|
# @login_required
|
||||||
# @scodoc
|
# @scodoc
|
||||||
# @permission_required(Permission.ScoView)
|
# @permission_required(Permission.ScoView)
|
||||||
|
# @as_json
|
||||||
# def api_function(arg: int):
|
# def api_function(arg: int):
|
||||||
# """Une fonction quelconque de l'API"""
|
# """Une fonction quelconque de l'API"""
|
||||||
# return jsonify(
|
# return {"current_user": current_user.to_dict(), "arg": arg, "dept": g.scodoc_dept}
|
||||||
# {"current_user": current_user.to_dict(), "arg": arg, "dept": g.scodoc_dept}
|
#
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/etudiants/courants", defaults={"long": False})
|
@bp.route("/etudiants/courants", defaults={"long": False})
|
||||||
@ -51,6 +52,7 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def etudiants_courants(long=False):
|
def etudiants_courants(long=False):
|
||||||
"""
|
"""
|
||||||
La liste des étudiants des semestres "courants" (tous départements)
|
La liste des étudiants des semestres "courants" (tous départements)
|
||||||
@ -96,7 +98,7 @@ def etudiants_courants(long=False):
|
|||||||
data = [etud.to_dict_api() for etud in etuds]
|
data = [etud.to_dict_api() for etud in etuds]
|
||||||
else:
|
else:
|
||||||
data = [etud.to_dict_short() for etud in etuds]
|
data = [etud.to_dict_short() for etud in etuds]
|
||||||
return jsonify(data)
|
return data
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/etudiant/etudid/<int:etudid>")
|
@bp.route("/etudiant/etudid/<int:etudid>")
|
||||||
@ -108,6 +110,7 @@ def etudiants_courants(long=False):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def etudiant(etudid: int = None, nip: str = None, ine: str = None):
|
def etudiant(etudid: int = None, nip: str = None, ine: str = None):
|
||||||
"""
|
"""
|
||||||
Retourne les informations de l'étudiant correspondant, ou 404 si non trouvé.
|
Retourne les informations de l'étudiant correspondant, ou 404 si non trouvé.
|
||||||
@ -127,7 +130,7 @@ def etudiant(etudid: int = None, nip: str = None, ine: str = None):
|
|||||||
message="étudiant inconnu",
|
message="étudiant inconnu",
|
||||||
)
|
)
|
||||||
|
|
||||||
return jsonify(etud.to_dict_api())
|
return etud.to_dict_api()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/etudiants/etudid/<int:etudid>", methods=["GET"])
|
@bp.route("/etudiants/etudid/<int:etudid>", methods=["GET"])
|
||||||
@ -138,6 +141,7 @@ def etudiant(etudid: int = None, nip: str = None, ine: str = None):
|
|||||||
@api_web_bp.route("/etudiants/ine/<string:ine>", methods=["GET"])
|
@api_web_bp.route("/etudiants/ine/<string:ine>", methods=["GET"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def etudiants(etudid: int = None, nip: str = None, ine: str = None):
|
def etudiants(etudid: int = None, nip: str = None, ine: str = None):
|
||||||
"""
|
"""
|
||||||
Info sur le ou les étudiants correspondant. Comme /etudiant mais renvoie
|
Info sur le ou les étudiants correspondant. Comme /etudiant mais renvoie
|
||||||
@ -163,7 +167,7 @@ def etudiants(etudid: int = None, nip: str = None, ine: str = None):
|
|||||||
etuds = etuds.join(Departement).filter(
|
etuds = etuds.join(Departement).filter(
|
||||||
or_(Departement.acronym == acronym for acronym in allowed_depts)
|
or_(Departement.acronym == acronym for acronym in allowed_depts)
|
||||||
)
|
)
|
||||||
return jsonify([etud.to_dict_api() for etud in query])
|
return [etud.to_dict_api() for etud in query]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/etudiant/etudid/<int:etudid>/formsemestres")
|
@bp.route("/etudiant/etudid/<int:etudid>/formsemestres")
|
||||||
@ -174,6 +178,7 @@ def etudiants(etudid: int = None, nip: str = None, ine: str = None):
|
|||||||
@api_web_bp.route("/etudiant/ine/<string:ine>/formsemestres")
|
@api_web_bp.route("/etudiant/ine/<string:ine>/formsemestres")
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None):
|
def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None):
|
||||||
"""
|
"""
|
||||||
Liste des semestres qu'un étudiant a suivi, triés par ordre chronologique.
|
Liste des semestres qu'un étudiant a suivi, triés par ordre chronologique.
|
||||||
@ -206,7 +211,7 @@ def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None)
|
|||||||
|
|
||||||
formsemestres = query.order_by(FormSemestre.date_debut)
|
formsemestres = query.order_by(FormSemestre.date_debut)
|
||||||
|
|
||||||
return jsonify([formsemestre.to_dict_api() for formsemestre in formsemestres])
|
return [formsemestre.to_dict_api() for formsemestre in formsemestres]
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
@ -265,7 +270,7 @@ def bulletin(
|
|||||||
formsemestre = FormSemestre.query.filter_by(id=formsemestre_id).first_or_404()
|
formsemestre = FormSemestre.query.filter_by(id=formsemestre_id).first_or_404()
|
||||||
dept = Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()
|
dept = Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()
|
||||||
if g.scodoc_dept and dept.acronym != g.scodoc_dept:
|
if g.scodoc_dept and dept.acronym != g.scodoc_dept:
|
||||||
return json_error(404, "formsemestre inexistant")
|
return json_error(404, "formsemestre inexistant", as_response=True)
|
||||||
app.set_sco_dept(dept.acronym)
|
app.set_sco_dept(dept.acronym)
|
||||||
|
|
||||||
if code_type == "nip":
|
if code_type == "nip":
|
||||||
@ -303,6 +308,7 @@ def bulletin(
|
|||||||
)
|
)
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def etudiant_groups(formsemestre_id: int, etudid: int = None):
|
def etudiant_groups(formsemestre_id: int, etudid: int = None):
|
||||||
"""
|
"""
|
||||||
Retourne la liste des groupes auxquels appartient l'étudiant dans le formsemestre indiqué
|
Retourne la liste des groupes auxquels appartient l'étudiant dans le formsemestre indiqué
|
||||||
@ -352,4 +358,4 @@ def etudiant_groups(formsemestre_id: int, etudid: int = None):
|
|||||||
app.set_sco_dept(dept.acronym)
|
app.set_sco_dept(dept.acronym)
|
||||||
data = sco_groups.get_etud_groups(etud.id, formsemestre.id)
|
data = sco_groups.get_etud_groups(etud.id, formsemestre.id)
|
||||||
|
|
||||||
return jsonify(data)
|
return data
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
ScoDoc 9 API : accès aux évaluations
|
ScoDoc 9 API : accès aux évaluations
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from flask import g, jsonify
|
from flask import g
|
||||||
|
from flask_json import as_json
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
import app
|
import app
|
||||||
@ -26,7 +27,8 @@ import app.scodoc.sco_utils as scu
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
def evaluation(evaluation_id: int):
|
@as_json
|
||||||
|
def the_eval(evaluation_id: int):
|
||||||
"""Description d'une évaluation.
|
"""Description d'une évaluation.
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -56,7 +58,7 @@ def evaluation(evaluation_id: int):
|
|||||||
.filter_by(dept_id=g.scodoc_dept_id)
|
.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
)
|
)
|
||||||
e = query.first_or_404()
|
e = query.first_or_404()
|
||||||
return jsonify(e.to_dict_api())
|
return e.to_dict_api()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/moduleimpl/<int:moduleimpl_id>/evaluations")
|
@bp.route("/moduleimpl/<int:moduleimpl_id>/evaluations")
|
||||||
@ -64,6 +66,7 @@ def evaluation(evaluation_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def evaluations(moduleimpl_id: int):
|
def evaluations(moduleimpl_id: int):
|
||||||
"""
|
"""
|
||||||
Retourne la liste des évaluations d'un moduleimpl
|
Retourne la liste des évaluations d'un moduleimpl
|
||||||
@ -79,7 +82,7 @@ def evaluations(moduleimpl_id: int):
|
|||||||
.join(FormSemestre)
|
.join(FormSemestre)
|
||||||
.filter_by(dept_id=g.scodoc_dept_id)
|
.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
)
|
)
|
||||||
return jsonify([e.to_dict_api() for e in query])
|
return [e.to_dict_api() for e in query]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/evaluation/<int:evaluation_id>/notes")
|
@bp.route("/evaluation/<int:evaluation_id>/notes")
|
||||||
@ -87,6 +90,7 @@ def evaluations(moduleimpl_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def evaluation_notes(evaluation_id: int):
|
def evaluation_notes(evaluation_id: int):
|
||||||
"""
|
"""
|
||||||
Retourne la liste des notes à partir de l'id d'une évaluation donnée
|
Retourne la liste des notes à partir de l'id d'une évaluation donnée
|
||||||
@ -124,8 +128,8 @@ def evaluation_notes(evaluation_id: int):
|
|||||||
.filter_by(dept_id=g.scodoc_dept_id)
|
.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
evaluation = query.first_or_404()
|
the_eval = query.first_or_404()
|
||||||
dept = evaluation.moduleimpl.formsemestre.departement
|
dept = the_eval.moduleimpl.formsemestre.departement
|
||||||
app.set_sco_dept(dept.acronym)
|
app.set_sco_dept(dept.acronym)
|
||||||
|
|
||||||
notes = sco_evaluation_db.do_evaluation_get_all_notes(evaluation_id)
|
notes = sco_evaluation_db.do_evaluation_get_all_notes(evaluation_id)
|
||||||
@ -133,7 +137,7 @@ def evaluation_notes(evaluation_id: int):
|
|||||||
# "ABS", "EXC", etc mais laisse les notes sur le barème de l'éval.
|
# "ABS", "EXC", etc mais laisse les notes sur le barème de l'éval.
|
||||||
note = notes[etudid]
|
note = notes[etudid]
|
||||||
note["value"] = scu.fmt_note(note["value"], keep_numeric=True)
|
note["value"] = scu.fmt_note(note["value"], keep_numeric=True)
|
||||||
note["note_max"] = evaluation.note_max
|
note["note_max"] = the_eval.note_max
|
||||||
del note["id"]
|
del note["id"]
|
||||||
|
|
||||||
return jsonify(notes)
|
return notes
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
ScoDoc 9 API : accès aux formations
|
ScoDoc 9 API : accès aux formations
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from flask import g, jsonify, request
|
from flask import g, request
|
||||||
|
from flask_json import as_json
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
import app
|
import app
|
||||||
@ -18,7 +19,6 @@ from app.scodoc.sco_utils import json_error
|
|||||||
from app.decorators import scodoc, permission_required
|
from app.decorators import scodoc, permission_required
|
||||||
from app.models import ApcParcours, Formation, FormSemestre, ModuleImpl, UniteEns
|
from app.models import ApcParcours, Formation, FormSemestre, ModuleImpl, UniteEns
|
||||||
from app.scodoc import sco_formations
|
from app.scodoc import sco_formations
|
||||||
from app.scodoc.sco_exceptions import ScoFormationConflict
|
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
@ -27,6 +27,7 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def formations():
|
def formations():
|
||||||
"""
|
"""
|
||||||
Retourne la liste de toutes les formations (tous départements)
|
Retourne la liste de toutes les formations (tous départements)
|
||||||
@ -35,7 +36,7 @@ def formations():
|
|||||||
if g.scodoc_dept:
|
if g.scodoc_dept:
|
||||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
|
|
||||||
return jsonify([d.to_dict() for d in query])
|
return [d.to_dict() for d in query]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formations_ids")
|
@bp.route("/formations_ids")
|
||||||
@ -43,6 +44,7 @@ def formations():
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def formations_ids():
|
def formations_ids():
|
||||||
"""
|
"""
|
||||||
Retourne la liste de toutes les id de formations (tous départements)
|
Retourne la liste de toutes les id de formations (tous départements)
|
||||||
@ -52,7 +54,7 @@ def formations_ids():
|
|||||||
query = Formation.query
|
query = Formation.query
|
||||||
if g.scodoc_dept:
|
if g.scodoc_dept:
|
||||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
return jsonify([d.id for d in query])
|
return [d.id for d in query]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formation/<int:formation_id>")
|
@bp.route("/formation/<int:formation_id>")
|
||||||
@ -60,6 +62,7 @@ def formations_ids():
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def formation_by_id(formation_id: int):
|
def formation_by_id(formation_id: int):
|
||||||
"""
|
"""
|
||||||
La formation d'id donné
|
La formation d'id donné
|
||||||
@ -84,7 +87,7 @@ def formation_by_id(formation_id: int):
|
|||||||
query = Formation.query.filter_by(id=formation_id)
|
query = Formation.query.filter_by(id=formation_id)
|
||||||
if g.scodoc_dept:
|
if g.scodoc_dept:
|
||||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
return jsonify(query.first_or_404().to_dict())
|
return query.first_or_404().to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
@ -106,6 +109,7 @@ def formation_by_id(formation_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def formation_export_by_formation_id(formation_id: int, export_ids=False):
|
def formation_export_by_formation_id(formation_id: int, export_ids=False):
|
||||||
"""
|
"""
|
||||||
Retourne la formation, avec UE, matières, modules
|
Retourne la formation, avec UE, matières, modules
|
||||||
@ -212,7 +216,7 @@ def formation_export_by_formation_id(formation_id: int, export_ids=False):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
return json_error(500, message="Erreur inconnue")
|
return json_error(500, message="Erreur inconnue")
|
||||||
|
|
||||||
return jsonify(data)
|
return data
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formation/<int:formation_id>/referentiel_competences")
|
@bp.route("/formation/<int:formation_id>/referentiel_competences")
|
||||||
@ -220,6 +224,7 @@ def formation_export_by_formation_id(formation_id: int, export_ids=False):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def referentiel_competences(formation_id: int):
|
def referentiel_competences(formation_id: int):
|
||||||
"""
|
"""
|
||||||
Retourne le référentiel de compétences
|
Retourne le référentiel de compétences
|
||||||
@ -233,8 +238,8 @@ def referentiel_competences(formation_id: int):
|
|||||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
formation = query.first_or_404(formation_id)
|
formation = query.first_or_404(formation_id)
|
||||||
if formation.referentiel_competence is None:
|
if formation.referentiel_competence is None:
|
||||||
return jsonify(None)
|
return None
|
||||||
return jsonify(formation.referentiel_competence.to_dict())
|
return formation.referentiel_competence.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/moduleimpl/<int:moduleimpl_id>")
|
@bp.route("/moduleimpl/<int:moduleimpl_id>")
|
||||||
@ -242,6 +247,7 @@ def referentiel_competences(formation_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def moduleimpl(moduleimpl_id: int):
|
def moduleimpl(moduleimpl_id: int):
|
||||||
"""
|
"""
|
||||||
Retourne un moduleimpl en fonction de son id
|
Retourne un moduleimpl en fonction de son id
|
||||||
@ -281,7 +287,7 @@ def moduleimpl(moduleimpl_id: int):
|
|||||||
if g.scodoc_dept:
|
if g.scodoc_dept:
|
||||||
query = query.join(FormSemestre).filter_by(dept_id=g.scodoc_dept_id)
|
query = query.join(FormSemestre).filter_by(dept_id=g.scodoc_dept_id)
|
||||||
modimpl: ModuleImpl = query.first_or_404()
|
modimpl: ModuleImpl = query.first_or_404()
|
||||||
return jsonify(modimpl.to_dict(convert_objects=True))
|
return modimpl.to_dict(convert_objects=True)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/set_ue_parcours/<int:ue_id>", methods=["POST"])
|
@bp.route("/set_ue_parcours/<int:ue_id>", methods=["POST"])
|
||||||
@ -289,6 +295,7 @@ def moduleimpl(moduleimpl_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoChangeFormation)
|
@permission_required(Permission.ScoChangeFormation)
|
||||||
|
@as_json
|
||||||
def set_ue_parcours(ue_id: int):
|
def set_ue_parcours(ue_id: int):
|
||||||
"""Associe UE et parcours BUT.
|
"""Associe UE et parcours BUT.
|
||||||
La liste des ids de parcours est passée en argument JSON.
|
La liste des ids de parcours est passée en argument JSON.
|
||||||
@ -307,4 +314,4 @@ def set_ue_parcours(ue_id: int):
|
|||||||
]
|
]
|
||||||
log(f"set_ue_parcours: ue_id={ue.id} parcours_ids={parcours_ids}")
|
log(f"set_ue_parcours: ue_id={ue.id} parcours_ids={parcours_ids}")
|
||||||
ok, error_message = ue.set_parcours(parcours)
|
ok, error_message = ue.set_parcours(parcours)
|
||||||
return jsonify({"status": ok, "message": error_message})
|
return {"status": ok, "message": error_message}
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"""
|
"""
|
||||||
from operator import attrgetter, itemgetter
|
from operator import attrgetter, itemgetter
|
||||||
|
|
||||||
from flask import g, jsonify, request
|
from flask import g, request
|
||||||
|
from flask_json import as_json
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
import app
|
import app
|
||||||
@ -42,6 +43,7 @@ from app.tables.recap import TableRecap
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def formsemestre_infos(formsemestre_id: int):
|
def formsemestre_infos(formsemestre_id: int):
|
||||||
"""
|
"""
|
||||||
Information sur le formsemestre indiqué.
|
Information sur le formsemestre indiqué.
|
||||||
@ -83,7 +85,7 @@ def formsemestre_infos(formsemestre_id: int):
|
|||||||
if g.scodoc_dept:
|
if g.scodoc_dept:
|
||||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
formsemestre: FormSemestre = query.first_or_404(formsemestre_id)
|
formsemestre: FormSemestre = query.first_or_404(formsemestre_id)
|
||||||
return jsonify(formsemestre.to_dict_api())
|
return formsemestre.to_dict_api()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestres/query")
|
@bp.route("/formsemestres/query")
|
||||||
@ -91,6 +93,7 @@ def formsemestre_infos(formsemestre_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def formsemestres_query():
|
def formsemestres_query():
|
||||||
"""
|
"""
|
||||||
Retourne les formsemestres filtrés par
|
Retourne les formsemestres filtrés par
|
||||||
@ -146,7 +149,7 @@ def formsemestres_query():
|
|||||||
formsemestres = formsemestres.join(FormSemestreInscription).join(Identite)
|
formsemestres = formsemestres.join(FormSemestreInscription).join(Identite)
|
||||||
formsemestres = formsemestres.filter_by(code_ine=ine)
|
formsemestres = formsemestres.filter_by(code_ine=ine)
|
||||||
|
|
||||||
return jsonify([formsemestre.to_dict_api() for formsemestre in formsemestres])
|
return [formsemestre.to_dict_api() for formsemestre in formsemestres]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestre/<int:formsemestre_id>/bulletins")
|
@bp.route("/formsemestre/<int:formsemestre_id>/bulletins")
|
||||||
@ -156,6 +159,7 @@ def formsemestres_query():
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def bulletins(formsemestre_id: int, version: str = "long"):
|
def bulletins(formsemestre_id: int, version: str = "long"):
|
||||||
"""
|
"""
|
||||||
Retourne les bulletins d'un formsemestre donné
|
Retourne les bulletins d'un formsemestre donné
|
||||||
@ -179,7 +183,7 @@ def bulletins(formsemestre_id: int, version: str = "long"):
|
|||||||
)
|
)
|
||||||
data.append(bul_etu.json)
|
data.append(bul_etu.json)
|
||||||
|
|
||||||
return jsonify(data)
|
return data
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestre/<int:formsemestre_id>/programme")
|
@bp.route("/formsemestre/<int:formsemestre_id>/programme")
|
||||||
@ -187,6 +191,7 @@ def bulletins(formsemestre_id: int, version: str = "long"):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def formsemestre_programme(formsemestre_id: int):
|
def formsemestre_programme(formsemestre_id: int):
|
||||||
"""
|
"""
|
||||||
Retourne la liste des Ues, ressources et SAE d'un semestre
|
Retourne la liste des Ues, ressources et SAE d'un semestre
|
||||||
@ -266,15 +271,13 @@ def formsemestre_programme(formsemestre_id: int):
|
|||||||
for modimpl in formsemestre.modimpls_sorted:
|
for modimpl in formsemestre.modimpls_sorted:
|
||||||
d = modimpl.to_dict(convert_objects=True)
|
d = modimpl.to_dict(convert_objects=True)
|
||||||
m_list[modimpl.module.module_type].append(d)
|
m_list[modimpl.module.module_type].append(d)
|
||||||
return jsonify(
|
return {
|
||||||
{
|
|
||||||
"ues": [ue.to_dict(convert_objects=True) for ue in ues],
|
"ues": [ue.to_dict(convert_objects=True) for ue in ues],
|
||||||
"ressources": m_list[ModuleType.RESSOURCE],
|
"ressources": m_list[ModuleType.RESSOURCE],
|
||||||
"saes": m_list[ModuleType.SAE],
|
"saes": m_list[ModuleType.SAE],
|
||||||
"modules": m_list[ModuleType.STANDARD],
|
"modules": m_list[ModuleType.STANDARD],
|
||||||
"malus": m_list[ModuleType.MALUS],
|
"malus": m_list[ModuleType.MALUS],
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
@ -312,6 +315,7 @@ def formsemestre_programme(formsemestre_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def formsemestre_etudiants(
|
def formsemestre_etudiants(
|
||||||
formsemestre_id: int, with_query: bool = False, long: bool = False
|
formsemestre_id: int, with_query: bool = False, long: bool = False
|
||||||
):
|
):
|
||||||
@ -347,7 +351,7 @@ def formsemestre_etudiants(
|
|||||||
etud["id"], formsemestre_id, exclude_default=True
|
etud["id"], formsemestre_id, exclude_default=True
|
||||||
)
|
)
|
||||||
|
|
||||||
return jsonify(sorted(etuds, key=itemgetter("sort_key")))
|
return sorted(etuds, key=itemgetter("sort_key"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestre/<int:formsemestre_id>/etat_evals")
|
@bp.route("/formsemestre/<int:formsemestre_id>/etat_evals")
|
||||||
@ -355,6 +359,7 @@ def formsemestre_etudiants(
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def etat_evals(formsemestre_id: int):
|
def etat_evals(formsemestre_id: int):
|
||||||
"""
|
"""
|
||||||
Informations sur l'état des évaluations d'un formsemestre.
|
Informations sur l'état des évaluations d'un formsemestre.
|
||||||
@ -456,7 +461,7 @@ def etat_evals(formsemestre_id: int):
|
|||||||
|
|
||||||
modimpl_dict["evaluations"] = list_eval
|
modimpl_dict["evaluations"] = list_eval
|
||||||
result.append(modimpl_dict)
|
result.append(modimpl_dict)
|
||||||
return jsonify(result)
|
return result
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestre/<int:formsemestre_id>/resultats")
|
@bp.route("/formsemestre/<int:formsemestre_id>/resultats")
|
||||||
@ -464,6 +469,7 @@ def etat_evals(formsemestre_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def formsemestre_resultat(formsemestre_id: int):
|
def formsemestre_resultat(formsemestre_id: int):
|
||||||
"""Tableau récapitulatif des résultats
|
"""Tableau récapitulatif des résultats
|
||||||
Pour chaque étudiant, son état, ses groupes, ses moyennes d'UE et de modules.
|
Pour chaque étudiant, son état, ses groupes, ses moyennes d'UE et de modules.
|
||||||
@ -489,4 +495,4 @@ def formsemestre_resultat(formsemestre_id: int):
|
|||||||
for row in rows:
|
for row in rows:
|
||||||
row["partitions"] = etud_groups.get(row["etudid"], {})
|
row["partitions"] = etud_groups.get(row["etudid"], {})
|
||||||
|
|
||||||
return jsonify(rows)
|
return rows
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
ScoDoc 9 API : jury WIP
|
ScoDoc 9 API : jury WIP
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from flask import jsonify
|
from flask_json import as_json
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
import app
|
import app
|
||||||
@ -25,6 +25,7 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def decisions_jury(formsemestre_id: int):
|
def decisions_jury(formsemestre_id: int):
|
||||||
"""Décisions du jury des étudiants du formsemestre."""
|
"""Décisions du jury des étudiants du formsemestre."""
|
||||||
# APC, pair:
|
# APC, pair:
|
||||||
@ -32,6 +33,6 @@ def decisions_jury(formsemestre_id: int):
|
|||||||
if formsemestre.formation.is_apc():
|
if formsemestre.formation.is_apc():
|
||||||
app.set_sco_dept(formsemestre.departement.acronym)
|
app.set_sco_dept(formsemestre.departement.acronym)
|
||||||
rows = jury_but_results.get_jury_but_results(formsemestre)
|
rows = jury_but_results.get_jury_but_results(formsemestre)
|
||||||
return jsonify(rows)
|
return rows
|
||||||
else:
|
else:
|
||||||
raise ScoException("non implemente")
|
raise ScoException("non implemente")
|
||||||
|
@ -30,11 +30,10 @@ Contrib @jmp
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from flask import jsonify, g, send_file
|
from flask import Response, send_file
|
||||||
from flask_login import login_required
|
from flask_json import as_json
|
||||||
|
|
||||||
from app.api import api_bp as bp, api_web_bp
|
from app.api import api_bp as bp
|
||||||
from app.api import requested_format
|
|
||||||
from app.scodoc.sco_utils import json_error
|
from app.scodoc.sco_utils import json_error
|
||||||
from app.models import Departement
|
from app.models import Departement
|
||||||
from app.scodoc.sco_logos import list_logos, find_logo
|
from app.scodoc.sco_logos import list_logos, find_logo
|
||||||
@ -47,10 +46,11 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
@bp.route("/logos")
|
@bp.route("/logos")
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def api_get_glob_logos():
|
def api_get_glob_logos():
|
||||||
"""Liste tous les logos"""
|
"""Liste tous les logos"""
|
||||||
logos = list_logos()[None]
|
logos = list_logos()[None]
|
||||||
return jsonify(list(logos.keys()))
|
return list(logos.keys())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/logo/<string:logoname>")
|
@bp.route("/logo/<string:logoname>")
|
||||||
@ -68,27 +68,29 @@ def api_get_glob_logo(logoname):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def core_get_logos(dept_id):
|
def _core_get_logos(dept_id) -> list:
|
||||||
logos = list_logos().get(dept_id, dict())
|
logos = list_logos().get(dept_id, dict())
|
||||||
return jsonify(list(logos.keys()))
|
return list(logos.keys())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/<string:departement>/logos")
|
@bp.route("/departement/<string:departement>/logos")
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def api_get_local_logos_by_acronym(departement):
|
def api_get_local_logos_by_acronym(departement):
|
||||||
dept_id = Departement.from_acronym(departement).id
|
dept_id = Departement.from_acronym(departement).id
|
||||||
return core_get_logos(dept_id)
|
return _core_get_logos(dept_id)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/id/<int:dept_id>/logos")
|
@bp.route("/departement/id/<int:dept_id>/logos")
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def api_get_local_logos_by_id(dept_id):
|
def api_get_local_logos_by_id(dept_id):
|
||||||
return core_get_logos(dept_id)
|
return _core_get_logos(dept_id)
|
||||||
|
|
||||||
|
|
||||||
def core_get_logo(dept_id, logoname):
|
def _core_get_logo(dept_id, logoname) -> Response:
|
||||||
logo = find_logo(logoname=logoname, dept_id=dept_id)
|
logo = find_logo(logoname=logoname, dept_id=dept_id)
|
||||||
if logo is None:
|
if logo is None:
|
||||||
return json_error(404, message="logo not found")
|
return json_error(404, message="logo not found")
|
||||||
@ -105,11 +107,11 @@ def core_get_logo(dept_id, logoname):
|
|||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
def api_get_local_logo_dept_by_acronym(departement, logoname):
|
def api_get_local_logo_dept_by_acronym(departement, logoname):
|
||||||
dept_id = Departement.from_acronym(departement).id
|
dept_id = Departement.from_acronym(departement).id
|
||||||
return core_get_logo(dept_id, logoname)
|
return _core_get_logo(dept_id, logoname)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/id/<int:dept_id>/logo/<string:logoname>")
|
@bp.route("/departement/id/<int:dept_id>/logo/<string:logoname>")
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
def api_get_local_logo_dept_by_id(dept_id, logoname):
|
def api_get_local_logo_dept_by_id(dept_id, logoname):
|
||||||
return core_get_logo(dept_id, logoname)
|
return _core_get_logo(dept_id, logoname)
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"""
|
"""
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
|
||||||
from flask import g, jsonify, request
|
from flask import g, request
|
||||||
|
from flask_json import as_json
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
import app
|
import app
|
||||||
@ -31,6 +32,7 @@ from app.scodoc import sco_utils as scu
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def partition_info(partition_id: int):
|
def partition_info(partition_id: int):
|
||||||
"""Info sur une partition.
|
"""Info sur une partition.
|
||||||
|
|
||||||
@ -55,7 +57,7 @@ def partition_info(partition_id: int):
|
|||||||
if g.scodoc_dept:
|
if g.scodoc_dept:
|
||||||
query = query.join(FormSemestre).filter_by(dept_id=g.scodoc_dept_id)
|
query = query.join(FormSemestre).filter_by(dept_id=g.scodoc_dept_id)
|
||||||
partition = query.first_or_404()
|
partition = query.first_or_404()
|
||||||
return jsonify(partition.to_dict(with_groups=True))
|
return partition.to_dict(with_groups=True)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestre/<int:formsemestre_id>/partitions")
|
@bp.route("/formsemestre/<int:formsemestre_id>/partitions")
|
||||||
@ -63,6 +65,7 @@ def partition_info(partition_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def formsemestre_partitions(formsemestre_id: int):
|
def formsemestre_partitions(formsemestre_id: int):
|
||||||
"""Liste de toutes les partitions d'un formsemestre
|
"""Liste de toutes les partitions d'un formsemestre
|
||||||
|
|
||||||
@ -88,13 +91,11 @@ def formsemestre_partitions(formsemestre_id: int):
|
|||||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
formsemestre: FormSemestre = query.first_or_404(formsemestre_id)
|
formsemestre: FormSemestre = query.first_or_404(formsemestre_id)
|
||||||
partitions = sorted(formsemestre.partitions, key=attrgetter("numero"))
|
partitions = sorted(formsemestre.partitions, key=attrgetter("numero"))
|
||||||
return jsonify(
|
return {
|
||||||
{
|
|
||||||
partition.id: partition.to_dict(with_groups=True)
|
partition.id: partition.to_dict(with_groups=True)
|
||||||
for partition in partitions
|
for partition in partitions
|
||||||
if partition.partition_name is not None
|
if partition.partition_name is not None
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/group/<int:group_id>/etudiants")
|
@bp.route("/group/<int:group_id>/etudiants")
|
||||||
@ -102,6 +103,7 @@ def formsemestre_partitions(formsemestre_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def etud_in_group(group_id: int):
|
def etud_in_group(group_id: int):
|
||||||
"""
|
"""
|
||||||
Retourne la liste des étudiants dans un groupe
|
Retourne la liste des étudiants dans un groupe
|
||||||
@ -128,7 +130,7 @@ def etud_in_group(group_id: int):
|
|||||||
query.join(Partition).join(FormSemestre).filter_by(dept_id=g.scodoc_dept_id)
|
query.join(Partition).join(FormSemestre).filter_by(dept_id=g.scodoc_dept_id)
|
||||||
)
|
)
|
||||||
group = query.first_or_404()
|
group = query.first_or_404()
|
||||||
return jsonify([etud.to_dict_short() for etud in group.etuds])
|
return [etud.to_dict_short() for etud in group.etuds]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/group/<int:group_id>/etudiants/query")
|
@bp.route("/group/<int:group_id>/etudiants/query")
|
||||||
@ -136,6 +138,7 @@ def etud_in_group(group_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def etud_in_group_query(group_id: int):
|
def etud_in_group_query(group_id: int):
|
||||||
"""Étudiants du groupe, filtrés par état"""
|
"""Étudiants du groupe, filtrés par état"""
|
||||||
etat = request.args.get("etat")
|
etat = request.args.get("etat")
|
||||||
@ -156,7 +159,7 @@ def etud_in_group_query(group_id: int):
|
|||||||
|
|
||||||
query = query.join(group_membership).filter_by(group_id=group_id)
|
query = query.join(group_membership).filter_by(group_id=group_id)
|
||||||
|
|
||||||
return jsonify([etud.to_dict_short() for etud in query])
|
return [etud.to_dict_short() for etud in query]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/group/<int:group_id>/set_etudiant/<int:etudid>", methods=["POST"])
|
@bp.route("/group/<int:group_id>/set_etudiant/<int:etudid>", methods=["POST"])
|
||||||
@ -164,6 +167,7 @@ def etud_in_group_query(group_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def set_etud_group(etudid: int, group_id: int):
|
def set_etud_group(etudid: int, group_id: int):
|
||||||
"""Affecte l'étudiant au groupe indiqué"""
|
"""Affecte l'étudiant au groupe indiqué"""
|
||||||
etud = Identite.query.get_or_404(etudid)
|
etud = Identite.query.get_or_404(etudid)
|
||||||
@ -182,7 +186,7 @@ def set_etud_group(etudid: int, group_id: int):
|
|||||||
etudid, group_id, group.partition.to_dict()
|
etudid, group_id, group.partition.to_dict()
|
||||||
)
|
)
|
||||||
|
|
||||||
return jsonify({"group_id": group_id, "etudid": etudid})
|
return {"group_id": group_id, "etudid": etudid}
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/group/<int:group_id>/remove_etudiant/<int:etudid>", methods=["POST"])
|
@bp.route("/group/<int:group_id>/remove_etudiant/<int:etudid>", methods=["POST"])
|
||||||
@ -192,6 +196,7 @@ def set_etud_group(etudid: int, group_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def group_remove_etud(group_id: int, etudid: int):
|
def group_remove_etud(group_id: int, etudid: int):
|
||||||
"""Retire l'étudiant de ce groupe. S'il n'y est pas, ne fait rien."""
|
"""Retire l'étudiant de ce groupe. S'il n'y est pas, ne fait rien."""
|
||||||
etud = Identite.query.get_or_404(etudid)
|
etud = Identite.query.get_or_404(etudid)
|
||||||
@ -215,7 +220,7 @@ def group_remove_etud(group_id: int, etudid: int):
|
|||||||
# Update parcours
|
# Update parcours
|
||||||
group.partition.formsemestre.update_inscriptions_parcours_from_groups()
|
group.partition.formsemestre.update_inscriptions_parcours_from_groups()
|
||||||
sco_cache.invalidate_formsemestre(group.partition.formsemestre_id)
|
sco_cache.invalidate_formsemestre(group.partition.formsemestre_id)
|
||||||
return jsonify({"group_id": group_id, "etudid": etudid})
|
return {"group_id": group_id, "etudid": etudid}
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
@ -227,6 +232,7 @@ def group_remove_etud(group_id: int, etudid: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def partition_remove_etud(partition_id: int, etudid: int):
|
def partition_remove_etud(partition_id: int, etudid: int):
|
||||||
"""Enlève l'étudiant de tous les groupes de cette partition
|
"""Enlève l'étudiant de tous les groupes de cette partition
|
||||||
(NB: en principe, un étudiant ne doit être que dans 0 ou 1 groupe d'une partition)
|
(NB: en principe, un étudiant ne doit être que dans 0 ou 1 groupe d'une partition)
|
||||||
@ -256,7 +262,7 @@ def partition_remove_etud(partition_id: int, etudid: int):
|
|||||||
partition.formsemestre.update_inscriptions_parcours_from_groups()
|
partition.formsemestre.update_inscriptions_parcours_from_groups()
|
||||||
app.set_sco_dept(partition.formsemestre.departement.acronym)
|
app.set_sco_dept(partition.formsemestre.departement.acronym)
|
||||||
sco_cache.invalidate_formsemestre(partition.formsemestre_id)
|
sco_cache.invalidate_formsemestre(partition.formsemestre_id)
|
||||||
return jsonify({"partition_id": partition_id, "etudid": etudid})
|
return {"partition_id": partition_id, "etudid": etudid}
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/partition/<int:partition_id>/group/create", methods=["POST"])
|
@bp.route("/partition/<int:partition_id>/group/create", methods=["POST"])
|
||||||
@ -264,6 +270,7 @@ def partition_remove_etud(partition_id: int, etudid: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def group_create(partition_id: int):
|
def group_create(partition_id: int):
|
||||||
"""Création d'un groupe dans une partition
|
"""Création d'un groupe dans une partition
|
||||||
|
|
||||||
@ -294,7 +301,7 @@ def group_create(partition_id: int):
|
|||||||
log(f"created group {group}")
|
log(f"created group {group}")
|
||||||
app.set_sco_dept(partition.formsemestre.departement.acronym)
|
app.set_sco_dept(partition.formsemestre.departement.acronym)
|
||||||
sco_cache.invalidate_formsemestre(partition.formsemestre_id)
|
sco_cache.invalidate_formsemestre(partition.formsemestre_id)
|
||||||
return jsonify(group.to_dict(with_partition=True))
|
return group.to_dict(with_partition=True)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/group/<int:group_id>/delete", methods=["POST"])
|
@bp.route("/group/<int:group_id>/delete", methods=["POST"])
|
||||||
@ -302,6 +309,7 @@ def group_create(partition_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def group_delete(group_id: int):
|
def group_delete(group_id: int):
|
||||||
"""Suppression d'un groupe"""
|
"""Suppression d'un groupe"""
|
||||||
query = GroupDescr.query.filter_by(id=group_id)
|
query = GroupDescr.query.filter_by(id=group_id)
|
||||||
@ -320,7 +328,7 @@ def group_delete(group_id: int):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
app.set_sco_dept(group.partition.formsemestre.departement.acronym)
|
app.set_sco_dept(group.partition.formsemestre.departement.acronym)
|
||||||
sco_cache.invalidate_formsemestre(formsemestre_id)
|
sco_cache.invalidate_formsemestre(formsemestre_id)
|
||||||
return jsonify({"OK": True})
|
return {"OK": True}
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/group/<int:group_id>/edit", methods=["POST"])
|
@bp.route("/group/<int:group_id>/edit", methods=["POST"])
|
||||||
@ -328,6 +336,7 @@ def group_delete(group_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def group_edit(group_id: int):
|
def group_edit(group_id: int):
|
||||||
"""Edit a group"""
|
"""Edit a group"""
|
||||||
query = GroupDescr.query.filter_by(id=group_id)
|
query = GroupDescr.query.filter_by(id=group_id)
|
||||||
@ -352,7 +361,7 @@ def group_edit(group_id: int):
|
|||||||
log(f"modified {group}")
|
log(f"modified {group}")
|
||||||
app.set_sco_dept(group.partition.formsemestre.departement.acronym)
|
app.set_sco_dept(group.partition.formsemestre.departement.acronym)
|
||||||
sco_cache.invalidate_formsemestre(group.partition.formsemestre_id)
|
sco_cache.invalidate_formsemestre(group.partition.formsemestre_id)
|
||||||
return jsonify(group.to_dict(with_partition=True))
|
return group.to_dict(with_partition=True)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestre/<int:formsemestre_id>/partition/create", methods=["POST"])
|
@bp.route("/formsemestre/<int:formsemestre_id>/partition/create", methods=["POST"])
|
||||||
@ -362,6 +371,7 @@ def group_edit(group_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def partition_create(formsemestre_id: int):
|
def partition_create(formsemestre_id: int):
|
||||||
"""Création d'une partition dans un semestre
|
"""Création d'une partition dans un semestre
|
||||||
|
|
||||||
@ -414,7 +424,7 @@ def partition_create(formsemestre_id: int):
|
|||||||
log(f"created partition {partition}")
|
log(f"created partition {partition}")
|
||||||
app.set_sco_dept(formsemestre.departement.acronym)
|
app.set_sco_dept(formsemestre.departement.acronym)
|
||||||
sco_cache.invalidate_formsemestre(formsemestre_id)
|
sco_cache.invalidate_formsemestre(formsemestre_id)
|
||||||
return jsonify(partition.to_dict(with_groups=True))
|
return partition.to_dict(with_groups=True)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestre/<int:formsemestre_id>/partitions/order", methods=["POST"])
|
@bp.route("/formsemestre/<int:formsemestre_id>/partitions/order", methods=["POST"])
|
||||||
@ -424,6 +434,7 @@ def partition_create(formsemestre_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def formsemestre_order_partitions(formsemestre_id: int):
|
def formsemestre_order_partitions(formsemestre_id: int):
|
||||||
"""Modifie l'ordre des partitions du formsemestre
|
"""Modifie l'ordre des partitions du formsemestre
|
||||||
JSON args: [partition_id1, partition_id2, ...]
|
JSON args: [partition_id1, partition_id2, ...]
|
||||||
@ -449,13 +460,11 @@ def formsemestre_order_partitions(formsemestre_id: int):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
app.set_sco_dept(formsemestre.departement.acronym)
|
app.set_sco_dept(formsemestre.departement.acronym)
|
||||||
sco_cache.invalidate_formsemestre(formsemestre_id)
|
sco_cache.invalidate_formsemestre(formsemestre_id)
|
||||||
return jsonify(
|
return [
|
||||||
[
|
|
||||||
partition.to_dict()
|
partition.to_dict()
|
||||||
for partition in formsemestre.partitions.order_by(Partition.numero)
|
for partition in formsemestre.partitions.order_by(Partition.numero)
|
||||||
if partition.partition_name is not None
|
if partition.partition_name is not None
|
||||||
]
|
]
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/partition/<int:partition_id>/groups/order", methods=["POST"])
|
@bp.route("/partition/<int:partition_id>/groups/order", methods=["POST"])
|
||||||
@ -463,6 +472,7 @@ def formsemestre_order_partitions(formsemestre_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def partition_order_groups(partition_id: int):
|
def partition_order_groups(partition_id: int):
|
||||||
"""Modifie l'ordre des groupes de la partition
|
"""Modifie l'ordre des groupes de la partition
|
||||||
JSON args: [group_id1, group_id2, ...]
|
JSON args: [group_id1, group_id2, ...]
|
||||||
@ -489,7 +499,7 @@ def partition_order_groups(partition_id: int):
|
|||||||
app.set_sco_dept(partition.formsemestre.departement.acronym)
|
app.set_sco_dept(partition.formsemestre.departement.acronym)
|
||||||
sco_cache.invalidate_formsemestre(partition.formsemestre_id)
|
sco_cache.invalidate_formsemestre(partition.formsemestre_id)
|
||||||
log(f"partition_order_groups: {partition} : {group_ids}")
|
log(f"partition_order_groups: {partition} : {group_ids}")
|
||||||
return jsonify(partition.to_dict(with_groups=True))
|
return partition.to_dict(with_groups=True)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/partition/<int:partition_id>/edit", methods=["POST"])
|
@bp.route("/partition/<int:partition_id>/edit", methods=["POST"])
|
||||||
@ -497,6 +507,7 @@ def partition_order_groups(partition_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def partition_edit(partition_id: int):
|
def partition_edit(partition_id: int):
|
||||||
"""Modification d'une partition dans un semestre
|
"""Modification d'une partition dans un semestre
|
||||||
|
|
||||||
@ -558,7 +569,7 @@ def partition_edit(partition_id: int):
|
|||||||
app.set_sco_dept(partition.formsemestre.departement.acronym)
|
app.set_sco_dept(partition.formsemestre.departement.acronym)
|
||||||
sco_cache.invalidate_formsemestre(partition.formsemestre_id)
|
sco_cache.invalidate_formsemestre(partition.formsemestre_id)
|
||||||
|
|
||||||
return jsonify(partition.to_dict(with_groups=True))
|
return partition.to_dict(with_groups=True)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/partition/<int:partition_id>/delete", methods=["POST"])
|
@bp.route("/partition/<int:partition_id>/delete", methods=["POST"])
|
||||||
@ -566,6 +577,7 @@ def partition_edit(partition_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoEtudChangeGroups)
|
@permission_required(Permission.ScoEtudChangeGroups)
|
||||||
|
@as_json
|
||||||
def partition_delete(partition_id: int):
|
def partition_delete(partition_id: int):
|
||||||
"""Suppression d'une partition (et de tous ses groupes).
|
"""Suppression d'une partition (et de tous ses groupes).
|
||||||
|
|
||||||
@ -593,4 +605,4 @@ def partition_delete(partition_id: int):
|
|||||||
sco_cache.invalidate_formsemestre(formsemestre.id)
|
sco_cache.invalidate_formsemestre(formsemestre.id)
|
||||||
if is_parcours:
|
if is_parcours:
|
||||||
formsemestre.update_inscriptions_parcours_from_groups()
|
formsemestre.update_inscriptions_parcours_from_groups()
|
||||||
return jsonify({"OK": True})
|
return {"OK": True}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from flask import jsonify
|
from flask_json import as_json
|
||||||
from app import db, log
|
from app import db, log
|
||||||
from app.api import api_bp as bp
|
from app.api import api_bp as bp
|
||||||
from app.auth.logic import basic_auth, token_auth
|
from app.auth.logic import basic_auth, token_auth
|
||||||
@ -6,12 +6,13 @@ from app.auth.logic import basic_auth, token_auth
|
|||||||
|
|
||||||
@bp.route("/tokens", methods=["POST"])
|
@bp.route("/tokens", methods=["POST"])
|
||||||
@basic_auth.login_required
|
@basic_auth.login_required
|
||||||
|
@as_json
|
||||||
def get_token():
|
def get_token():
|
||||||
"renvoie un jeton jwt pour l'utilisateur courant"
|
"renvoie un jeton jwt pour l'utilisateur courant"
|
||||||
token = basic_auth.current_user().get_token()
|
token = basic_auth.current_user().get_token()
|
||||||
log(f"API: giving token to {basic_auth.current_user()}")
|
log(f"API: giving token to {basic_auth.current_user()}")
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify({"token": token})
|
return {"token": token}
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/tokens", methods=["DELETE"])
|
@bp.route("/tokens", methods=["DELETE"])
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from flask import g, jsonify, request
|
from flask import g, request
|
||||||
|
from flask_json import as_json
|
||||||
from flask_login import current_user, login_required
|
from flask_login import current_user, login_required
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
@ -29,6 +30,7 @@ from app.scodoc import sco_utils as scu
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoUsersView)
|
@permission_required(Permission.ScoUsersView)
|
||||||
|
@as_json
|
||||||
def user_info(uid: int):
|
def user_info(uid: int):
|
||||||
"""
|
"""
|
||||||
Info sur un compte utilisateur scodoc
|
Info sur un compte utilisateur scodoc
|
||||||
@ -41,7 +43,7 @@ def user_info(uid: int):
|
|||||||
if (None not in allowed_depts) and (user.dept not in allowed_depts):
|
if (None not in allowed_depts) and (user.dept not in allowed_depts):
|
||||||
return json_error(404, "user not found")
|
return json_error(404, "user not found")
|
||||||
|
|
||||||
return jsonify(user.to_dict())
|
return user.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/users/query")
|
@bp.route("/users/query")
|
||||||
@ -49,6 +51,7 @@ def user_info(uid: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def users_info_query():
|
def users_info_query():
|
||||||
"""Utilisateurs, filtrés par dept, active ou début nom
|
"""Utilisateurs, filtrés par dept, active ou début nom
|
||||||
/users/query?departement=dept_acronym&active=1&starts_with=<string:nom>
|
/users/query?departement=dept_acronym&active=1&starts_with=<string:nom>
|
||||||
@ -79,7 +82,7 @@ def users_info_query():
|
|||||||
)
|
)
|
||||||
|
|
||||||
query = query.order_by(User.user_name)
|
query = query.order_by(User.user_name)
|
||||||
return jsonify([user.to_dict() for user in query])
|
return [user.to_dict() for user in query]
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/user/create", methods=["POST"])
|
@bp.route("/user/create", methods=["POST"])
|
||||||
@ -87,6 +90,7 @@ def users_info_query():
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoUsersAdmin)
|
@permission_required(Permission.ScoUsersAdmin)
|
||||||
|
@as_json
|
||||||
def user_create():
|
def user_create():
|
||||||
"""Création d'un utilisateur
|
"""Création d'un utilisateur
|
||||||
The request content type should be "application/json":
|
The request content type should be "application/json":
|
||||||
@ -121,7 +125,7 @@ def user_create():
|
|||||||
user = User(user_name=user_name, active=active, dept=dept, nom=nom, prenom=prenom)
|
user = User(user_name=user_name, active=active, dept=dept, nom=nom, prenom=prenom)
|
||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(user.to_dict())
|
return user.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/user/<int:uid>/edit", methods=["POST"])
|
@bp.route("/user/<int:uid>/edit", methods=["POST"])
|
||||||
@ -129,6 +133,7 @@ def user_create():
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoUsersAdmin)
|
@permission_required(Permission.ScoUsersAdmin)
|
||||||
|
@as_json
|
||||||
def user_edit(uid: int):
|
def user_edit(uid: int):
|
||||||
"""Modification d'un utilisateur
|
"""Modification d'un utilisateur
|
||||||
Champs modifiables:
|
Champs modifiables:
|
||||||
@ -165,7 +170,7 @@ def user_edit(uid: int):
|
|||||||
|
|
||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(user.to_dict())
|
return user.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/user/<int:uid>/password", methods=["POST"])
|
@bp.route("/user/<int:uid>/password", methods=["POST"])
|
||||||
@ -173,6 +178,7 @@ def user_edit(uid: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoUsersAdmin)
|
@permission_required(Permission.ScoUsersAdmin)
|
||||||
|
@as_json
|
||||||
def user_password(uid: int):
|
def user_password(uid: int):
|
||||||
"""Modification du mot de passe d'un utilisateur
|
"""Modification du mot de passe d'un utilisateur
|
||||||
Champs modifiables:
|
Champs modifiables:
|
||||||
@ -194,7 +200,7 @@ def user_password(uid: int):
|
|||||||
user.set_password(password)
|
user.set_password(password)
|
||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(user.to_dict())
|
return user.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/user/<int:uid>/role/<string:role_name>/add", methods=["POST"])
|
@bp.route("/user/<int:uid>/role/<string:role_name>/add", methods=["POST"])
|
||||||
@ -210,6 +216,7 @@ def user_password(uid: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def user_role_add(uid: int, role_name: str, dept: str = None):
|
def user_role_add(uid: int, role_name: str, dept: str = None):
|
||||||
"""Add a role to the user"""
|
"""Add a role to the user"""
|
||||||
user: User = User.query.get_or_404(uid)
|
user: User = User.query.get_or_404(uid)
|
||||||
@ -222,7 +229,7 @@ def user_role_add(uid: int, role_name: str, dept: str = None):
|
|||||||
user.add_role(role, dept)
|
user.add_role(role, dept)
|
||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(user.to_dict())
|
return user.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/user/<int:uid>/role/<string:role_name>/remove", methods=["POST"])
|
@bp.route("/user/<int:uid>/role/<string:role_name>/remove", methods=["POST"])
|
||||||
@ -238,6 +245,7 @@ def user_role_add(uid: int, role_name: str, dept: str = None):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def user_role_remove(uid: int, role_name: str, dept: str = None):
|
def user_role_remove(uid: int, role_name: str, dept: str = None):
|
||||||
"""Remove the role from the user"""
|
"""Remove the role from the user"""
|
||||||
user: User = User.query.get_or_404(uid)
|
user: User = User.query.get_or_404(uid)
|
||||||
@ -256,7 +264,7 @@ def user_role_remove(uid: int, role_name: str, dept: str = None):
|
|||||||
db.session.delete(user_role)
|
db.session.delete(user_role)
|
||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(user.to_dict())
|
return user.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/permissions")
|
@bp.route("/permissions")
|
||||||
@ -264,9 +272,10 @@ def user_role_remove(uid: int, role_name: str, dept: str = None):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoUsersView)
|
@permission_required(Permission.ScoUsersView)
|
||||||
|
@as_json
|
||||||
def list_permissions():
|
def list_permissions():
|
||||||
"""Liste des noms de permissions définies"""
|
"""Liste des noms de permissions définies"""
|
||||||
return jsonify(list(Permission.permission_by_name.keys()))
|
return list(Permission.permission_by_name.keys())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/role/<string:role_name>")
|
@bp.route("/role/<string:role_name>")
|
||||||
@ -274,9 +283,10 @@ def list_permissions():
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoUsersView)
|
@permission_required(Permission.ScoUsersView)
|
||||||
|
@as_json
|
||||||
def list_role(role_name: str):
|
def list_role(role_name: str):
|
||||||
"""Un rôle"""
|
"""Un rôle"""
|
||||||
return jsonify(Role.query.filter_by(name=role_name).first_or_404().to_dict())
|
return Role.query.filter_by(name=role_name).first_or_404().to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/roles")
|
@bp.route("/roles")
|
||||||
@ -284,9 +294,10 @@ def list_role(role_name: str):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoUsersView)
|
@permission_required(Permission.ScoUsersView)
|
||||||
|
@as_json
|
||||||
def list_roles():
|
def list_roles():
|
||||||
"""Tous les rôles définis"""
|
"""Tous les rôles définis"""
|
||||||
return jsonify([role.to_dict() for role in Role.query])
|
return [role.to_dict() for role in Role.query]
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
@ -300,6 +311,7 @@ def list_roles():
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def role_permission_add(role_name: str, perm_name: str):
|
def role_permission_add(role_name: str, perm_name: str):
|
||||||
"""Add permission to role"""
|
"""Add permission to role"""
|
||||||
role: Role = Role.query.filter_by(name=role_name).first_or_404()
|
role: Role = Role.query.filter_by(name=role_name).first_or_404()
|
||||||
@ -309,7 +321,7 @@ def role_permission_add(role_name: str, perm_name: str):
|
|||||||
role.add_permission(permission)
|
role.add_permission(permission)
|
||||||
db.session.add(role)
|
db.session.add(role)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(role.to_dict())
|
return role.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
@ -323,6 +335,7 @@ def role_permission_add(role_name: str, perm_name: str):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def role_permission_remove(role_name: str, perm_name: str):
|
def role_permission_remove(role_name: str, perm_name: str):
|
||||||
"""Remove permission from role"""
|
"""Remove permission from role"""
|
||||||
role: Role = Role.query.filter_by(name=role_name).first_or_404()
|
role: Role = Role.query.filter_by(name=role_name).first_or_404()
|
||||||
@ -332,7 +345,7 @@ def role_permission_remove(role_name: str, perm_name: str):
|
|||||||
role.remove_permission(permission)
|
role.remove_permission(permission)
|
||||||
db.session.add(role)
|
db.session.add(role)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(role.to_dict())
|
return role.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/role/create/<string:role_name>", methods=["POST"])
|
@bp.route("/role/create/<string:role_name>", methods=["POST"])
|
||||||
@ -340,6 +353,7 @@ def role_permission_remove(role_name: str, perm_name: str):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def role_create(role_name: str):
|
def role_create(role_name: str):
|
||||||
"""Create a new role with permissions.
|
"""Create a new role with permissions.
|
||||||
{
|
{
|
||||||
@ -359,7 +373,7 @@ def role_create(role_name: str):
|
|||||||
return json_error(404, "role_create: invalid permissions")
|
return json_error(404, "role_create: invalid permissions")
|
||||||
db.session.add(role)
|
db.session.add(role)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(role.to_dict())
|
return role.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/role/<string:role_name>/edit", methods=["POST"])
|
@bp.route("/role/<string:role_name>/edit", methods=["POST"])
|
||||||
@ -367,6 +381,7 @@ def role_create(role_name: str):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def role_edit(role_name: str):
|
def role_edit(role_name: str):
|
||||||
"""Edit a role. On peut spécifier un nom et/ou des permissions.
|
"""Edit a role. On peut spécifier un nom et/ou des permissions.
|
||||||
{
|
{
|
||||||
@ -390,7 +405,7 @@ def role_edit(role_name: str):
|
|||||||
role.name = role_name
|
role.name = role_name
|
||||||
db.session.add(role)
|
db.session.add(role)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify(role.to_dict())
|
return role.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/role/<string:role_name>/delete", methods=["POST"])
|
@bp.route("/role/<string:role_name>/delete", methods=["POST"])
|
||||||
@ -398,9 +413,10 @@ def role_edit(role_name: str):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoSuperAdmin)
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
@as_json
|
||||||
def role_delete(role_name: str):
|
def role_delete(role_name: str):
|
||||||
"""Delete a role"""
|
"""Delete a role"""
|
||||||
role: Role = Role.query.filter_by(name=role_name).first_or_404()
|
role: Role = Role.query.filter_by(name=role_name).first_or_404()
|
||||||
db.session.delete(role)
|
db.session.delete(role)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify({"OK": True})
|
return {"OK": True}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import os
|
import os
|
||||||
from config import Config
|
from datetime import datetime
|
||||||
from datetime import datetime, date
|
|
||||||
import glob
|
import glob
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from flask import render_template, redirect, url_for, request, flash, send_file, abort
|
from flask import render_template, redirect, url_for, request, flash, send_file, abort
|
||||||
from flask.json import jsonify
|
from flask_json import as_json
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
from sqlalchemy import text, sql
|
||||||
|
from werkzeug.utils import secure_filename
|
||||||
|
|
||||||
from app.decorators import permission_required
|
from app.decorators import permission_required
|
||||||
|
|
||||||
@ -58,8 +59,7 @@ from app.scodoc import sco_etud, sco_excel
|
|||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
from sqlalchemy import text, sql
|
from config import Config
|
||||||
from werkzeug.utils import secure_filename
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/", methods=["GET", "POST"])
|
@bp.route("/", methods=["GET", "POST"])
|
||||||
@ -1698,6 +1698,7 @@ def envoyer_offre(entreprise_id, offre_id):
|
|||||||
|
|
||||||
@bp.route("/etudiants")
|
@bp.route("/etudiants")
|
||||||
@permission_required(Permission.RelationsEntreprisesChange)
|
@permission_required(Permission.RelationsEntreprisesChange)
|
||||||
|
@as_json
|
||||||
def json_etudiants():
|
def json_etudiants():
|
||||||
"""
|
"""
|
||||||
Permet de récuperer un JSON avec tous les étudiants
|
Permet de récuperer un JSON avec tous les étudiants
|
||||||
@ -1723,7 +1724,7 @@ def json_etudiants():
|
|||||||
"info": f"Département {are.get_dept_acronym_by_id(etudiant.dept_id)}",
|
"info": f"Département {are.get_dept_acronym_by_id(etudiant.dept_id)}",
|
||||||
}
|
}
|
||||||
list.append(content)
|
list.append(content)
|
||||||
return jsonify(results=list)
|
return list
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/responsables")
|
@bp.route("/responsables")
|
||||||
@ -1749,7 +1750,7 @@ def json_responsables():
|
|||||||
value = f"{responsable.get_nomplogin()}"
|
value = f"{responsable.get_nomplogin()}"
|
||||||
content = {"id": f"{responsable.id}", "value": value}
|
content = {"id": f"{responsable.id}", "value": value}
|
||||||
list.append(content)
|
list.append(content)
|
||||||
return jsonify(results=list)
|
return list
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/export_donnees")
|
@bp.route("/export_donnees")
|
||||||
@ -1843,7 +1844,7 @@ def import_donnees():
|
|||||||
db.session.add(correspondant)
|
db.session.add(correspondant)
|
||||||
correspondants.append(correspondant)
|
correspondants.append(correspondant)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(f"Importation réussie")
|
flash("Importation réussie")
|
||||||
return render_template(
|
return render_template(
|
||||||
"entreprises/import_donnees.j2",
|
"entreprises/import_donnees.j2",
|
||||||
title="Importation données",
|
title="Importation données",
|
||||||
|
@ -85,6 +85,7 @@ class ApcReferentielCompetences(db.Model, XMLModel):
|
|||||||
backref="referentiel",
|
backref="referentiel",
|
||||||
lazy="dynamic",
|
lazy="dynamic",
|
||||||
cascade="all, delete-orphan",
|
cascade="all, delete-orphan",
|
||||||
|
order_by="ApcParcours.numero, ApcParcours.code",
|
||||||
)
|
)
|
||||||
formations = db.relationship(
|
formations = db.relationship(
|
||||||
"Formation",
|
"Formation",
|
||||||
|
@ -275,6 +275,7 @@ DEVENIRS_NEXT2 = {NEXT_OR_NEXT2: 1, NEXT2: 1}
|
|||||||
|
|
||||||
NO_SEMESTRE_ID = -1 # code semestre si pas de semestres
|
NO_SEMESTRE_ID = -1 # code semestre si pas de semestres
|
||||||
|
|
||||||
|
|
||||||
# Règles gestion cursus
|
# Règles gestion cursus
|
||||||
class DUTRule(object):
|
class DUTRule(object):
|
||||||
def __init__(self, rule_id, premise, conclusion):
|
def __init__(self, rule_id, premise, conclusion):
|
||||||
@ -298,7 +299,7 @@ class DUTRule(object):
|
|||||||
|
|
||||||
|
|
||||||
# Types de cursus
|
# Types de cursus
|
||||||
DEFAULT_TYPE_CURSUS = 100 # pour le menu de creation nouvelle formation
|
DEFAULT_TYPE_CURSUS = 700 # (BUT) pour le menu de creation nouvelle formation
|
||||||
|
|
||||||
|
|
||||||
class TypeCursus:
|
class TypeCursus:
|
||||||
|
@ -33,8 +33,9 @@ import email
|
|||||||
import time
|
import time
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from flask import g, request
|
from flask import g, request, Response
|
||||||
from flask import flash, jsonify, render_template, url_for
|
from flask import flash, render_template, url_for
|
||||||
|
from flask_json import json_response
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app import email
|
from app import email
|
||||||
@ -79,14 +80,14 @@ def get_formsemestre_bulletin_etud_json(
|
|||||||
etud: Identite,
|
etud: Identite,
|
||||||
force_publishing=False,
|
force_publishing=False,
|
||||||
version="long",
|
version="long",
|
||||||
) -> str:
|
) -> Response:
|
||||||
"""Le JSON du bulletin d'un étudiant, quel que soit le type de formation."""
|
"""Le JSON du bulletin d'un étudiant, quel que soit le type de formation."""
|
||||||
if formsemestre.formation.is_apc():
|
if formsemestre.formation.is_apc():
|
||||||
bulletins_sem = bulletin_but.BulletinBUT(formsemestre)
|
bulletins_sem = bulletin_but.BulletinBUT(formsemestre)
|
||||||
if not etud.id in bulletins_sem.res.identdict:
|
if not etud.id in bulletins_sem.res.identdict:
|
||||||
return json_error(404, "get_formsemestre_bulletin_etud_json: invalid etud")
|
return json_error(404, "get_formsemestre_bulletin_etud_json: invalid etud")
|
||||||
return jsonify(
|
return json_response(
|
||||||
bulletins_sem.bulletin_etud(
|
data_=bulletins_sem.bulletin_etud(
|
||||||
etud,
|
etud,
|
||||||
formsemestre,
|
formsemestre,
|
||||||
force_publishing=force_publishing,
|
force_publishing=force_publishing,
|
||||||
|
@ -51,8 +51,9 @@ import pydot
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import g, request
|
from flask import g, request, Response
|
||||||
from flask import flash, url_for, make_response, jsonify
|
from flask import flash, url_for, make_response
|
||||||
|
from flask_json import json_response
|
||||||
from werkzeug.http import HTTP_STATUS_CODES
|
from werkzeug.http import HTTP_STATUS_CODES
|
||||||
|
|
||||||
from config import Config
|
from config import Config
|
||||||
@ -804,24 +805,26 @@ def get_request_args():
|
|||||||
return vals
|
return vals
|
||||||
|
|
||||||
|
|
||||||
def json_error(status_code, message=None):
|
def json_error(status_code, message=None) -> Response:
|
||||||
"""Simple JSON response, for errors"""
|
"""Simple JSON for errors.
|
||||||
|
If as-response, returns Flask's Response. Otherwise returns a dict.
|
||||||
|
"""
|
||||||
payload = {
|
payload = {
|
||||||
"error": HTTP_STATUS_CODES.get(status_code, "Unknown error"),
|
"error": HTTP_STATUS_CODES.get(status_code, "Unknown error"),
|
||||||
"status": status_code,
|
"status": status_code,
|
||||||
}
|
}
|
||||||
if message:
|
if message:
|
||||||
payload["message"] = message
|
payload["message"] = message
|
||||||
response = jsonify(payload)
|
response = json_response(status_=status_code, data_=payload)
|
||||||
response.status_code = status_code
|
response.status_code = status_code
|
||||||
log(f"Error: {response}")
|
log(f"Error: {response}")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def json_ok_response(status_code=200, payload=None):
|
def json_ok_response(status_code=200, payload=None) -> Response:
|
||||||
"""Simple JSON respons for "success" """
|
"""Simple JSON respons for "success" """
|
||||||
payload = payload or {"OK": True}
|
payload = payload or {"OK": True}
|
||||||
response = jsonify(payload)
|
response = json_response(status_=status_code, data_=payload)
|
||||||
response.status_code = status_code
|
response.status_code = status_code
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ from app.scodoc.sco_exceptions import ScoValueError
|
|||||||
class ApoEtapeVDI(object):
|
class ApoEtapeVDI(object):
|
||||||
_ETAPE_VDI_SEP = "!"
|
_ETAPE_VDI_SEP = "!"
|
||||||
|
|
||||||
def __init__(self, etape_vdi=None, etape="", vdi=""):
|
def __init__(self, etape_vdi: str = None, etape: str = "", vdi: str = ""):
|
||||||
"""Build from string representation, e.g. 'V1RT!111'"""
|
"""Build from string representation, e.g. 'V1RT!111'"""
|
||||||
if etape_vdi:
|
if etape_vdi:
|
||||||
self.etape_vdi = etape_vdi
|
self.etape_vdi = etape_vdi
|
||||||
@ -52,6 +52,10 @@ class ApoEtapeVDI(object):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.etape_vdi
|
return self.etape_vdi
|
||||||
|
|
||||||
|
def __json__(self) -> str:
|
||||||
|
"json repr for flask_json"
|
||||||
|
return str(self)
|
||||||
|
|
||||||
def _cmp(self, other):
|
def _cmp(self, other):
|
||||||
"""Test égalité de deux codes étapes.
|
"""Test égalité de deux codes étapes.
|
||||||
Si le VDI des deux est spécifié, on l'utilise. Sinon, seul le code étape est pris en compte.
|
Si le VDI des deux est spécifié, on l'utilise. Sinon, seul le code étape est pris en compte.
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
<li><a class="stdlink" href="{{
|
<li><a class="stdlink" href="{{
|
||||||
url_for('notes.ue_table', scodoc_dept=g.scodoc_dept, formation_id=formation.id )
|
url_for('notes.ue_table', scodoc_dept=g.scodoc_dept, formation_id=formation.id )
|
||||||
}}">{{ formation.get_titre_version() }}</a></li>
|
}}">{{ formation.get_titre_version() }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li><em>aucune</em></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
@ -32,10 +32,10 @@ Emmanuel Viennet, 2021
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
from flask import jsonify
|
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
from flask.templating import render_template
|
from flask_json import as_json
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
from flask.templating import render_template
|
||||||
from app.scodoc.codes_cursus import UE_SPORT
|
from app.scodoc.codes_cursus import UE_SPORT
|
||||||
|
|
||||||
|
|
||||||
@ -58,6 +58,7 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
)
|
)
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def table_modules_ue_coefs(formation_id, semestre_idx=None, parcours_id: int = None):
|
def table_modules_ue_coefs(formation_id, semestre_idx=None, parcours_id: int = None):
|
||||||
"""Description JSON de la table des coefs modules/UE dans une formation
|
"""Description JSON de la table des coefs modules/UE dans une formation
|
||||||
|
|
||||||
@ -111,10 +112,10 @@ def table_modules_ue_coefs(formation_id, semestre_idx=None, parcours_id: int = N
|
|||||||
]
|
]
|
||||||
# Les champs de saisie
|
# Les champs de saisie
|
||||||
cells = []
|
cells = []
|
||||||
for (row, mod) in enumerate(modules, start=2):
|
for row, mod in enumerate(modules, start=2):
|
||||||
style = "champs champs_" + scu.ModuleType(mod.module_type).name
|
style = "champs champs_" + scu.ModuleType(mod.module_type).name
|
||||||
mod_parcours_ids = {p.id for p in mod.parcours}
|
mod_parcours_ids = {p.id for p in mod.parcours}
|
||||||
for (col, ue) in enumerate(ues, start=2):
|
for col, ue in enumerate(ues, start=2):
|
||||||
# met en gris les coefs qui devraient être nuls
|
# met en gris les coefs qui devraient être nuls
|
||||||
# car le module n'est pas dans le parcours de l'UE:
|
# car le module n'est pas dans le parcours de l'UE:
|
||||||
if (
|
if (
|
||||||
@ -136,7 +137,7 @@ def table_modules_ue_coefs(formation_id, semestre_idx=None, parcours_id: int = N
|
|||||||
"ue_id": ue.id,
|
"ue_id": ue.id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return jsonify(col_titres_mods + row_titres_ue + cells)
|
return col_titres_mods + row_titres_ue + cells
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/set_module_ue_coef", methods=["POST"])
|
@bp.route("/set_module_ue_coef", methods=["POST"])
|
||||||
|
@ -6,10 +6,11 @@ Emmanuel Viennet, 2021
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from flask import jsonify, flash, url_for
|
from flask import flash, url_for
|
||||||
from flask import Markup
|
from flask import Markup
|
||||||
from flask import current_app, g, request
|
from flask import current_app, g, request
|
||||||
from flask.templating import render_template
|
from flask.templating import render_template
|
||||||
|
from flask_json import as_json
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from werkzeug.utils import redirect
|
from werkzeug.utils import redirect
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
@ -33,12 +34,13 @@ from app.views import ScoData
|
|||||||
@bp.route("/referentiel/comp/get/<int:refcomp_id>")
|
@bp.route("/referentiel/comp/get/<int:refcomp_id>")
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def refcomp(refcomp_id):
|
def refcomp(refcomp_id):
|
||||||
"""Le référentiel de compétences, en JSON."""
|
"""Le référentiel de compétences, en JSON."""
|
||||||
ref: ApcReferentielCompetences = ApcReferentielCompetences.query.get_or_404(
|
ref: ApcReferentielCompetences = ApcReferentielCompetences.query.get_or_404(
|
||||||
refcomp_id
|
refcomp_id
|
||||||
)
|
)
|
||||||
return jsonify(ref.to_dict())
|
return ref.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/referentiel/comp/show/<int:refcomp_id>")
|
@bp.route("/referentiel/comp/show/<int:refcomp_id>")
|
||||||
|
@ -35,8 +35,9 @@ import requests
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import jsonify, url_for, flash, render_template, make_response
|
from flask import url_for, flash, render_template, make_response
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
|
from flask_json import as_json
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileAllowed
|
from flask_wtf.file import FileField, FileAllowed
|
||||||
@ -501,10 +502,11 @@ sco_publish(
|
|||||||
@bp.route("/Notes/search_etud_by_name") # for JS apis
|
@bp.route("/Notes/search_etud_by_name") # for JS apis
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
|
@as_json
|
||||||
def search_etud_by_name():
|
def search_etud_by_name():
|
||||||
term = request.args["term"]
|
term = request.args["term"]
|
||||||
data = sco_find_etud.search_etud_by_name(term)
|
data = sco_find_etud.search_etud_by_name(term)
|
||||||
return jsonify(data)
|
return data
|
||||||
|
|
||||||
|
|
||||||
# XMLgetEtudInfos était le nom dans l'ancienne API ScoDoc 6
|
# XMLgetEtudInfos était le nom dans l'ancienne API ScoDoc 6
|
||||||
@ -895,6 +897,7 @@ sco_publish(
|
|||||||
methods=["GET", "POST"],
|
methods=["GET", "POST"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Nouvel éditeur de partitions et groupe, @SebL Jul 2022
|
# Nouvel éditeur de partitions et groupe, @SebL Jul 2022
|
||||||
@bp.route("/partition_editor", methods=["GET", "POST"])
|
@bp.route("/partition_editor", methods=["GET", "POST"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@ -2266,7 +2269,7 @@ def formsemestre_import_etud_admission(formsemestre_id, import_email=True):
|
|||||||
)
|
)
|
||||||
if changed_mails:
|
if changed_mails:
|
||||||
H.append("<h3>Adresses mails modifiées:</h3>")
|
H.append("<h3>Adresses mails modifiées:</h3>")
|
||||||
for (info, new_mail) in changed_mails:
|
for info, new_mail in changed_mails:
|
||||||
H.append(
|
H.append(
|
||||||
"%s: <tt>%s</tt> devient <tt>%s</tt><br>"
|
"%s: <tt>%s</tt> devient <tt>%s</tt><br>"
|
||||||
% (info["nom"], info["email"], new_mail)
|
% (info["nom"], info["email"], new_mail)
|
||||||
@ -2286,6 +2289,7 @@ sco_publish(
|
|||||||
Permission.ScoEtudChangeAdr,
|
Permission.ScoEtudChangeAdr,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# --- Statistiques
|
# --- Statistiques
|
||||||
@bp.route("/stat_bac")
|
@bp.route("/stat_bac")
|
||||||
@scodoc
|
@scodoc
|
||||||
|
@ -38,6 +38,9 @@ class Config:
|
|||||||
SCODOC_ERR_FILE = os.path.join(SCODOC_VAR_DIR, "log", "scodoc_exc.log")
|
SCODOC_ERR_FILE = os.path.join(SCODOC_VAR_DIR, "log", "scodoc_exc.log")
|
||||||
#
|
#
|
||||||
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # Flask uploads (16Mo, en ligne avec nginx)
|
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # Flask uploads (16Mo, en ligne avec nginx)
|
||||||
|
# flask_json:
|
||||||
|
JSON_ADD_STATUS = False
|
||||||
|
JSON_USE_ENCODE_METHODS = True
|
||||||
|
|
||||||
|
|
||||||
class ProdConfig(Config):
|
class ProdConfig(Config):
|
||||||
|
@ -26,6 +26,7 @@ flask-babel==3.0.1
|
|||||||
Flask-Bootstrap==3.3.7.1
|
Flask-Bootstrap==3.3.7.1
|
||||||
Flask-Caching==2.0.2
|
Flask-Caching==2.0.2
|
||||||
Flask-HTTPAuth==4.7.0
|
Flask-HTTPAuth==4.7.0
|
||||||
|
Flask-JSON==0.3.5
|
||||||
Flask-Login==0.6.2
|
Flask-Login==0.6.2
|
||||||
Flask-Mail==0.9.1
|
Flask-Mail==0.9.1
|
||||||
Flask-Migrate==4.0.4
|
Flask-Migrate==4.0.4
|
||||||
|
@ -17,7 +17,6 @@ import os
|
|||||||
import requests
|
import requests
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import pytest
|
import pytest
|
||||||
from app.scodoc import sco_utils as scu
|
|
||||||
|
|
||||||
# --- Lecture configuration (variables d'env ou .env)
|
# --- Lecture configuration (variables d'env ou .env)
|
||||||
try:
|
try:
|
||||||
@ -34,6 +33,7 @@ API_PASSWORD = os.environ.get("API_PASSWORD", os.environ.get("API_PASSWD", "test
|
|||||||
API_USER_ADMIN = os.environ.get("API_USER_ADMIN", "admin_api")
|
API_USER_ADMIN = os.environ.get("API_USER_ADMIN", "admin_api")
|
||||||
API_PASSWORD_ADMIN = os.environ.get("API_PASSWD_ADMIN", "admin_api")
|
API_PASSWORD_ADMIN = os.environ.get("API_PASSWD_ADMIN", "admin_api")
|
||||||
DEPT_ACRONYM = "TAPI"
|
DEPT_ACRONYM = "TAPI"
|
||||||
|
SCO_TEST_API_TIMEOUT = 5
|
||||||
print(f"SCODOC_URL={SCODOC_URL}")
|
print(f"SCODOC_URL={SCODOC_URL}")
|
||||||
print(f"API URL={API_URL}")
|
print(f"API URL={API_URL}")
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ def GET(path: str, headers: dict = None, errmsg=None, dept=None):
|
|||||||
url,
|
url,
|
||||||
headers=headers or {},
|
headers=headers or {},
|
||||||
verify=CHECK_CERTIFICATE,
|
verify=CHECK_CERTIFICATE,
|
||||||
timeout=scu.SCO_TEST_API_TIMEOUT,
|
timeout=SCO_TEST_API_TIMEOUT,
|
||||||
)
|
)
|
||||||
if reply.status_code != 200:
|
if reply.status_code != 200:
|
||||||
raise APIError(
|
raise APIError(
|
||||||
@ -111,7 +111,7 @@ def POST_JSON(path: str, data: dict = {}, headers: dict = None, errmsg=None, dep
|
|||||||
json=data,
|
json=data,
|
||||||
headers=headers or {},
|
headers=headers or {},
|
||||||
verify=CHECK_CERTIFICATE,
|
verify=CHECK_CERTIFICATE,
|
||||||
timeout=10,
|
timeout=SCO_TEST_API_TIMEOUT,
|
||||||
)
|
)
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
raise APIError(errmsg or f"erreur status={r.status_code} !", r.json())
|
raise APIError(errmsg or f"erreur status={r.status_code} !", r.json())
|
||||||
|
@ -88,7 +88,9 @@ def test_permissions(api_headers):
|
|||||||
assert r.status_code == 401
|
assert r.status_code == 401
|
||||||
|
|
||||||
# Demande un jeton pour "other"
|
# Demande un jeton pour "other"
|
||||||
r = requests.post(API_URL + "/tokens", auth=("other", "other"), timeout=10)
|
r = requests.post(
|
||||||
|
API_URL + "/tokens", auth=("other", "other"), timeout=scu.SCO_TEST_API_TIMEOUT
|
||||||
|
)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
token = r.json()["token"]
|
token = r.json()["token"]
|
||||||
headers = {"Authorization": f"Bearer {token}"}
|
headers = {"Authorization": f"Bearer {token}"}
|
||||||
|
@ -1,526 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<formation acronyme="BUT INFO" titre_officiel="Bachelor Universitaire de Technologie" version="1" formation_code="FCOD49" code_specialite="" titre="BUT INFORMATIQUE" commentaire="" type_parcours="700" referentiel_competence_id="4" refcomp_version_orebut="2021-12-11 00:00:00" refcomp_specialite="INFO" refcomp_type_titre="B.U.T.">
|
|
||||||
<ue is_external="0" acronyme="UE11" code_apogee="V1INFU11" numero="0" coefficient="0.0" titre="Compétence 1 : Réaliser un développement d'application" coef_rcue="1.0" semestre_idx="1" color="#b80004" type="0" ue_code="UCOD62" ects="5.0" apc_niveau_libelle="Développer des applications informatiques simples " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1639">
|
|
||||||
<matiere titre="Portfolio" numero="0">
|
|
||||||
<module titre="Initiation au développement" abbrev="Initiation au dev." code="R1.01-A" heures_cours="0.0" heures_td="24.0" heures_tp="30.0" coefficient="66.0" ects="" semestre_id="1" numero="10" code_apogee="VINFR101" module_type="2">
|
|
||||||
<coefficients ue_reference="1638" coef="12.0"/>
|
|
||||||
<coefficients ue_reference="1639" coef="21.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Implémentation d'un besoin client" abbrev="Implémentation" code="S1.01" heures_cours="0.0" heures_td="2.0" heures_tp="2.0" coefficient="40.0" ects="" semestre_id="1" numero="10" code_apogee="VINFS101" module_type="3">
|
|
||||||
<coefficients ue_reference="1639" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE12" code_apogee="V1INFU12" numero="1" coefficient="0.0" titre="Compétence 2 : Optimiser des applications informatiques" coef_rcue="1.0" semestre_idx="1" color="#f97b3d" type="0" ue_code="UCOD61" ects="5.0" apc_niveau_libelle="Appréhender et construire des algorithmes " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1638">
|
|
||||||
<matiere titre="Ressource" numero="2">
|
|
||||||
<module titre="Initiation au développement" abbrev="Initiation au dev." code="R1.01-B" heures_cours="0.0" heures_td="16.0" heures_tp="24.0" coefficient="66.0" ects="" semestre_id="1" numero="20" code_apogee="VINFR101" module_type="2">
|
|
||||||
<coefficients ue_reference="1638" coef="12.0"/>
|
|
||||||
<coefficients ue_reference="1639" coef="21.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Comparaison d'approches algorithmiques" abbrev="Comparaison d'algo." code="S1.02" heures_cours="0.0" heures_td="2.0" heures_tp="2.0" coefficient="40.0" ects="" semestre_id="1" numero="20" code_apogee="VINFS102" module_type="3">
|
|
||||||
<coefficients ue_reference="1638" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Développement d'interfaces web" abbrev="Dev. interfaces web" code="R1.02" heures_cours="0.0" heures_td="5.0" heures_tp="14.0" coefficient="35.0" ects="" semestre_id="1" numero="30" code_apogee="VINFR102" module_type="2">
|
|
||||||
<coefficients ue_reference="1639" coef="12.0"/>
|
|
||||||
<coefficients ue_reference="1900" coef="18.0"/>
|
|
||||||
<coefficients ue_reference="1901" coef="5.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Mathématiques discrètes" abbrev="Maths discrètes" code="R1.06" heures_cours="0.0" heures_td="30.0" heures_tp="10.0" coefficient="33.0" ects="" semestre_id="1" numero="70" code_apogee="VINFR106" module_type="2">
|
|
||||||
<coefficients ue_reference="1638" coef="15.0"/>
|
|
||||||
<coefficients ue_reference="1885" coef="18.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Outils mathématiques fondamentaux" abbrev="Outils fondamentaux" code="R1.07" heures_cours="0.0" heures_td="14.0" heures_tp="10.0" coefficient="15.0" ects="" semestre_id="1" numero="80" code_apogee="VINFR107" module_type="2">
|
|
||||||
<coefficients ue_reference="1638" coef="15.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Gestion de projet & des organisations" abbrev="Gestion proj. orga." code="R1.08" heures_cours="0.0" heures_td="21.0" heures_tp="10.0" coefficient="38.0" ects="" semestre_id="1" numero="90" code_apogee="VINFR108" module_type="2">
|
|
||||||
<coefficients ue_reference="1900" coef="27.0"/>
|
|
||||||
<coefficients ue_reference="1901" coef="11.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE13" code_apogee="V1INFU13" numero="2" coefficient="0.0" titre="Compétence 3 : Administrer des systèmes informatiques communicants" coef_rcue="1.0" semestre_idx="1" color="#feb40b" type="0" ue_code="UCOD50" ects="5.0" apc_niveau_libelle="Installer et configurer un poste de travail " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1637">
|
|
||||||
<matiere titre="SAE" numero="1">
|
|
||||||
<module titre="Installation d'un poste pour le développement" abbrev="Installation poste" code="S1.03" heures_cours="0.0" heures_td="5.0" heures_tp="4.0" coefficient="40.0" ects="" semestre_id="1" numero="30" code_apogee="VINFS103" module_type="3">
|
|
||||||
<coefficients ue_reference="1637" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Introduction à l'architecture des ordinateurs" abbrev="Intro. archi." code="R1.03" heures_cours="0.0" heures_td="12.0" heures_tp="8.0" coefficient="24.0" ects="" semestre_id="1" numero="40" code_apogee="VINFR103" module_type="2">
|
|
||||||
<coefficients ue_reference="1637" coef="21.0"/>
|
|
||||||
<coefficients ue_reference="1638" coef="6.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Introduction aux systèmes d’exploitation et à leur fonctionnement" abbrev="Intro. systèmes" code="R1.04" heures_cours="0.0" heures_td="5.0" heures_tp="20.0" coefficient="24.0" ects="" semestre_id="1" numero="50" code_apogee="VINFR104" module_type="2">
|
|
||||||
<coefficients ue_reference="1637" coef="21.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE14" code_apogee="V1INFU14" numero="3" coefficient="0.0" titre="Compétence 4 : Gérer des données de l'information" coef_rcue="1.0" semestre_idx="1" color="#80cb3f" type="0" ue_code="UCOD10" ects="5.0" apc_niveau_libelle="Concevoir et mettre en place une base de données à partir d’un cahier des charges client " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1885">
|
|
||||||
<matiere titre="Ressources" numero="0">
|
|
||||||
<module titre="Création d'une base de données" abbrev="Création BD" code="S1.04" heures_cours="0.0" heures_td="4.0" heures_tp="2.0" coefficient="40.0" ects="" semestre_id="1" numero="40" code_apogee="VINFS104" module_type="3">
|
|
||||||
<coefficients ue_reference="1885" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Introduction aux bases de données et SQL" abbrev="Introduction BD" code="R1.05" heures_cours="12.0" heures_td="9.0" heures_tp="24.0" coefficient="36.0" ects="" semestre_id="1" numero="60" code_apogee="VINFR105" module_type="2">
|
|
||||||
<coefficients ue_reference="1885" coef="36.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE15" code_apogee="V1INFU15" numero="4" coefficient="0.0" titre="Compétence 5 : Conduire un projet" coef_rcue="1.0" semestre_idx="1" color="#05162e" type="0" ue_code="UCOD15" ects="5.0" apc_niveau_libelle="Identifier les besoins métiers des clients et des utilisateurs " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1900">
|
|
||||||
<matiere titre="Compétence 5 : Conduire un projet" numero="1">
|
|
||||||
<module titre="Recueil de besoins" abbrev="Recueil de besoins" code="S1.05" heures_cours="0.0" heures_td="4.0" heures_tp="2.0" coefficient="40.0" ects="" semestre_id="1" numero="50" code_apogee="VINFS105" module_type="3">
|
|
||||||
<coefficients ue_reference="1900" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Économie durable et numérique" abbrev="Économie" code="R1.09" heures_cours="0.0" heures_td="18.0" heures_tp="5.0" coefficient="17.0" ects="" semestre_id="1" numero="100" code_apogee="VINFR109" module_type="2">
|
|
||||||
<coefficients ue_reference="1885" coef="6.0"/>
|
|
||||||
<coefficients ue_reference="1901" coef="11.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE16" code_apogee="V1INFU16" numero="5" coefficient="0.0" titre="Compétence 6 : Travailler dans une équipe informatique" coef_rcue="1.0" semestre_idx="1" color="#548687" type="0" ue_code="UCOD16" ects="5.0" apc_niveau_libelle="Identifier ses aptitudes pour travailler dans une équipe " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1901">
|
|
||||||
<matiere titre="Compétence 6 : Travailler dans une équipe informatique" numero="1">
|
|
||||||
<module titre="Portfolio" abbrev="Portfolio" code="P1.01" heures_cours="0.0" heures_td="0.0" heures_tp="6.0" coefficient="0.0" ects="" semestre_id="1" numero="1" code_apogee="VINFPOR1" module_type="0"/>
|
|
||||||
<module titre="Découverte de l'environnement économique et écologique" abbrev="Environnement éco." code="S1.06" heures_cours="0.0" heures_td="0.0" heures_tp="6.0" coefficient="40.0" ects="" semestre_id="1" numero="60" code_apogee="VINFS106" module_type="3">
|
|
||||||
<coefficients ue_reference="1901" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Anglais technique" abbrev="Anglais technique" code="R1.10" heures_cours="0.0" heures_td="15.0" heures_tp="9.0" coefficient="29.0" ects="" semestre_id="1" numero="110" code_apogee="VINFR110" module_type="2">
|
|
||||||
<coefficients ue_reference="1637" coef="12.0"/>
|
|
||||||
<coefficients ue_reference="1639" coef="6.0"/>
|
|
||||||
<coefficients ue_reference="1901" coef="11.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Bases de la communication" abbrev="Bases de la comm" code="R1.11" heures_cours="0.0" heures_td="15.0" heures_tp="9.0" coefficient="32.0" ects="" semestre_id="1" numero="120" code_apogee="VINFR111" module_type="2">
|
|
||||||
<coefficients ue_reference="1637" coef="6.0"/>
|
|
||||||
<coefficients ue_reference="1900" coef="15.0"/>
|
|
||||||
<coefficients ue_reference="1901" coef="11.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Projet professionnel et personnel" abbrev="PPP" code="R1.12" heures_cours="0.0" heures_td="8.0" heures_tp="2.0" coefficient="11.0" ects="" semestre_id="1" numero="130" code_apogee="VINFR112" module_type="2">
|
|
||||||
<coefficients ue_reference="1901" coef="11.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE17" code_apogee="" numero="6" coefficient="0.0" titre="Sport/Culture" coef_rcue="1.0" semestre_idx="1" color="#444054" type="1" ue_code="X7.2" ects="0.0" reference="2472">
|
|
||||||
<matiere titre="Sport/Culture" numero="1">
|
|
||||||
<module titre="Sport / Culture" abbrev="Sport" code="X1.01" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="1" numero="520" code_apogee="" module_type="0"/>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE21" code_apogee="V1INFU21" numero="7" coefficient="0.0" titre="Compétence 1: Réaliser un développement d'application" coef_rcue="1.0" semestre_idx="2" color="#b80004" type="0" ue_code="UCOD17" ects="5.0" apc_niveau_libelle="Développer des applications informatiques simples " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1902">
|
|
||||||
<matiere titre="Compétence 1: Réaliser un développement d'application" numero="1">
|
|
||||||
<module titre="Développement orienté objets" abbrev="Développement orienté objets" code="R2.01" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="140" code_apogee="VINFR201" module_type="2">
|
|
||||||
<coefficients ue_reference="1902" coef="21.0"/>
|
|
||||||
<coefficients ue_reference="1903" coef="15.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Développement d'applications avec IHM" abbrev="Développement d'applications avec IHM" code="R2.02" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="150" code_apogee="VINFR202" module_type="2">
|
|
||||||
<coefficients ue_reference="1902" coef="21.0"/>
|
|
||||||
<coefficients ue_reference="1906" coef="3.0"/>
|
|
||||||
<coefficients ue_reference="1907" coef="4.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Qualité de développement" abbrev="Qualité de développement" code="R2.03" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="160" code_apogee="VINFR203" module_type="2">
|
|
||||||
<coefficients ue_reference="1902" coef="12.0"/>
|
|
||||||
<coefficients ue_reference="1906" coef="6.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Développement d'une application" abbrev="Développement d'une application" code="S2.01" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="280" code_apogee="VINFS201" module_type="3">
|
|
||||||
<coefficients ue_reference="1902" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE22" code_apogee="V1INFU22" numero="8" coefficient="0.0" titre="Compétence 2 : Optimiser des applications informatiques" coef_rcue="1.0" semestre_idx="2" color="#f97b3d" type="0" ue_code="UCOD18" ects="5.0" apc_niveau_libelle="Appréhender et construire des algorithmes " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1903">
|
|
||||||
<matiere titre="Compétence 2 : Optimiser des applications informatiques" numero="1">
|
|
||||||
<module titre="Graphes" abbrev="Graphes" code="R2.07" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="210" code_apogee="VINFR207" module_type="2">
|
|
||||||
<coefficients ue_reference="1903" coef="21.0"/>
|
|
||||||
<coefficients ue_reference="1906" coef="6.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Méthodes numériques" abbrev="Méthodes numériques" code="R2.09" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="230" code_apogee="VINFR209" module_type="2">
|
|
||||||
<coefficients ue_reference="1903" coef="12.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Exploration algorithmique d'un problème" abbrev="Exploration algorithmique d'un problème" code="S2.02" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="290" code_apogee="VINFS202" module_type="3">
|
|
||||||
<coefficients ue_reference="1903" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE23" code_apogee="V1INFU23" numero="9" coefficient="0.0" titre="Compétence 3 : Administrer des systèmes informatiques communicants" coef_rcue="1.0" semestre_idx="2" color="#feb40b" type="0" ue_code="UCOD19" ects="5.0" apc_niveau_libelle="Installer et configurer un poste de travail " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1904">
|
|
||||||
<matiere titre="Compétence 3 : Administrer des systèmes informatiques communicants" numero="1">
|
|
||||||
<module titre="Communication et fonctionnement bas niveau" abbrev="Communication et fonctionnement bas niveau" code="R2.04-A" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="170" code_apogee="VINFR204" module_type="2">
|
|
||||||
<coefficients ue_reference="1903" coef="6.0"/>
|
|
||||||
<coefficients ue_reference="1904" coef="18.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Communication et fonctionnement bas niveau" abbrev="Communication et fonctionnement bas niveau" code="R2.04-B" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="180" code_apogee="VINFR204" module_type="2">
|
|
||||||
<coefficients ue_reference="1903" coef="6.0"/>
|
|
||||||
<coefficients ue_reference="1904" coef="18.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Introduction aux services réseaux" abbrev="Introduction aux services réseaux" code="R2.05" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="190" code_apogee="VINFR205" module_type="2">
|
|
||||||
<coefficients ue_reference="1904" coef="15.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Installation de services réseau" abbrev="Installation de services réseau" code="S2.03" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="300" code_apogee="VINFS203" module_type="3">
|
|
||||||
<coefficients ue_reference="1904" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE24" code_apogee="V1INFU24" numero="10" coefficient="0.0" titre="Compétence 4 : Gérer des données de l'information" coef_rcue="1.0" semestre_idx="2" color="#80cb3f" type="0" ue_code="UCOD20" ects="5.0" apc_niveau_libelle="Concevoir et mettre en place une base de données à partir d’un cahier des charges client " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1905">
|
|
||||||
<matiere titre="Compétence 4 : Gérer des données de l'information" numero="1">
|
|
||||||
<module titre="Exploitation d'une base de données" abbrev="Exploitation d'une base de données" code="R2.06" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="200" code_apogee="VINFR206" module_type="2">
|
|
||||||
<coefficients ue_reference="1905" coef="30.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Outils numériques pour les statistiques descriptives" abbrev="Outils numériques pour les statistiques descriptives" code="R2.08" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="220" code_apogee="VINFR208" module_type="2">
|
|
||||||
<coefficients ue_reference="1905" coef="12.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Exploitation d'une base de données" abbrev="Exploitation d'une base de données" code="S2.04" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="310" code_apogee="VINFS204" module_type="3">
|
|
||||||
<coefficients ue_reference="1905" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE25" code_apogee="V1INFU25" numero="11" coefficient="0.0" titre="Compétence 5 : Conduire un projet" coef_rcue="1.0" semestre_idx="2" color="#05162e" type="0" ue_code="UCOD21" ects="5.0" apc_niveau_libelle="Identifier les besoins métiers des clients et des utilisateurs " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1906">
|
|
||||||
<matiere titre="Compétence 5 : Conduire un projet" numero="1">
|
|
||||||
<module titre="Gestion de projet & des organisations" abbrev="Gestion de projet & des organisations" code="R2.10" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="240" code_apogee="VINFR210" module_type="2">
|
|
||||||
<coefficients ue_reference="1905" coef="12.0"/>
|
|
||||||
<coefficients ue_reference="1906" coef="30.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Anglais d'entreprise" abbrev="Anglais d'entreprise" code="R2.12" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="260" code_apogee="VINFR212" module_type="2">
|
|
||||||
<coefficients ue_reference="1904" coef="6.0"/>
|
|
||||||
<coefficients ue_reference="1905" coef="6.0"/>
|
|
||||||
<coefficients ue_reference="1906" coef="6.0"/>
|
|
||||||
<coefficients ue_reference="1907" coef="17.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Gestion d'un projet" abbrev="Gestion d'un projet" code="S2.05" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="320" code_apogee="VINFS205" module_type="3">
|
|
||||||
<coefficients ue_reference="1906" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE26" code_apogee="V1INFU26" numero="12" coefficient="0.0" titre="Compétence 6 : Travailler dans une équipe informatique" coef_rcue="1.0" semestre_idx="2" color="#548687" type="0" ue_code="UCOD22" ects="5.0" apc_niveau_libelle="Identifier ses aptitudes pour travailler dans une équipe " apc_niveau_annee="BUT1" apc_niveau_ordre="1" reference="1907">
|
|
||||||
<matiere titre="Compétence 6 : Travailler dans une équipe informatique" numero="1">
|
|
||||||
<module titre="Droit des contrats et du numérique" abbrev="Droit des contrats et du numérique" code="R2.11" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="250" code_apogee="VINFR211" module_type="2">
|
|
||||||
<coefficients ue_reference="1907" coef="17.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Communication avec le milieu professionnel" abbrev="Communication avec le milieu professionnel" code="R2.13" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="270" code_apogee="VINFR213" module_type="2">
|
|
||||||
<coefficients ue_reference="1902" coef="6.0"/>
|
|
||||||
<coefficients ue_reference="1904" coef="3.0"/>
|
|
||||||
<coefficients ue_reference="1906" coef="9.0"/>
|
|
||||||
<coefficients ue_reference="1907" coef="11.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Organisation d'un travail d'équipe" abbrev="Organisation d'un travail d'équipe" code="S2.06" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="330" code_apogee="VINFS206" module_type="3">
|
|
||||||
<coefficients ue_reference="1907" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Portfolio" abbrev="Portfolio" code="P2.01" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="340" code_apogee="VINFPOR2" module_type="3"/>
|
|
||||||
<module titre="Projet professionnel et personnel : métiers de l'informatique" abbrev="PPP" code="R2.14" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="2" numero="350" code_apogee="VINFR214" module_type="2">
|
|
||||||
<coefficients ue_reference="1907" coef="11.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE31" code_apogee="" numero="13" coefficient="0.0" titre="Compétence 1 : Réaliser un développement d'application" coef_rcue="1.0" semestre_idx="3" color="#b80004" type="0" ue_code="UCOD71" ects="5.0" apc_niveau_libelle="Partir des exigences et aller jusqu’à une application complète " apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="1986">
|
|
||||||
<matiere titre="Compétence 1 : Réaliser un développement d'application" numero="1"/>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE32" code_apogee="" numero="14" coefficient="0.0" titre="Compétence 2 : Optimiser des applications informatiques" coef_rcue="1.0" semestre_idx="3" color="#f97b3d" type="0" ue_code="UCOD79" ects="5.0" apc_niveau_libelle="Sélectionner les algorithmes adéquats pour répondre à un problème donné " apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="1987">
|
|
||||||
<matiere titre="Compétence 2 : Optimiser des applications informatiques" numero="1"/>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE33" code_apogee="" numero="15" coefficient="0.0" titre="Compétence 3 : Administrer des systèmes informatiques communicants" coef_rcue="1.0" semestre_idx="3" color="#feb40b" type="0" ue_code="UCOD102" ects="5.0" apc_niveau_libelle="Déployer des services dans une architecture réseau" apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="1988">
|
|
||||||
<matiere titre="Compétence 3 : Administrer des systèmes informatiques communicants" numero="1"/>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE34" code_apogee="" numero="16" coefficient="0.0" titre="Compétence 4 : Gérer des données de l'information" coef_rcue="1.0" semestre_idx="3" color="#80cb3f" type="0" ue_code="UCOD103" ects="5.0" apc_niveau_libelle="Optimiser une base de données, interagir avec une application et mettre en œuvre la sécurité " apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="1989">
|
|
||||||
<matiere titre="Compétence 4 : Gérer des données de l'information" numero="1"/>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE35" code_apogee="" numero="17" coefficient="0.0" titre="Compétence 5 : Conduire un projet" coef_rcue="1.0" semestre_idx="3" color="#05162e" type="0" ue_code="UCOD104" ects="5.0" apc_niveau_libelle="Appliquer une démarche de suivi de projet en fonction des besoins métiers des clients et des utilisateurs " apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="1990">
|
|
||||||
<matiere titre="Compétence 5 : Conduire un projet" numero="1"/>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE36" code_apogee="" numero="18" coefficient="0.0" titre="Compétence 6 : Travailler dans une équipe informatique" coef_rcue="1.0" semestre_idx="3" color="#548687" type="0" ue_code="UCOD105" ects="5.0" apc_niveau_libelle="Situer son rôle et ses missions au sein d’une équipe informatique " apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="1991">
|
|
||||||
<matiere titre="Compétence 6 : Travailler dans une équipe informatique" numero="1">
|
|
||||||
<module titre="Développement web" abbrev="Développement web" code="R3.01" heures_cours="0.0" heures_td="8.0" heures_tp="25.0" coefficient="0.0" ects="" semestre_id="3" numero="360" code_apogee="VINFR301" module_type="2">
|
|
||||||
<coefficients ue_reference="1986" coef="15.0"/>
|
|
||||||
<coefficients ue_reference="1987" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="1988" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="1989" coef="10.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Développement efficace" abbrev="Développement efficace" code="R3.02" heures_cours="0.0" heures_td="8.0" heures_tp="8.0" coefficient="0.0" ects="" semestre_id="3" numero="370" code_apogee="VINFR302" module_type="2">
|
|
||||||
<coefficients ue_reference="1986" coef="10.0"/>
|
|
||||||
<coefficients ue_reference="1987" coef="13.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Analyse" abbrev="Analyse" code="R3.03" heures_cours="0.0" heures_td="8.0" heures_tp="8.0" coefficient="0.0" ects="" semestre_id="3" numero="380" code_apogee="VINFR303" module_type="2">
|
|
||||||
<coefficients ue_reference="1986" coef="12.0"/>
|
|
||||||
<coefficients ue_reference="1987" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="1990" coef="10.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Qualité de développement" abbrev="Qualité de développement" code="R3.04" heures_cours="0.0" heures_td="16.0" heures_tp="24.0" coefficient="0.0" ects="" semestre_id="3" numero="390" code_apogee="VINFR304" module_type="2">
|
|
||||||
<coefficients ue_reference="1986" coef="15.0"/>
|
|
||||||
<coefficients ue_reference="1990" coef="8.0"/>
|
|
||||||
<coefficients ue_reference="1991" coef="5.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Programmation système" abbrev="Programmation système" code="R3.05" heures_cours="0.0" heures_td="12.0" heures_tp="12.0" coefficient="0.0" ects="" semestre_id="3" numero="400" code_apogee="VINFR305" module_type="2">
|
|
||||||
<coefficients ue_reference="1988" coef="22.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Architecture des réseaux" abbrev="Architecture des réseaux" code="R3.06" heures_cours="0.0" heures_td="8.0" heures_tp="8.0" coefficient="0.0" ects="" semestre_id="3" numero="410" code_apogee="VINFR306" module_type="2">
|
|
||||||
<coefficients ue_reference="1987" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="1988" coef="18.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="SQL dans un langage de programmation" abbrev="SQL dans un langage de programmation" code="R3.07" heures_cours="0.0" heures_td="12.0" heures_tp="16.0" coefficient="0.0" ects="" semestre_id="3" numero="420" code_apogee="VINFR307" module_type="2">
|
|
||||||
<coefficients ue_reference="1989" coef="25.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Probabilités" abbrev="Probabilités" code="R3.08" heures_cours="0.0" heures_td="22.0" heures_tp="7.0" coefficient="0.0" ects="" semestre_id="3" numero="430" code_apogee="VINFR308" module_type="2">
|
|
||||||
<coefficients ue_reference="1987" coef="17.0"/>
|
|
||||||
<coefficients ue_reference="1989" coef="5.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Cryptographie et sécurité" abbrev="Cryptographie et sécurité" code="R3.09" heures_cours="0.0" heures_td="8.0" heures_tp="12.0" coefficient="0.0" ects="" semestre_id="3" numero="440" code_apogee="VINFR309" module_type="2">
|
|
||||||
<coefficients ue_reference="1987" coef="10.0"/>
|
|
||||||
<coefficients ue_reference="1988" coef="10.0"/>
|
|
||||||
<coefficients ue_reference="1989" coef="5.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Management des systèmes d'information" abbrev="Management des systèmes d'information" code="R3.10" heures_cours="0.0" heures_td="24.0" heures_tp="8.0" coefficient="0.0" ects="" semestre_id="3" numero="450" code_apogee="VINFR310" module_type="2">
|
|
||||||
<coefficients ue_reference="1989" coef="10.0"/>
|
|
||||||
<coefficients ue_reference="1990" coef="18.0"/>
|
|
||||||
<coefficients ue_reference="1991" coef="16.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Droit des contrats et du numérique" abbrev="Droit des contrats et du numérique" code="R3.11" heures_cours="0.0" heures_td="28.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="3" numero="460" code_apogee="VINFR311" module_type="2">
|
|
||||||
<coefficients ue_reference="1986" coef="8.0"/>
|
|
||||||
<coefficients ue_reference="1989" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="1990" coef="10.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Anglais professionnel" abbrev="Anglais professionnel" code="R3.12" heures_cours="0.0" heures_td="16.0" heures_tp="8.0" coefficient="0.0" ects="" semestre_id="3" numero="470" code_apogee="VINFR312" module_type="2">
|
|
||||||
<coefficients ue_reference="1987" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="1988" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="1990" coef="7.0"/>
|
|
||||||
<coefficients ue_reference="1991" coef="8.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Communication professionnelle" abbrev="Communication professionnelle" code="R3.13" heures_cours="0.0" heures_td="16.0" heures_tp="8.0" coefficient="0.0" ects="" semestre_id="3" numero="480" code_apogee="VINFR313" module_type="2">
|
|
||||||
<coefficients ue_reference="1990" coef="7.0"/>
|
|
||||||
<coefficients ue_reference="1991" coef="16.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Développement d'une application" abbrev="Développement d'une application" code="S3.01" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="3" numero="490" code_apogee="VINFS301" module_type="3">
|
|
||||||
<coefficients ue_reference="1986" coef="40.0"/>
|
|
||||||
<coefficients ue_reference="1987" coef="40.0"/>
|
|
||||||
<coefficients ue_reference="1988" coef="40.0"/>
|
|
||||||
<coefficients ue_reference="1989" coef="40.0"/>
|
|
||||||
<coefficients ue_reference="1990" coef="40.0"/>
|
|
||||||
<coefficients ue_reference="1991" coef="40.0"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Portfolio" abbrev="Portfolio" code="P3.01" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="3" numero="500" code_apogee="" module_type="3"/>
|
|
||||||
<module titre="Projet personnel et professionnel" abbrev="Projet personnel et professionnel" code="R3.14" heures_cours="0.0" heures_td="8.0" heures_tp="5.0" coefficient="0.0" ects="" semestre_id="3" numero="510" code_apogee="VINFR314" module_type="2">
|
|
||||||
<coefficients ue_reference="1991" coef="15.0"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE37" code_apogee="" numero="19" coefficient="0.0" titre="Sport / Culture" coef_rcue="1.0" semestre_idx="3" color="#444054" type="1" ue_code="X7.1" ects="0.0" reference="2551">
|
|
||||||
<matiere titre="UE7" numero="1">
|
|
||||||
<module titre="Sport / Culture" abbrev="Sport" code="X3.01" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="3" numero="680" code_apogee="" module_type="0"/>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="Sport, culture, engagement" code_apogee="" numero="20" coefficient="0.0" titre="Sport, culture, engagement" coef_rcue="1.0" semestre_idx="4" color="#444054" type="1" ue_code="OPT4" ects="1.0" reference="2594">
|
|
||||||
<matiere titre="Sport, culture, engagement" numero="1">
|
|
||||||
<module titre="Bonus" abbrev="Bonus" code="Bonus" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="690" code_apogee="" module_type="0"/>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE41" code_apogee="" numero="21" coefficient="0.0" titre="UE41 Compétence 1 : Réaliser un développement d'application" coef_rcue="1.0" semestre_idx="4" color="#b80004" type="0" ue_code="UCOD171" ects="5.0" apc_niveau_libelle="Partir des exigences et aller jusqu’à une application complète " apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="2520">
|
|
||||||
<matiere titre="UE41 Compétence 1 : Réaliser un développement d'application" numero="1">
|
|
||||||
<module titre="Architecture logicielle" abbrev="Architecture logicielle" code="R4.01" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="530" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2520" coef="16.0"/>
|
|
||||||
<coefficients ue_reference="2522" coef="12.0"/>
|
|
||||||
<coefficients ue_reference="2525" coef="4.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC21.01" libelle="Élaborer et implémenter les spécifications fonctionnelles et non fonctionnelles à partir des exigences"/>
|
|
||||||
<app_critiques code="AC21.02" libelle="Appliquer des principes d’accessibilité et d’ergonomie"/>
|
|
||||||
<app_critiques code="AC21.03" libelle="Adopter de bonnes pratiques de conception et de programmation"/>
|
|
||||||
<app_critiques code="AC23.01" libelle="Concevoir et développer des applications communicantes"/>
|
|
||||||
<app_critiques code="AC26.02" libelle="Appliquer une démarche pour intégrer une équipe informatique au sein d’une organisation"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Projet Personnel et Professionnel" abbrev="Projet Personnel et Professionnel" code="R4.07" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="590" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2525" coef="10.0"/>
|
|
||||||
<app_critiques code="AC21.01" libelle="Élaborer et implémenter les spécifications fonctionnelles et non fonctionnelles à partir des exigences"/>
|
|
||||||
<app_critiques code="AC21.02" libelle="Appliquer des principes d’accessibilité et d’ergonomie"/>
|
|
||||||
<app_critiques code="AC21.03" libelle="Adopter de bonnes pratiques de conception et de programmation"/>
|
|
||||||
<app_critiques code="AC21.04" libelle="Vérifier et valider la qualité de l’application par les tests"/>
|
|
||||||
<app_critiques code="AC22.01" libelle="Choisir des structures de données complexes adaptées au problème"/>
|
|
||||||
<app_critiques code="AC22.02" libelle="Utiliser des techniques algorithmiques adaptées pour des problèmes complexes (par ex. recherche opérationnelle, méthodes arborescentes, optimisation globale, intelligence artificielle...)"/>
|
|
||||||
<app_critiques code="AC22.03" libelle="Comprendre les enjeux et moyens de sécurisation des données et du code"/>
|
|
||||||
<app_critiques code="AC22.04" libelle="Évaluer l’impact environnemental et sociétal des solutions proposées"/>
|
|
||||||
<app_critiques code="AC23.01" libelle="Concevoir et développer des applications communicantes"/>
|
|
||||||
<app_critiques code="AC23.02" libelle="Utiliser des serveurs et des services réseaux virtualisés"/>
|
|
||||||
<app_critiques code="AC23.03" libelle="Sécuriser les services et données d’un système"/>
|
|
||||||
<app_critiques code="AC24.01" libelle="Optimiser les modèles de données de l’entreprise"/>
|
|
||||||
<app_critiques code="AC24.02" libelle="Assurer la sécurité des données (intégrité et confidentialité)"/>
|
|
||||||
<app_critiques code="AC24.03" libelle="Organiser la restitution de données à travers la programmation et la visualisation"/>
|
|
||||||
<app_critiques code="AC24.04" libelle="Manipuler des données hétérogènes"/>
|
|
||||||
<app_critiques code="AC25.01" libelle="Identifier les processus présents dans une organisation en vue d’améliorer les systèmes d’information"/>
|
|
||||||
<app_critiques code="AC25.02" libelle="Formaliser les besoins du client et de l'utilisateur"/>
|
|
||||||
<app_critiques code="AC25.03" libelle="Identifier les critères de faisabilité d’un projet informatique"/>
|
|
||||||
<app_critiques code="AC25.04" libelle="Définir et mettre en œuvre une démarche de suivi de projet"/>
|
|
||||||
<app_critiques code="AC26.01" libelle="Comprendre la diversité, la structure et la dimension de l’informatique dans une organisation (ESN, DSI,...)"/>
|
|
||||||
<app_critiques code="AC26.02" libelle="Appliquer une démarche pour intégrer une équipe informatique au sein d’une organisation"/>
|
|
||||||
<app_critiques code="AC26.03" libelle="Mobiliser les compétences interpersonnelles pour travailler dans une équipe informatique"/>
|
|
||||||
<app_critiques code="AC26.04" libelle="Rendre compte de son activité professionnelle"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Complétement web" abbrev="Complétement web" code="R4.A.10" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="620" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2520" coef="8.0"/>
|
|
||||||
<coefficients ue_reference="2521" coef="4.0"/>
|
|
||||||
<coefficients ue_reference="2523" coef="8.0"/>
|
|
||||||
<coefficients ue_reference="2524" coef="4.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC21.01" libelle="Élaborer et implémenter les spécifications fonctionnelles et non fonctionnelles à partir des exigences"/>
|
|
||||||
<app_critiques code="AC21.02" libelle="Appliquer des principes d’accessibilité et d’ergonomie"/>
|
|
||||||
<app_critiques code="AC22.04" libelle="Évaluer l’impact environnemental et sociétal des solutions proposées"/>
|
|
||||||
<app_critiques code="AC24.02" libelle="Assurer la sécurité des données (intégrité et confidentialité)"/>
|
|
||||||
<app_critiques code="AC24.03" libelle="Organiser la restitution de données à travers la programmation et la visualisation"/>
|
|
||||||
<app_critiques code="AC25.02" libelle="Formaliser les besoins du client et de l'utilisateur"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Développement pour applications mobiles" abbrev="Développement pour applications mobiles" code="R4.A.11" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="630" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2520" coef="8.0"/>
|
|
||||||
<coefficients ue_reference="2521" coef="4.0"/>
|
|
||||||
<coefficients ue_reference="2523" coef="8.0"/>
|
|
||||||
<coefficients ue_reference="2524" coef="4.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC21.01" libelle="Élaborer et implémenter les spécifications fonctionnelles et non fonctionnelles à partir des exigences"/>
|
|
||||||
<app_critiques code="AC22.04" libelle="Évaluer l’impact environnemental et sociétal des solutions proposées"/>
|
|
||||||
<app_critiques code="AC24.03" libelle="Organiser la restitution de données à travers la programmation et la visualisation"/>
|
|
||||||
<app_critiques code="AC25.02" libelle="Formaliser les besoins du client et de l'utilisateur"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Développement d'une application complexe" abbrev="Développement d'une application complexe" code="S4.A.01" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="650" code_apogee="" module_type="3">
|
|
||||||
<coefficients ue_reference="2520" coef="15.0"/>
|
|
||||||
<coefficients ue_reference="2521" coef="15.0"/>
|
|
||||||
<coefficients ue_reference="2522" coef="15.0"/>
|
|
||||||
<coefficients ue_reference="2523" coef="15.0"/>
|
|
||||||
<coefficients ue_reference="2524" coef="15.0"/>
|
|
||||||
<coefficients ue_reference="2525" coef="15.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC21.04" libelle="Vérifier et valider la qualité de l’application par les tests"/>
|
|
||||||
<app_critiques code="AC22.02" libelle="Utiliser des techniques algorithmiques adaptées pour des problèmes complexes (par ex. recherche opérationnelle, méthodes arborescentes, optimisation globale, intelligence artificielle...)"/>
|
|
||||||
<app_critiques code="AC22.03" libelle="Comprendre les enjeux et moyens de sécurisation des données et du code"/>
|
|
||||||
<app_critiques code="AC22.04" libelle="Évaluer l’impact environnemental et sociétal des solutions proposées"/>
|
|
||||||
<app_critiques code="AC23.03" libelle="Sécuriser les services et données d’un système"/>
|
|
||||||
<app_critiques code="AC24.01" libelle="Optimiser les modèles de données de l’entreprise"/>
|
|
||||||
<app_critiques code="AC24.02" libelle="Assurer la sécurité des données (intégrité et confidentialité)"/>
|
|
||||||
<app_critiques code="AC25.02" libelle="Formaliser les besoins du client et de l'utilisateur"/>
|
|
||||||
<app_critiques code="AC25.03" libelle="Identifier les critères de faisabilité d’un projet informatique"/>
|
|
||||||
<app_critiques code="AC25.04" libelle="Définir et mettre en œuvre une démarche de suivi de projet"/>
|
|
||||||
<app_critiques code="AC26.02" libelle="Appliquer une démarche pour intégrer une équipe informatique au sein d’une organisation"/>
|
|
||||||
<app_critiques code="AC26.03" libelle="Mobiliser les compétences interpersonnelles pour travailler dans une équipe informatique"/>
|
|
||||||
<app_critiques code="AC26.04" libelle="Rendre compte de son activité professionnelle"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Stage" abbrev="Stage" code="S4.St" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="660" code_apogee="" module_type="3">
|
|
||||||
<coefficients ue_reference="2520" coef="40.0"/>
|
|
||||||
<coefficients ue_reference="2521" coef="40.0"/>
|
|
||||||
<coefficients ue_reference="2522" coef="40.0"/>
|
|
||||||
<coefficients ue_reference="2523" coef="40.0"/>
|
|
||||||
<coefficients ue_reference="2524" coef="40.0"/>
|
|
||||||
<coefficients ue_reference="2525" coef="40.0"/>
|
|
||||||
<app_critiques code="AC21.01" libelle="Élaborer et implémenter les spécifications fonctionnelles et non fonctionnelles à partir des exigences"/>
|
|
||||||
<app_critiques code="AC21.02" libelle="Appliquer des principes d’accessibilité et d’ergonomie"/>
|
|
||||||
<app_critiques code="AC21.03" libelle="Adopter de bonnes pratiques de conception et de programmation"/>
|
|
||||||
<app_critiques code="AC21.04" libelle="Vérifier et valider la qualité de l’application par les tests"/>
|
|
||||||
<app_critiques code="AC22.01" libelle="Choisir des structures de données complexes adaptées au problème"/>
|
|
||||||
<app_critiques code="AC22.02" libelle="Utiliser des techniques algorithmiques adaptées pour des problèmes complexes (par ex. recherche opérationnelle, méthodes arborescentes, optimisation globale, intelligence artificielle...)"/>
|
|
||||||
<app_critiques code="AC22.03" libelle="Comprendre les enjeux et moyens de sécurisation des données et du code"/>
|
|
||||||
<app_critiques code="AC22.04" libelle="Évaluer l’impact environnemental et sociétal des solutions proposées"/>
|
|
||||||
<app_critiques code="AC23.01" libelle="Concevoir et développer des applications communicantes"/>
|
|
||||||
<app_critiques code="AC23.02" libelle="Utiliser des serveurs et des services réseaux virtualisés"/>
|
|
||||||
<app_critiques code="AC23.03" libelle="Sécuriser les services et données d’un système"/>
|
|
||||||
<app_critiques code="AC24.01" libelle="Optimiser les modèles de données de l’entreprise"/>
|
|
||||||
<app_critiques code="AC24.02" libelle="Assurer la sécurité des données (intégrité et confidentialité)"/>
|
|
||||||
<app_critiques code="AC24.03" libelle="Organiser la restitution de données à travers la programmation et la visualisation"/>
|
|
||||||
<app_critiques code="AC24.04" libelle="Manipuler des données hétérogènes"/>
|
|
||||||
<app_critiques code="AC25.01" libelle="Identifier les processus présents dans une organisation en vue d’améliorer les systèmes d’information"/>
|
|
||||||
<app_critiques code="AC25.02" libelle="Formaliser les besoins du client et de l'utilisateur"/>
|
|
||||||
<app_critiques code="AC25.03" libelle="Identifier les critères de faisabilité d’un projet informatique"/>
|
|
||||||
<app_critiques code="AC25.04" libelle="Définir et mettre en œuvre une démarche de suivi de projet"/>
|
|
||||||
<app_critiques code="AC26.01" libelle="Comprendre la diversité, la structure et la dimension de l’informatique dans une organisation (ESN, DSI,...)"/>
|
|
||||||
<app_critiques code="AC26.02" libelle="Appliquer une démarche pour intégrer une équipe informatique au sein d’une organisation"/>
|
|
||||||
<app_critiques code="AC26.03" libelle="Mobiliser les compétences interpersonnelles pour travailler dans une équipe informatique"/>
|
|
||||||
<app_critiques code="AC26.04" libelle="Rendre compte de son activité professionnelle"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Portfolio" abbrev="Portfolio" code="P4.01" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="670" code_apogee="" module_type="3">
|
|
||||||
<coefficients ue_reference="2520" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="2521" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="2522" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="2523" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="2524" coef="5.0"/>
|
|
||||||
<coefficients ue_reference="2525" coef="5.0"/>
|
|
||||||
<app_critiques code="AC21.01" libelle="Élaborer et implémenter les spécifications fonctionnelles et non fonctionnelles à partir des exigences"/>
|
|
||||||
<app_critiques code="AC21.02" libelle="Appliquer des principes d’accessibilité et d’ergonomie"/>
|
|
||||||
<app_critiques code="AC21.03" libelle="Adopter de bonnes pratiques de conception et de programmation"/>
|
|
||||||
<app_critiques code="AC21.04" libelle="Vérifier et valider la qualité de l’application par les tests"/>
|
|
||||||
<app_critiques code="AC22.01" libelle="Choisir des structures de données complexes adaptées au problème"/>
|
|
||||||
<app_critiques code="AC22.02" libelle="Utiliser des techniques algorithmiques adaptées pour des problèmes complexes (par ex. recherche opérationnelle, méthodes arborescentes, optimisation globale, intelligence artificielle...)"/>
|
|
||||||
<app_critiques code="AC22.03" libelle="Comprendre les enjeux et moyens de sécurisation des données et du code"/>
|
|
||||||
<app_critiques code="AC22.04" libelle="Évaluer l’impact environnemental et sociétal des solutions proposées"/>
|
|
||||||
<app_critiques code="AC23.01" libelle="Concevoir et développer des applications communicantes"/>
|
|
||||||
<app_critiques code="AC23.02" libelle="Utiliser des serveurs et des services réseaux virtualisés"/>
|
|
||||||
<app_critiques code="AC23.03" libelle="Sécuriser les services et données d’un système"/>
|
|
||||||
<app_critiques code="AC24.01" libelle="Optimiser les modèles de données de l’entreprise"/>
|
|
||||||
<app_critiques code="AC24.02" libelle="Assurer la sécurité des données (intégrité et confidentialité)"/>
|
|
||||||
<app_critiques code="AC24.03" libelle="Organiser la restitution de données à travers la programmation et la visualisation"/>
|
|
||||||
<app_critiques code="AC24.04" libelle="Manipuler des données hétérogènes"/>
|
|
||||||
<app_critiques code="AC25.01" libelle="Identifier les processus présents dans une organisation en vue d’améliorer les systèmes d’information"/>
|
|
||||||
<app_critiques code="AC25.02" libelle="Formaliser les besoins du client et de l'utilisateur"/>
|
|
||||||
<app_critiques code="AC25.03" libelle="Identifier les critères de faisabilité d’un projet informatique"/>
|
|
||||||
<app_critiques code="AC25.04" libelle="Définir et mettre en œuvre une démarche de suivi de projet"/>
|
|
||||||
<app_critiques code="AC26.01" libelle="Comprendre la diversité, la structure et la dimension de l’informatique dans une organisation (ESN, DSI,...)"/>
|
|
||||||
<app_critiques code="AC26.02" libelle="Appliquer une démarche pour intégrer une équipe informatique au sein d’une organisation"/>
|
|
||||||
<app_critiques code="AC26.03" libelle="Mobiliser les compétences interpersonnelles pour travailler dans une équipe informatique"/>
|
|
||||||
<app_critiques code="AC26.04" libelle="Rendre compte de son activité professionnelle"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE42" code_apogee="" numero="22" coefficient="0.0" titre="UE42 Compétence 2 : Optimiser des applications informatiques" coef_rcue="1.0" semestre_idx="4" color="#f97b3d" type="0" ue_code="UCOD172" ects="5.0" apc_niveau_libelle="Sélectionner les algorithmes adéquats pour répondre à un problème donné " apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="2521">
|
|
||||||
<matiere titre="UE42 Compétence 2 : Optimiser des applications informatiques" numero="1">
|
|
||||||
<module titre="Méthodes d'optimisation" abbrev="Méthodes d'optimisation" code="R4.04" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="560" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2521" coef="12.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC22.02" libelle="Utiliser des techniques algorithmiques adaptées pour des problèmes complexes (par ex. recherche opérationnelle, méthodes arborescentes, optimisation globale, intelligence artificielle...)"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Automates et langages" abbrev="Automates et langages" code="R4.A.12" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="640" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2521" coef="12.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC22.01" libelle="Choisir des structures de données complexes adaptées au problème"/>
|
|
||||||
<app_critiques code="AC22.02" libelle="Utiliser des techniques algorithmiques adaptées pour des problèmes complexes (par ex. recherche opérationnelle, méthodes arborescentes, optimisation globale, intelligence artificielle...)"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE43" code_apogee="" numero="23" coefficient="0.0" titre="UE43 Compétence 3 : Administrer des systèmes informatiques communicants" coef_rcue="1.0" semestre_idx="4" color="#feb40b" type="0" ue_code="UCOD173" ects="5.0" apc_niveau_libelle="Déployer des services dans une architecture réseau" apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="2522">
|
|
||||||
<matiere titre="UE43 Compétence 3 : Administrer des systèmes informatiques communicants" numero="1">
|
|
||||||
<module titre="Virtualisation" abbrev="Virtualisation" code="R4.A.08" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="600" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2522" coef="28.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC23.02" libelle="Utiliser des serveurs et des services réseaux virtualisés"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE44" code_apogee="" numero="24" coefficient="0.0" titre="UE44 Compétence 4 : Gérer des données de l'information" coef_rcue="1.0" semestre_idx="4" color="#80cb3f" type="0" ue_code="UCOD174" ects="5.0" apc_niveau_libelle="Optimiser une base de données, interagir avec une application et mettre en œuvre la sécurité " apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="2523">
|
|
||||||
<matiere titre="UE44 Compétence 4 : Gérer des données de l'information" numero="1">
|
|
||||||
<module titre="Qualité & Non-relationnel" abbrev="Qualité & Non-relationnel" code="R4.03" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="550" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2523" coef="18.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC24.01" libelle="Optimiser les modèles de données de l’entreprise"/>
|
|
||||||
<app_critiques code="AC24.04" libelle="Manipuler des données hétérogènes"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE45" code_apogee="" numero="25" coefficient="0.0" titre="UE45 Compétence 5 : Conduire un projet" coef_rcue="1.0" semestre_idx="4" color="#05162e" type="0" ue_code="UCOD175" ects="5.0" apc_niveau_libelle="Appliquer une démarche de suivi de projet en fonction des besoins métiers des clients et des utilisateurs " apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="2524">
|
|
||||||
<matiere titre="UE45 Compétence 5 : Conduire un projet" numero="1">
|
|
||||||
<module titre="Qualité de développement" abbrev="Qualité de développement" code="R4.02" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="540" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2520" coef="8.0"/>
|
|
||||||
<coefficients ue_reference="2524" coef="10.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC21.04" libelle="Vérifier et valider la qualité de l’application par les tests"/>
|
|
||||||
<app_critiques code="AC25.03" libelle="Identifier les critères de faisabilité d’un projet informatique"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Management avancé des systèmes d'information" abbrev="Management avancé des systèmes d'information" code="R4.A.09" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="610" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2521" coef="4.0"/>
|
|
||||||
<coefficients ue_reference="2524" coef="22.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC22.04" libelle="Évaluer l’impact environnemental et sociétal des solutions proposées"/>
|
|
||||||
<app_critiques code="AC25.03" libelle="Identifier les critères de faisabilité d’un projet informatique"/>
|
|
||||||
<app_critiques code="AC25.04" libelle="Définir et mettre en œuvre une démarche de suivi de projet"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
<ue is_external="0" acronyme="UE46" code_apogee="" numero="26" coefficient="0.0" titre="UE46 Compétence 6 : Travailler dans une équipe informatique" coef_rcue="1.0" semestre_idx="4" color="#548687" type="0" ue_code="UCOD176" ects="5.0" apc_niveau_libelle="Situer son rôle et ses missions au sein d’une équipe informatique " apc_niveau_annee="BUT2" apc_niveau_ordre="2" reference="2525">
|
|
||||||
<matiere titre="UE46 Compétence 6 : Travailler dans une équipe informatique" numero="1">
|
|
||||||
<module titre="Anglais" abbrev="Anglais" code="R4.05" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="570" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2521" coef="4.0"/>
|
|
||||||
<coefficients ue_reference="2525" coef="13.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC22.04" libelle="Évaluer l’impact environnemental et sociétal des solutions proposées"/>
|
|
||||||
<app_critiques code="AC26.03" libelle="Mobiliser les compétences interpersonnelles pour travailler dans une équipe informatique"/>
|
|
||||||
<app_critiques code="AC26.04" libelle="Rendre compte de son activité professionnelle"/>
|
|
||||||
</module>
|
|
||||||
<module titre="Communication interne" abbrev="Communication interne" code="R4.06" heures_cours="0.0" heures_td="0.0" heures_tp="0.0" coefficient="0.0" ects="" semestre_id="4" numero="580" code_apogee="" module_type="2">
|
|
||||||
<coefficients ue_reference="2523" coef="6.0"/>
|
|
||||||
<coefficients ue_reference="2525" coef="13.0"/>
|
|
||||||
<parcours code="A" numero="0" libelle="A : Réalisation d’applications : conception, développement, validation"/>
|
|
||||||
<app_critiques code="AC24.04" libelle="Manipuler des données hétérogènes"/>
|
|
||||||
<app_critiques code="AC26.02" libelle="Appliquer une démarche pour intégrer une équipe informatique au sein d’une organisation"/>
|
|
||||||
<app_critiques code="AC26.04" libelle="Rendre compte de son activité professionnelle"/>
|
|
||||||
</module>
|
|
||||||
</matiere>
|
|
||||||
</ue>
|
|
||||||
</formation>
|
|
@ -42,7 +42,7 @@ from tools.fakeportal.gen_nomprenoms import nomprenom
|
|||||||
random.seed(12345678) # tests reproductibles
|
random.seed(12345678) # tests reproductibles
|
||||||
|
|
||||||
# La formation à utiliser:
|
# La formation à utiliser:
|
||||||
FORMATION_XML_FILENAME = "tests/ressources/formations/scodoc_formation_RT_BUT_RT_v1.xml"
|
FORMATION_XML_FILENAME = "tests/ressources/formations/scodoc_formation_BUT_RT_v1.xml"
|
||||||
REFCOMP_FILENAME = (
|
REFCOMP_FILENAME = (
|
||||||
"ressources/referentiels/but2022/competences/but-RT-05012022-081735.xml"
|
"ressources/referentiels/but2022/competences/but-RT-05012022-081735.xml"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user