From 77348c2cdf20c15da6d8acedf3a7a98cdced55d7 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sun, 27 Nov 2022 23:31:48 +0100 Subject: [PATCH] =?UTF-8?q?API:=20bulletins:=20re-ecriture=20et=20format?= =?UTF-8?q?=20json=20classic=20avec=20mati=C3=A8res=20(long=5Fmat,=20short?= =?UTF-8?q?=5Fmat).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/etudiants.py | 157 +++++++----------------------- app/scodoc/sco_bulletins.py | 2 + app/scodoc/sco_bulletins_xml.py | 2 + tests/api/README.md | 8 +- tests/api/test_api_permissions.py | 8 +- 5 files changed, 49 insertions(+), 128 deletions(-) diff --git a/app/api/etudiants.py b/app/api/etudiants.py index fcafae68..c1ebd07f 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 ae2cc60d..9a98d6fe 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 661b0bd5..2f3c2c6b 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 77e4f816..535b6cde 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 c9042a9d..fc0c628f 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]