forked from ScoDoc/ScoDoc
Merge branch 'master' into prepajury9
This commit is contained in:
commit
4403da99e9
@ -226,50 +226,27 @@ def dept_formsemestres_ids_by_id(dept_id: int):
|
||||
|
||||
|
||||
@bp.route("/departement/<string:acronym>/formsemestres_courants")
|
||||
@bp.route("/departement/id/<int:dept_id>/formsemestres_courants")
|
||||
@login_required
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@as_json
|
||||
def dept_formsemestres_courants(acronym: str):
|
||||
def dept_formsemestres_courants(acronym: str = "", dept_id: int | None = None):
|
||||
"""
|
||||
Liste des semestres actifs d'un département d'acronyme donné
|
||||
Liste les semestres du département indiqué (par son acronyme ou son id)
|
||||
contenant la date courante, ou à défaut celle indiquée en argument
|
||||
(au format ISO).
|
||||
|
||||
QUERY
|
||||
-----
|
||||
date_courante:<string:date_courante>
|
||||
|
||||
Exemple de résultat :
|
||||
[
|
||||
{
|
||||
"titre": "master machine info",
|
||||
"gestion_semestrielle": false,
|
||||
"scodoc7_id": null,
|
||||
"date_debut": "01/09/2021",
|
||||
"bul_bgcolor": null,
|
||||
"date_fin": "15/12/2022",
|
||||
"resp_can_edit": false,
|
||||
"dept_id": 1,
|
||||
"etat": true,
|
||||
"resp_can_change_ens": false,
|
||||
"id": 1,
|
||||
"modalite": "FI",
|
||||
"ens_can_edit_eval": false,
|
||||
"formation_id": 1,
|
||||
"gestion_compensation": false,
|
||||
"elt_sem_apo": null,
|
||||
"semestre_id": 1,
|
||||
"bul_hide_xml": false,
|
||||
"elt_annee_apo": null,
|
||||
"block_moyennes": false,
|
||||
"formsemestre_id": 1,
|
||||
"titre_num": "master machine info semestre 1",
|
||||
"date_debut_iso": "2021-09-01",
|
||||
"date_fin_iso": "2022-12-15",
|
||||
"responsables": [
|
||||
3,
|
||||
2
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
||||
dept = (
|
||||
Departement.query.filter_by(acronym=acronym).first_or_404()
|
||||
if acronym
|
||||
else Departement.query.get_or_404(dept_id)
|
||||
)
|
||||
date_courante = request.args.get("date_courante")
|
||||
date_courante = datetime.fromisoformat(date_courante) if date_courante else None
|
||||
return [
|
||||
@ -278,29 +255,3 @@ def dept_formsemestres_courants(acronym: str):
|
||||
dept, date_courante
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@bp.route("/departement/id/<int:dept_id>/formsemestres_courants")
|
||||
@login_required
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@as_json
|
||||
def dept_formsemestres_courants_by_id(dept_id: int):
|
||||
"""
|
||||
Liste des semestres actifs d'un département d'id donné
|
||||
"""
|
||||
# Le département, spécifié par un id ou un acronyme
|
||||
dept = Departement.query.get_or_404(dept_id)
|
||||
date_courante = request.args.get("date_courante")
|
||||
if date_courante:
|
||||
test_date = datetime.fromisoformat(date_courante)
|
||||
else:
|
||||
test_date = db.func.current_date()
|
||||
# Les semestres en cours de ce département
|
||||
formsemestres = FormSemestre.query.filter(
|
||||
FormSemestre.dept_id == dept.id,
|
||||
FormSemestre.date_debut <= test_date,
|
||||
FormSemestre.date_fin >= test_date,
|
||||
)
|
||||
|
||||
return [d.to_dict_api() for d in formsemestres]
|
||||
|
@ -89,12 +89,17 @@ def _get_etud_by_code(
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@as_json
|
||||
def etudiants_courants(long=False):
|
||||
def etudiants_courants(long: bool = False):
|
||||
"""
|
||||
La liste des étudiants des semestres "courants" (tous départements)
|
||||
(date du jour comprise dans la période couverte par le sem.)
|
||||
dans lesquels l'utilisateur a la permission ScoView
|
||||
(donc tous si le dept du rôle est None).
|
||||
La liste des étudiants des semestres "courants".
|
||||
Considère tous les départements dans lesquels l'utilisateur a la
|
||||
permission `ScoView` (donc tous si le dépt. du rôle est `None`),
|
||||
et les formsemestres contenant la date courante,
|
||||
ou à défaut celle indiquée en argument (au format ISO).
|
||||
|
||||
QUERY
|
||||
-----
|
||||
date_courante:<string:date_courante>
|
||||
|
||||
Exemple de résultat :
|
||||
[
|
||||
@ -183,8 +188,13 @@ def etudiant(etudid: int = None, nip: str = None, ine: str = None):
|
||||
@permission_required(Permission.ScoView)
|
||||
def get_photo_image(etudid: int = None, nip: str = None, ine: str = None):
|
||||
"""
|
||||
Retourne la photo de l'étudiant
|
||||
correspondant ou un placeholder si non existant.
|
||||
Retourne la photo de l'étudiant ou un placeholder si non existant.
|
||||
Le paramètre `size` peut prendre la valeur `small` (taille réduite, hauteur
|
||||
environ 90 pixels) ou `orig` (défaut, image de la taille originale).
|
||||
|
||||
QUERY
|
||||
-----
|
||||
size:<string:size>
|
||||
|
||||
etudid : l'etudid de l'étudiant
|
||||
nip : le code nip de l'étudiant
|
||||
|
@ -108,6 +108,17 @@ def formsemestres_query():
|
||||
dept_id : id du département
|
||||
ine ou nip: code d'un étudiant: ramène alors tous les semestres auxquels il est inscrit.
|
||||
etat: 0 si verrouillé, 1 sinon
|
||||
|
||||
QUERY
|
||||
-----
|
||||
etape_apo:<string:etape_apo>
|
||||
annee_scolaire:<string:annee_scolaire>
|
||||
dept_acronym:<string:dept_acronym>
|
||||
dept_id:<int:dept_id>
|
||||
etat:<int:etat>
|
||||
nip:<string:nip>
|
||||
ine:<string:ine>
|
||||
|
||||
"""
|
||||
etape_apo = request.args.get("etape_apo")
|
||||
annee_scolaire = request.args.get("annee_scolaire")
|
||||
@ -376,7 +387,16 @@ def formsemestre_programme(formsemestre_id: int):
|
||||
def formsemestre_etudiants(
|
||||
formsemestre_id: int, with_query: bool = False, long: bool = False
|
||||
):
|
||||
"""Étudiants d'un formsemestre."""
|
||||
"""Étudiants d'un formsemestre.
|
||||
|
||||
Si l'état est spécifié, ne renvoie que les inscrits (`I`), les
|
||||
démissionnaires (`D`) ou les défaillants (`DEF`)
|
||||
|
||||
QUERY
|
||||
-----
|
||||
etat:<string:etat>
|
||||
|
||||
"""
|
||||
query = FormSemestre.query.filter_by(id=formsemestre_id)
|
||||
if g.scodoc_dept:
|
||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||
@ -531,6 +551,13 @@ def etat_evals(formsemestre_id: int):
|
||||
def formsemestre_resultat(formsemestre_id: int):
|
||||
"""Tableau récapitulatif des résultats
|
||||
Pour chaque étudiant, son état, ses groupes, ses moyennes d'UE et de modules.
|
||||
|
||||
Si `format=raw`, ne converti pas les valeurs.
|
||||
|
||||
QUERY
|
||||
-----
|
||||
format:<string:format>
|
||||
|
||||
"""
|
||||
format_spec = request.args.get("format", None)
|
||||
if format_spec is not None and format_spec != "raw":
|
||||
@ -623,6 +650,12 @@ def formsemestre_edt(formsemestre_id: int):
|
||||
|
||||
group_ids permet de filtrer sur les groupes ScoDoc.
|
||||
show_modules_titles affiche le titre complet du module (défaut), sinon juste le code.
|
||||
|
||||
QUERY
|
||||
-----
|
||||
group_ids:<string:group_ids>
|
||||
show_modules_titles:<bool:show_modules_titles>
|
||||
|
||||
"""
|
||||
query = FormSemestre.query.filter_by(id=formsemestre_id)
|
||||
if g.scodoc_dept:
|
||||
|
@ -151,7 +151,13 @@ def etud_in_group(group_id: int):
|
||||
@permission_required(Permission.ScoView)
|
||||
@as_json
|
||||
def etud_in_group_query(group_id: int):
|
||||
"""Étudiants du groupe, filtrés par état"""
|
||||
"""Étudiants du groupe, filtrés par état (aucun, I, D, DEF)
|
||||
|
||||
QUERY
|
||||
-----
|
||||
etat:<string:etat>
|
||||
|
||||
"""
|
||||
etat = request.args.get("etat")
|
||||
if etat not in {None, scu.INSCRIT, scu.DEMISSION, scu.DEF}:
|
||||
return json_error(API_CLIENT_ERROR, "etat: valeur invalide")
|
||||
|
@ -59,6 +59,13 @@ def users_info_query():
|
||||
Seuls les utilisateurs "accessibles" (selon les permissions) sont retournés.
|
||||
Si accès via API web, le département de l'URL est ignoré, seules
|
||||
les permissions de l'utilisateur sont prises en compte.
|
||||
|
||||
QUERY
|
||||
-----
|
||||
active:<bool:active>
|
||||
departement:<string:departement>
|
||||
starts_with:<string:starts_with>
|
||||
|
||||
"""
|
||||
query = User.query
|
||||
active = request.args.get("active")
|
||||
|
@ -35,9 +35,9 @@ def after_cas_login():
|
||||
if user.cas_allow_login:
|
||||
current_app.logger.info(f"CAS: login {user.user_name}")
|
||||
if login_user(user):
|
||||
flask.session[
|
||||
"scodoc_cas_login_date"
|
||||
] = datetime.datetime.now().isoformat()
|
||||
flask.session["scodoc_cas_login_date"] = (
|
||||
datetime.datetime.now().isoformat()
|
||||
)
|
||||
user.cas_last_login = datetime.datetime.utcnow()
|
||||
if flask.session.get("CAS_EDT_ID"):
|
||||
# essaie de récupérer l'edt_id s'il est présent
|
||||
@ -45,8 +45,10 @@ def after_cas_login():
|
||||
# via l'expression `cas_edt_id_from_xml_regexp`
|
||||
# voir flask_cas.routing
|
||||
edt_id = flask.session.get("CAS_EDT_ID")
|
||||
current_app.logger.info(f"""after_cas_login: storing edt_id for {
|
||||
user.user_name}: '{edt_id}'""")
|
||||
current_app.logger.info(
|
||||
f"""after_cas_login: storing edt_id for {
|
||||
user.user_name}: '{edt_id}'"""
|
||||
)
|
||||
user.edt_id = edt_id
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
@ -55,12 +57,17 @@ def after_cas_login():
|
||||
current_app.logger.info(
|
||||
f"CAS login denied for {user.user_name} (not allowed to use CAS)"
|
||||
)
|
||||
else:
|
||||
else: # pas d'utilisateur ScoDoc ou bien compte inactif
|
||||
current_app.logger.info(
|
||||
f"""CAS login denied for {
|
||||
user.user_name if user else ""
|
||||
} cas_id={cas_id} (unknown or inactive)"""
|
||||
)
|
||||
if ScoDocSiteConfig.is_cas_forced():
|
||||
# Dans ce cas, pas de redirect vers la page de login pour éviter de boucler
|
||||
raise ScoValueError(
|
||||
"compte ScoDoc inexistant ou inactif pour cet utilisateur CAS"
|
||||
)
|
||||
else:
|
||||
current_app.logger.info(
|
||||
f"""CAS attribute '{ScoDocSiteConfig.get("cas_attribute_id")}' not found !
|
||||
|
@ -691,9 +691,13 @@ def module_edit(
|
||||
str(parcour.id) for parcour in ref_comp.parcours
|
||||
]
|
||||
+ ["-1"],
|
||||
"explanation": """Parcours dans lesquels est utilisé ce module.<br>
|
||||
Attention: si le module ne doit pas avoir les mêmes coefficients suivant le parcours,
|
||||
il faut en créer plusieurs versions, car dans ScoDoc chaque module a ses coefficients.""",
|
||||
"explanation": """Parcours dans lesquels est utilisé ce module (inutile
|
||||
hors BUT, pour les modules standards et dans les UEs de bonus).
|
||||
<br>
|
||||
Attention: si le module ne doit pas avoir les mêmes coefficients suivant
|
||||
le parcours, il faut en créer plusieurs versions, car dans ScoDoc chaque
|
||||
module a ses coefficients.
|
||||
""",
|
||||
},
|
||||
)
|
||||
]
|
||||
|
@ -564,7 +564,7 @@ def fiche_etud(etudid=None):
|
||||
%(etat_civil)s
|
||||
<span>%(email_link)s</span>
|
||||
</td><td class="photocell">
|
||||
<a href="etud_photo_orig_page?etudid=%(etudid)s">%(etudfoto)s</a>
|
||||
<a href="etud_photo_orig_page/%(etudid)s">%(etudfoto)s</a>
|
||||
</td></tr></table>
|
||||
"""
|
||||
+ situation_template
|
||||
|
@ -931,11 +931,12 @@ def saisie_notes_tableur(evaluation_id, group_ids=()):
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def feuille_saisie_notes(evaluation_id, group_ids=[]):
|
||||
def feuille_saisie_notes(evaluation_id, group_ids: list[int] = None):
|
||||
"""Document Excel pour saisie notes dans l'évaluation et les groupes indiqués"""
|
||||
evaluation: Evaluation = db.session.get(Evaluation, evaluation_id)
|
||||
if not evaluation:
|
||||
raise ScoValueError("invalid evaluation_id")
|
||||
group_ids = group_ids or []
|
||||
modimpl = evaluation.moduleimpl
|
||||
formsemestre = modimpl.formsemestre
|
||||
mod_responsable = sco_users.user_info(modimpl.responsable_id)
|
||||
@ -950,7 +951,8 @@ def feuille_saisie_notes(evaluation_id, group_ids=[]):
|
||||
if evaluation.date_debut
|
||||
else "(sans date)"
|
||||
)
|
||||
eval_titre = f"""{evaluation.description if evaluation.description else "évaluation"} {date_str}"""
|
||||
eval_titre = f"""{evaluation.description if evaluation.description else "évaluation"
|
||||
} {date_str}"""
|
||||
|
||||
description = f"""{eval_titre} en {evaluation.moduleimpl.module.abbrev or ""} ({
|
||||
evaluation.moduleimpl.module.code
|
||||
@ -986,7 +988,7 @@ def feuille_saisie_notes(evaluation_id, group_ids=[]):
|
||||
rows.append(
|
||||
[
|
||||
str(etudid),
|
||||
e["nom"].upper(),
|
||||
e.get("nom_disp", "") or e.get("nom_usuel", "") or e["nom"],
|
||||
e["prenom"].lower().capitalize(),
|
||||
e["inscr"]["etat"],
|
||||
grc,
|
||||
@ -1206,7 +1208,7 @@ def _get_sorted_etuds(evaluation: Evaluation, etudids: list, formsemestre_id: in
|
||||
def _form_saisie_notes(
|
||||
evaluation: Evaluation, modimpl: ModuleImpl, groups_infos, destination=""
|
||||
):
|
||||
"""Formulaire HTML saisie des notes dans l'évaluation E du moduleimpl M
|
||||
"""Formulaire HTML saisie des notes dans l'évaluation du moduleimpl
|
||||
pour les groupes indiqués.
|
||||
|
||||
On charge tous les étudiants, ne seront montrés que ceux
|
||||
|
@ -1018,23 +1018,21 @@ sco_publish("/get_photo_image", sco_photos.get_photo_image, Permission.ScoView)
|
||||
sco_publish("/etud_photo_html", sco_photos.etud_photo_html, Permission.ScoView)
|
||||
|
||||
|
||||
@bp.route("/etud_photo_orig_page")
|
||||
@bp.route("/etud_photo_orig_page/<int:etudid>")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func
|
||||
def etud_photo_orig_page(etudid=None):
|
||||
def etud_photo_orig_page(etudid):
|
||||
"Page with photo in orig. size"
|
||||
etud = sco_etud.get_etud_info(filled=True, etudid=etudid)[0]
|
||||
H = [
|
||||
html_sco_header.sco_header(page_title=etud["nomprenom"]),
|
||||
"<h2>%s</h2>" % etud["nomprenom"],
|
||||
'<div><a href="%s">'
|
||||
% url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
sco_photos.etud_photo_orig_html(etud),
|
||||
"</a></div>",
|
||||
html_sco_header.sco_footer(),
|
||||
]
|
||||
return "\n".join(H)
|
||||
etud = Identite.get_etud(etudid)
|
||||
return f"""{
|
||||
html_sco_header.sco_header(etudid=etud.id, page_title=etud.nomprenom)
|
||||
}
|
||||
<h2>{etud.nomprenom}</h2>
|
||||
<div>
|
||||
<a href="{etud.url_fiche()}">{etud.photo_html(size='orig')}</a>
|
||||
</div>
|
||||
{html_sco_header.sco_footer()}
|
||||
"""
|
||||
|
||||
|
||||
@bp.route("/form_change_photo", methods=["GET", "POST"])
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SCOVERSION = "9.6.980"
|
||||
SCOVERSION = "9.6.981"
|
||||
|
||||
SCONAME = "ScoDoc"
|
||||
|
||||
|
@ -280,3 +280,19 @@ def test_semestres_courant(api_headers):
|
||||
assert len(result_a) > 0
|
||||
sem = result_a[0]
|
||||
assert verify_fields(sem, FORMSEMESTRE_FIELDS) is True
|
||||
|
||||
# accès avec id incorrect
|
||||
r = requests.get(
|
||||
f"{API_URL}/departement/id/bad/formsemestres_courants?date_courante=2022-07-01",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
timeout=scu.SCO_TEST_API_TIMEOUT,
|
||||
)
|
||||
assert r.status_code == 404
|
||||
r = requests.get(
|
||||
f"{API_URL}/departement/id/-1/formsemestres_courants?date_courante=2022-07-01",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
timeout=scu.SCO_TEST_API_TIMEOUT,
|
||||
)
|
||||
assert r.status_code == 404
|
||||
|
@ -66,6 +66,7 @@ def test_permissions(api_headers):
|
||||
"assiduite_id": 1,
|
||||
"justif_id": 1,
|
||||
"etudids": "1",
|
||||
"ue_id": 1,
|
||||
}
|
||||
# Arguments spécifiques pour certaines routes
|
||||
# par défaut, on passe tous les arguments de all_args
|
||||
|
@ -172,7 +172,7 @@ class Token:
|
||||
sub_group = ET.Element("g")
|
||||
|
||||
# On décale l'élément de la query vers la droite par rapport à l'élément parent
|
||||
translate_x = x_offset + x_step
|
||||
translate_x = x_offset + _get_group_width(group) + x_step // 2
|
||||
|
||||
# création élément (param)
|
||||
param_el = _create_svg_element(key, COLORS.BLUE)
|
||||
@ -192,7 +192,7 @@ class Token:
|
||||
# création élément (=)
|
||||
equal_el = _create_svg_element("=", COLORS.GREY)
|
||||
# On met à jour le décalage en fonction de l'élément précédent
|
||||
translate_x = x_offset + x_step + _get_element_width(param_el)
|
||||
translate_x += _get_element_width(param_el)
|
||||
equal_el.set(
|
||||
"transform",
|
||||
f"translate({translate_x}, {query_y_offset})",
|
||||
@ -202,11 +202,7 @@ class Token:
|
||||
# création élément (value)
|
||||
value_el = _create_svg_element(value, COLORS.GREEN)
|
||||
# On met à jour le décalage en fonction des éléments précédents
|
||||
translate_x = (
|
||||
x_offset
|
||||
+ x_step
|
||||
+ sum(_get_element_width(el) for el in [param_el, equal_el])
|
||||
)
|
||||
translate_x += _get_element_width(equal_el)
|
||||
value_el.set(
|
||||
"transform",
|
||||
f"translate({translate_x}, {query_y_offset})",
|
||||
@ -214,16 +210,13 @@ class Token:
|
||||
sub_group.append(value_el)
|
||||
# Si il y a qu'un seul élément dans la query, on ne met pas de `&`
|
||||
if len(self.query) == 1:
|
||||
query_sub_element.append(sub_group)
|
||||
continue
|
||||
|
||||
# création élément (&)
|
||||
ampersand_group = _create_svg_element("&", "rgb(224,224,224)")
|
||||
# On met à jour le décalage en fonction des éléments précédents
|
||||
translate_x = (
|
||||
x_offset
|
||||
+ x_step
|
||||
+ sum(_get_element_width(el) for el in [param_el, equal_el, value_el])
|
||||
)
|
||||
translate_x += _get_element_width(value_el)
|
||||
ampersand_group.set(
|
||||
"transform",
|
||||
f"translate({translate_x}, {query_y_offset})",
|
||||
@ -466,6 +459,10 @@ def gen_api_map(app, endpoint_start="api"):
|
||||
# On positionne le token courant sur le token racine
|
||||
current_token = api_map
|
||||
|
||||
# Récupération de la fonction associée à la route
|
||||
func = app.view_functions[rule.endpoint]
|
||||
func_name = parse_doc_name(func.__doc__ or "") or func.__name__
|
||||
|
||||
# Pour chaque segment de la route
|
||||
for i, segment in enumerate(segments):
|
||||
# On cherche si le segment est déjà un enfant du token courant
|
||||
@ -473,7 +470,6 @@ def gen_api_map(app, endpoint_start="api"):
|
||||
|
||||
# Si ce n'est pas le cas on crée un nouveau token et on l'ajoute comme enfant
|
||||
if child is None:
|
||||
func = app.view_functions[rule.endpoint]
|
||||
# Si c'est le dernier segment, on marque le token comme une leaf
|
||||
# On utilise force_leaf car il est possible que le token ne soit que
|
||||
# momentanément une leaf
|
||||
@ -499,7 +495,7 @@ def gen_api_map(app, endpoint_start="api"):
|
||||
|
||||
# On ajoute le token comme enfant du token courant
|
||||
# en donnant la méthode et le nom de la fonction associée
|
||||
child.func_name = func.__name__
|
||||
child.func_name = func_name
|
||||
method: str = "POST" if "POST" in rule.methods else "GET"
|
||||
child.method = method
|
||||
current_token.add_child(child)
|
||||
@ -607,6 +603,9 @@ def generate_svg(element, fname):
|
||||
)
|
||||
ET.SubElement(marker, "polygon", {"points": "0 0, 10 3.5, 0 7"})
|
||||
|
||||
# Ajoute un décalage vertical pour avoir un peu de padding en haut
|
||||
element.set("transform", "translate(0, 10)")
|
||||
|
||||
# Ajout de l'élément principal à l'élément racine
|
||||
svg.append(element)
|
||||
|
||||
@ -615,6 +614,50 @@ def generate_svg(element, fname):
|
||||
tree.write(fname, encoding="utf-8", xml_declaration=True)
|
||||
|
||||
|
||||
def _get_doc_lines(keyword, doc) -> list[str]:
|
||||
"""
|
||||
Renvoie les lignes de la doc qui suivent le mot clé keyword
|
||||
|
||||
La doc doit contenir des lignes de la forme:
|
||||
|
||||
KEYWORD
|
||||
-------
|
||||
...
|
||||
|
||||
"""
|
||||
# Récupérer les lignes de la doc
|
||||
lines = [line.strip() for line in doc.split("\n")]
|
||||
# On cherche la ligne "KEYWORD" et on vérifie que la ligne suivante est "-----"
|
||||
# Si ce n'est pas le cas, on renvoie un dictionnaire vide
|
||||
try:
|
||||
kw_index = lines.index(keyword)
|
||||
kw_line = "-" * len(keyword)
|
||||
if lines[kw_index + 1] != kw_line:
|
||||
return []
|
||||
except ValueError:
|
||||
return []
|
||||
# On récupère les lignes de la doc qui correspondent au keyword (enfin on espère)
|
||||
kw_lines = lines[kw_index + 2 :]
|
||||
return kw_lines
|
||||
|
||||
|
||||
def parse_doc_name(doc):
|
||||
"""
|
||||
renvoie le nom de la route à partir de la docstring
|
||||
|
||||
La doc doit contenir des lignes de la forme:
|
||||
|
||||
DOC_ANCHOR
|
||||
----------
|
||||
nom_de_la_route
|
||||
|
||||
Il ne peut y avoir qu'une seule ligne suivant -----
|
||||
|
||||
"""
|
||||
name_lines: list[str] = _get_doc_lines("DOC_ANCHOR", doc)
|
||||
return name_lines[0] if name_lines else None
|
||||
|
||||
|
||||
def parse_query_doc(doc):
|
||||
"""
|
||||
renvoie un dictionnaire {param: <type:nom_param>} (ex: {assiduite_id : <int:assiduite_id>})
|
||||
@ -630,18 +673,7 @@ def parse_query_doc(doc):
|
||||
Dès qu'une ligne ne respecte pas ce format (voir regex dans la fonction), on arrête de parser
|
||||
Attention, la ligne ----- doit être collée contre QUERY et contre le premier paramètre
|
||||
"""
|
||||
# Récupérer les lignes de la doc
|
||||
lines = [line.strip() for line in doc.split("\n")]
|
||||
# On cherche la ligne "QUERY" et on vérifie que la ligne suivante est "-----"
|
||||
# Si ce n'est pas le cas, on renvoie un dictionnaire vide
|
||||
try:
|
||||
query_index = lines.index("QUERY")
|
||||
if lines[query_index + 1] != "-----":
|
||||
return {}
|
||||
except ValueError:
|
||||
return {}
|
||||
# On récupère les lignes de la doc qui correspondent à la query (enfin on espère)
|
||||
query_lines = lines[query_index + 2 :]
|
||||
query_lines: list[str] = _get_doc_lines("QUERY", doc)
|
||||
|
||||
query = {}
|
||||
regex = re.compile(r"^(\w+):(<.+>)$")
|
||||
|
Loading…
Reference in New Issue
Block a user