diff --git a/app/api/etudiants.py b/app/api/etudiants.py index fcafae68c..c1ebd07f2 100644 --- a/app/api/etudiants.py +++ b/app/api/etudiants.py @@ -9,7 +9,7 @@ """ from datetime import datetime -from flask import g, jsonify, request +from flask import abort, g, jsonify, request from flask_login import current_user from flask_login import login_required from sqlalchemy import desc, or_ @@ -210,160 +210,75 @@ def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None) @bp.route( - "/etudiant/etudid//formsemestre//bulletin", - methods=["GET"], - defaults={"version": "long", "pdf": False}, + "/etudiant///formsemestre//bulletin", ) @bp.route( - "/etudiant/nip//formsemestre//bulletin", - methods=["GET"], - defaults={"version": "long", "pdf": False}, + "/etudiant///formsemestre//bulletin/", ) @bp.route( - "/etudiant/ine//formsemestre//bulletin", - methods=["GET"], - defaults={"version": "long", "pdf": False}, -) -@bp.route( - "/etudiant/etudid//formsemestre//bulletin/pdf", - methods=["GET"], - defaults={"version": "long", "pdf": True}, -) -@bp.route( - "/etudiant/etudid//formsemestre//bulletin/short", - methods=["GET"], - defaults={"version": "short", "pdf": False}, -) -@bp.route( - "/etudiant/nip//formsemestre//bulletin/short", - methods=["GET"], - defaults={"version": "short", "pdf": False}, -) -@bp.route( - "/etudiant/ine//formsemestre//bulletin/short", - methods=["GET"], - defaults={"version": "short", "pdf": False}, -) -@bp.route( - "/etudiant/etudid//formsemestre//bulletin/short/pdf", - methods=["GET"], - defaults={"version": "short", "pdf": True}, -) -@bp.route( - "/etudiant/nip//formsemestre//bulletin/short/pdf", - methods=["GET"], - defaults={"version": "short", "pdf": True}, -) -@bp.route( - "/etudiant/ine//formsemestre//bulletin/short/pdf", - methods=["GET"], - defaults={"version": "short", "pdf": True}, -) -@bp.route( - "/etudiant/nip//formsemestre//bulletin/pdf", - methods=["GET"], - defaults={"version": "long", "pdf": True}, -) -@bp.route( - "/etudiant/ine//formsemestre//bulletin/pdf", - methods=["GET"], - defaults={"version": "long", "pdf": True}, + "/etudiant///formsemestre//bulletin//pdf", + defaults={"pdf": True}, ) @api_web_bp.route( - "/etudiant/etudid//formsemestre//bulletin", - methods=["GET"], - defaults={"version": "long", "pdf": False}, + "/etudiant///formsemestre//bulletin", ) @api_web_bp.route( - "/etudiant/nip//formsemestre//bulletin", - methods=["GET"], - defaults={"version": "long", "pdf": False}, + "/etudiant///formsemestre//bulletin/", ) @api_web_bp.route( - "/etudiant/ine//formsemestre//bulletin", - methods=["GET"], - defaults={"version": "long", "pdf": False}, -) -@api_web_bp.route( - "/etudiant/etudid//formsemestre//bulletin/pdf", - methods=["GET"], - defaults={"version": "long", "pdf": True}, -) -@api_web_bp.route( - "/etudiant/etudid//formsemestre//bulletin/short", - methods=["GET"], - defaults={"version": "short", "pdf": False}, -) -@api_web_bp.route( - "/etudiant/nip//formsemestre//bulletin/short", - methods=["GET"], - defaults={"version": "short", "pdf": False}, -) -@api_web_bp.route( - "/etudiant/ine//formsemestre//bulletin/short", - methods=["GET"], - defaults={"version": "short", "pdf": False}, -) -@api_web_bp.route( - "/etudiant/etudid//formsemestre//bulletin/short/pdf", - methods=["GET"], - defaults={"version": "short", "pdf": True}, -) -@api_web_bp.route( - "/etudiant/nip//formsemestre//bulletin/short/pdf", - methods=["GET"], - defaults={"version": "short", "pdf": True}, -) -@api_web_bp.route( - "/etudiant/ine//formsemestre//bulletin/short/pdf", - methods=["GET"], - defaults={"version": "short", "pdf": True}, + "/etudiant///formsemestre//bulletin//pdf", + defaults={"pdf": True}, ) @scodoc @permission_required(Permission.ScoView) -def etudiant_bulletin_semestre( - formsemestre_id, - etudid: int = None, - nip: str = None, - ine: str = None, - version="long", +def bulletin( + code_type: str = "etudid", + code: str = None, + formsemestre_id: int = None, + version: str = "long", pdf: bool = False, ): """ Retourne le bulletin d'un étudiant en fonction de son id et d'un semestre donné formsemestre_id : l'id d'un formsemestre - etudid : l'etudid d'un étudiant - nip : le code nip d'un étudiant - ine : le code ine d'un étudiant - Exemple de résultat : voir https://scodoc.org/ScoDoc9API/#bulletin + code_type : "etudid", "nip" ou "ine" + code : valeur du code INE, NIP ou etudid, selon code_type. + version : type de bulletin (par défaut, "long"): short, long, long_mat + pdf : si spécifié, bulletin au format PDF (et non JSON). + Exemple de résultat : voir https://scodoc.org/ScoDoc9API/#bulletin """ + if version == "pdf": + version = "long" + pdf = True + # return f"{code_type}={code}, version={version}, pdf={pdf}" formsemestre = FormSemestre.query.filter_by(id=formsemestre_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: return json_error(404, "formsemestre non trouve") - if etudid is not None: - query = Identite.query.filter_by(id=etudid) - elif nip is not None: - query = Identite.query.filter_by(code_nip=nip, dept_id=dept.id) - elif ine is not None: - query = Identite.query.filter_by(code_ine=ine, dept_id=dept.id) - else: - return json_error(404, message="parametre manquant") + app.set_sco_dept(dept.acronym) + if code_type == "nip": + query = Identite.query.filter_by(code_nip=code, dept_id=dept.id) + elif code_type == "etudid": + try: + etudid = int(code) + except ValueError: + return json_error(404, "invalid etudid type") + query = Identite.query.filter_by(id=etudid) + elif code_type == "ine": + query = Identite.query.filter_by(code_ine=code, dept_id=dept.id) + else: + return json_error(404, "invalid code_type") etud = query.first() if etud is None: return json_error(404, message="etudiant inexistant") - - app.set_sco_dept(dept.acronym) - if pdf: pdf_response, _ = do_formsemestre_bulletinetud( formsemestre, etud.id, version=version, format="pdf" ) return pdf_response - return sco_bulletins.get_formsemestre_bulletin_etud_json( formsemestre, etud, version=version ) diff --git a/app/scodoc/sco_bulletins.py b/app/scodoc/sco_bulletins.py index ae2cc60dd..9a98d6fe6 100644 --- a/app/scodoc/sco_bulletins.py +++ b/app/scodoc/sco_bulletins.py @@ -990,6 +990,8 @@ def do_formsemestre_bulletinetud( version=version, ) return bul, "" + if version.endswith("_mat"): + version = version[:-4] # enlève le "_mat" if formsemestre.formation.is_apc(): etudiant = Identite.query.get(etudid) diff --git a/app/scodoc/sco_bulletins_xml.py b/app/scodoc/sco_bulletins_xml.py index 661b0bd56..2f3c2c6b2 100644 --- a/app/scodoc/sco_bulletins_xml.py +++ b/app/scodoc/sco_bulletins_xml.py @@ -79,6 +79,8 @@ def make_xml_formsemestre_bulletinetud( "bulletin au format XML" from app.scodoc import sco_bulletins + if version.endswith("_mat"): + version = version[:-4] # enlève le "_mat" (ignoré en XML) log("xml_bulletin( formsemestre_id=%s, etudid=%s )" % (formsemestre_id, etudid)) sem = sco_formsemestre.get_formsemestre(formsemestre_id) diff --git a/tests/api/README.md b/tests/api/README.md index 77e4f8160..535b6cdee 100644 --- a/tests/api/README.md +++ b/tests/api/README.md @@ -5,7 +5,7 @@ Démarche générale: 1. On génère une base SQL de test: voir `tools/fakedatabase/create_test_api_database.py` - 1. modifier /opt/scodoc/.env pour indiquer + 1. modifier `/opt/scodoc/.env` pour indiquer ```bash FLASK_ENV=test_api @@ -27,20 +27,20 @@ Démarche générale: 2. On lance le serveur ScoDoc sur cette base - ``` + ```bash flask run --host 0.0.0.0 ``` 3. On lance les tests unitaires API -``` +```bash pytest tests/api/test_api_departements.py ``` Rappel: pour interroger l'API, il fait avoir un utilisateur avec (au moins) la permission ScoView dans tous les départements. Pour en créer un: -``` +```bash flask user-create lecteur_api LecteurAPI @all flask user-password lecteur_api flask edit-role LecteurAPI -a ScoView diff --git a/tests/api/test_api_permissions.py b/tests/api/test_api_permissions.py index c9042a9d4..fc0c628fb 100644 --- a/tests/api/test_api_permissions.py +++ b/tests/api/test_api_permissions.py @@ -14,7 +14,6 @@ import requests from tests.api.setup_test_api import API_URL, SCODOC_URL, CHECK_CERTIFICATE, api_headers -from tests.api.tools_test_api import verify_fields from app import create_app from config import RunningConfig @@ -33,13 +32,15 @@ def test_permissions(api_headers): r for r in app.url_map.iter_rules() if str(r).startswith("/ScoDoc/api") - and not "logo" in str(r) # ignore logos - and not "absence" in str(r) # ignore absences + and "logo" not in str(r) # ignore logos + and "absence" not in str(r) # ignore absences and "GET" in r.methods ] assert len(api_rules) > 0 args = { "acronym": "TAPI", + "code_type": "etudid", + "code": 1, "dept_id": 1, "dept_ident": "TAPI", "dept": "TAPI", @@ -57,6 +58,7 @@ def test_permissions(api_headers): "partition_id": 1, "role_name": "Ens", "uid": 1, + "version": "long", } for rule in api_rules: path = rule.build(args)[1]