# -*- mode: python -*- # -*- coding: utf-8 -*- ############################################################################## # # Gestion scolarite IUT # # Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Emmanuel Viennet emmanuel.viennet@viennet.net # ############################################################################## """API ScoDoc 9 """ # PAS ENCORE IMPLEMENTEE, juste un essai # Pour P. Bouron, il faudrait en priorité l'équivalent de # Scolarite/Notes/moduleimpl_withmodule_list (alias scodoc7 do_moduleimpl_withmodule_list) # Scolarite/Notes/evaluation_create # Scolarite/Notes/evaluation_delete # Scolarite/Notes/formation_list # Scolarite/Notes/formsemestre_list # Scolarite/Notes/formsemestre_partition_list # Scolarite/Notes/groups_view # Scolarite/Notes/moduleimpl_status # Scolarite/setGroups from datetime import datetime from flask import jsonify, request, g, send_file from sqlalchemy.sql import func from app import db, log from app.api import bp, requested_format from app.api.auth import token_auth from app.api.errors import error_response from app import models from app.models import FormSemestre, FormSemestreInscription, Identite from app.models import ApcReferentielCompetences from app.scodoc.sco_abs import annule_absence, annule_justif, add_absence, add_justif, list_abs_date from app.scodoc.sco_bulletins import formsemestre_bulletinetud_dict from app.scodoc.sco_bulletins_json import make_json_formsemestre_bulletinetud from app.scodoc.sco_evaluation_db import do_evaluation_get_all_notes from app.scodoc.sco_formations import formation_export from app.scodoc.sco_formsemestre_inscriptions import do_formsemestre_inscription_listinscrits from app.scodoc.sco_groups import setGroups, get_etud_groups, get_group_members from app.scodoc.sco_logos import list_logos, find_logo, _list_dept_logos from app.scodoc.sco_moduleimpl import moduleimpl_list from app.scodoc.sco_permissions import Permission ############################################### Departements ########################################################## from app.scodoc.sco_prepajury import feuille_preparation_jury from app.scodoc.sco_pvjury import formsemestre_pvjury from app.scodoc.sco_recapcomplet import formsemestre_recapcomplet from app.scodoc.sco_saisie_notes import notes_add @bp.route("/departements", methods=["GET"]) #@token_auth.login_required def departements(): """ Retourne la liste des ids de départements """ # Récupération de tous les départements depts = models.Departement.query.filter_by(visible=True).all() # Mise en place de la liste avec tous les ids de départements data = [d.id for d in depts] return jsonify(data) @bp.route("/departements//etudiants/liste/", methods=["GET"]) @token_auth.login_required def liste_etudiants(dept: str, formsemestre_id=None): # XXX TODO A REVOIR """ Retourne la liste des étudiants d'un département dept: l'acronym d'un département formsemestre_id: l'id d'un formesemestre """ # Si le formsemestre_id a été renseigné if formsemestre_id is not None: # Récupération du/des depts list_depts = models.Departement.query.filter( models.Departement.acronym == dept, models.FormSemestre.semestre_id == formsemestre_id, ) list_etuds = [] for dept in list_depts: # Récupération des étudiants d'un département x = models.Identite.query.filter(models.Identite.dept_id == dept.getId()) for y in x: # Ajout des étudiants dans la liste global list_etuds.append(y) else: # Si le formsemestre_id n'a pas été renseigné list_depts = models.Departement.query.filter( models.Departement.acronym == dept, models.FormSemestre.semestre_id == models.Departement.formsemestres, ) list_etuds = [] for dept in list_depts: x = models.Identite.query.filter(models.Identite.dept_id == dept.getId()) for y in x: list_etuds.append(y) # Mise en forme des données data = [d.to_dict() for d in list_etuds] # return jsonify(data) return error_response(501, message="Not implemented") @bp.route("/departements//semestres_courant", methods=["GET"]) # @token_auth.login_required def liste_semestres_courant(dept: str): """ Liste des semestres actifs d'un départements donné dept: l'acronym d'un département """ # Récupération des départements comportant l'acronym mit en paramètre depts = models.Departement.query.filter_by(acronym=dept).all() # Récupération de l'id id_dept = depts[0].id # Récupération des semestres suivant id_dept semestres = models.FormSemestre.query.filter_by(dept_id=id_dept, etat=True).all() # Mise en forme des données data = [d.to_dict() for d in semestres] return jsonify(data) @bp.route( "/departements//formations//referentiel_competences", methods=["GET"], ) def referenciel_competences(dept: str, formation_id: int): """ Retourne le référentiel de compétences dept : l'acronym d'un département formation_id : l'id d'une formation """ # depts = models.Departement.query.filter_by(acronym=dept).all() # # id_dept = depts[0].id # # formations = models.Formation.query.filter_by(id=formation_id, dept_id=id_dept).all() # # ref_comp = formations[0].referentiel_competence_id # # if ref_comp is None: # return error_response(204, message="Pas de référenciel de compétences pour cette formation") # else: # return jsonify(ref_comp) ref = ApcReferentielCompetences.query.get_or_404(formation_id) return jsonify(ref.to_dict()) @bp.route("/departements//formsemestre/programme", methods=["GET"]) def semestre_index(dept: str, formsemestre_id: int): """ Retourne la liste des Ues, ressources et SAE d'un semestre """ return error_response(501, message="not implemented") #################################################### Etudiants ######################################################## @bp.route("/etudiants", methods=["GET"]) def etudiants(): """ Retourne la liste de tous les étudiants """ # Récupération de tous les étudiants etu = models.Identite.query.all() # Mise en forme des données data = [d.to_dict_bul(include_urls=False) for d in etu] return jsonify(data) # return error_response(501, message="Not implemented") @bp.route("/etudiants/courant", methods=["GET"]) def etudiants_courant(): """ Retourne la liste des étudiants courant """ # Récupération de tous les étudiants etus = models.Identite.query.all() data = [] # Récupère uniquement les étudiants courant for etu in etus: if etu.inscription_courante() is not None: data.append(etu.to_dict_bul(include_urls=False)) return jsonify(data) # return error_response(501, message="Not implemented") @bp.route("/etudiant/etudid/", methods=["GET"]) @bp.route("/etudiant/nip/", methods=["GET"]) @bp.route("/etudiant/ine/", methods=["GET"]) def etudiant(etudid: int = None, nip: int = None, ine: int = None): """ Retourne les informations de l'étudiant correspondant à l'id passé en paramètres. etudid : l'etudid d'un étudiant nip : le code nip d'un étudiant ine : le code ine d'un étudiant """ etu = [] if etudid is not None: # Si route etudid # Récupération de l'étudiant etu = models.Identite.query.filter_by(id=etudid).first() if nip is not None: # Si route nip # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_nip=nip).first() if ine is not None: # Si route ine # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_ine=ine).first() # Mise en forme des données data = etu.to_dict_bul(include_urls=False) return jsonify(data) @bp.route("/etudiant/etudid//formsemestres") @bp.route("/etudiant/nip//formsemestres") @bp.route("/etudiant/ine//formsemestres") def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None): """ Retourne les semestres qu'un étudiant a suivis etudid : l'etudid d'un étudiant nip : le code nip d'un étudiant ine : le code ine d'un étudiant """ # Récupération de toutes les inscriptions inscriptions = models.FormSemestreInscription.query.all() sems = [] # Filtre les inscriptions contenant l'étudiant for sem in inscriptions: if etudid is not None: # Si route etudid if sem.etudid == etudid: sems.append(sem) if nip is not None: # Si route nip # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_nip=nip).first() if sem.etudid == etu.etudid: sems.append(sem) if ine is not None: # Si route ine # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_ine=ine).firt() if sem.etudid == etu.etudid: sems.append(sem) # Mise en forme des données data_inscriptions = [d.to_dict() for d in sems] formsemestres = [] # Filtre les formsemestre contenant les inscriptions de l'étudiant for sem in data_inscriptions: res = models.FormSemestre.query.filter_by(id=sem['formsemestre_id']).first() formsemestres.append(res) data = [] # Mise en forme des données for formsem in formsemestres: data.append(formsem.to_dict()) return jsonify(data) @bp.route("/etudiant/etudid//formsemestre//bulletin", methods=["GET"]) @bp.route("/etudiant/nip//formsemestre//bulletin", methods=["GET"]) @bp.route("/etudiant/ine//formsemestre//bulletin", methods=["GET"]) def etudiant_bulletin_semestre(formsemestre_id, etudid: int = None, nip: int = None, ine: int = None): """ 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 """ # Fonction utilisée : app.scodoc.sco_bulletins_json.make_json_formsemestre_bulletinetud() etu = None if etudid is not None: # Si route etudid return make_json_formsemestre_bulletinetud(formsemestre_id, etudid) else: if nip is not None: # Si route nip etu = models.Identite.query.filter_by(code_nip=nip).first() if ine is not None: # Si route ine etu = models.Identite.query.filter_by(code_nip=ine).first() if etu is not None: # Si route nip ou ine return make_json_formsemestre_bulletinetud(formsemestre_id, etu.etudid) # return error_response(501, message="Not implemented") @bp.route( "/etudiant/etudid//semestre//groups", methods=["GET"] ) @bp.route( "/etudiant/nip//semestre//groups", methods=["GET"] ) @bp.route( "/etudiant/ine//semestre//groups", methods=["GET"] ) def etudiant_groups(formsemestre_id: int, etudid: int = None, nip: int = None, ine: int = None): """ Retourne la liste des groupes auxquels appartient l'étudiant dans le semestre indiqué 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 """ # Fonction utilisée : app.scodoc.sco_groups.get_etud_groups() if etudid is None: if nip is not None: # Si route nip # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_nip=nip).first() # Récupération de sont etudid etudid = etu.etudid if ine is not None: # Si route ine # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_ine=ine).first() # Récupération de sont etudid etudid = etu.etudid # Récupération du formsemestre sem = models.FormSemestre.query.filter_by(id=formsemestre_id).first() try: # Utilisation de la fonction get_etud_groups data = get_etud_groups(etudid, sem.to_dict()) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return jsonify(data) ##############################################" Formations ############################################################ @bp.route("/formations", methods=["GET"]) def formations(): """ Retourne la liste des formations """ # Récupération de toutes les formations list_formations = models.Formation.query.all() # Mise en forme des données data = [d.to_dict() for d in list_formations] return jsonify(data) @bp.route("/formations/", methods=["GET"]) def formations_by_id(formation_id: int): """ Retourne une formation en fonction d'un id donné formation_id : l'id d'une formation """ # Récupération de la formation forma = models.Formation.query.filter_by(id=formation_id).first() # Mise en forme des données data = [d.to_dict() for d in forma] return jsonify(data) @bp.route("/formations/formation_export/", methods=["GET"]) def formation_export_by_formation_id(formation_id: int, export_ids=False): """ Retourne la formation, avec UE, matières, modules """ # Fonction utilité : app.scodoc.sco_formations.formation_export() try: # Utilisation de la fonction formation_export data = formation_export(formation_id) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return jsonify(data) @bp.route("/formations/apo/", methods=["GET"]) def formsemestre_apo(etape_apo: int): """ Retourne les informations sur les formsemestres etape_apo : l'id d'une étape apogée """ # Récupération des formsemestres apos = models.FormSemestreEtape.query.filter_by(etape_apo=etape_apo).all() data = [] # Filtre les formsemestres correspondant + mise en forme des données for apo in apos: formsem = models.FormSemestre.query.filter_by(id=apo["formsemestre_id"]).first() data.append(formsem.to_dict()) return jsonify(data) # return error_response(501, message="Not implemented") @bp.route("/formations/moduleimpl/", methods=["GET"]) def moduleimpls(moduleimpl_id: int): """ Retourne la liste des moduleimpl moduleimpl_id : l'id d'un moduleimpl """ # Récupération des tous les moduleimpl list_moduleimpls = models.ModuleImpl.query.filter_by(id=moduleimpl_id).all() # Mise en forme des données data = list_moduleimpls[0].to_dict() return jsonify(data) @bp.route( "/formations/moduleimpl//formsemestre/", methods=["GET"]) def moduleimpls_sem(moduleimpl_id: int, formsemestre_id: int): """ Retourne la liste des moduleimpl d'un semestre moduleimpl_id : l'id d'un moduleimpl formsemestre_id : l'id d'un formsemestre """ # Fonction utilisée : app.scodoc.sco_moduleimpl.moduleimpl_list() try: # Utilisation de la fonction moduleimpl_list data = moduleimpl_list(moduleimpl_id, formsemestre_id) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return jsonify(data) #################################################### UE ############################################################### @bp.route( "/departements//formations/programme/", methods=["GET"] ) def eus(dept: str, sem_id: int): """ Liste des UES, ressources et SAE d'un semestre """ return error_response(501, message="Not implemented") ########################################## Formsemestres ############################################################## @bp.route("/formations/formsemestre/", methods=["GET"]) def formsemestre(formsemestre_id: int): """ Retourne l'information sur le formsemestre correspondant au formsemestre_id formsemestre_id : l'id d'un formsemestre """ # Récupération de tous les formsemestres list_formsemetre = models.FormSemestre.query.filter_by(id=formsemestre_id) # Mise en forme des données data = list_formsemetre[0].to_dict() return jsonify(data) @bp.route( "/formsemestre//departements//etudiant/etudid//bulletin", methods=["GET"], ) @bp.route( "/formsemestre//departements//etudiant/nip//bulletin", methods=["GET"], ) @bp.route( "/formsemestre//departements//etudiant/ine//bulletin", methods=["GET"], ) def etudiant_bulletin(formsemestre_id, dept, etudid, format="json", *args, size): """ Retourne le bulletin de note d'un étudiant 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 """ # Fonction utilisée : app.scodoc.sco_bulletins.formsemestre_billetinetud_dict() data = [] if args[0] == "short": data = formsemestre_bulletinetud_dict(formsemestre_id, etudid, version=args[0]) elif args[0] == "selectevals": data = formsemestre_bulletinetud_dict(formsemestre_id, etudid, version=args[0]) elif args[0] == "long": data = formsemestre_bulletinetud_dict(formsemestre_id, etudid) else: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return jsonify(data) @bp.route("/formsemestre//bulletins", methods=["GET"]) def bulletins(formsemestre_id: int): """ Retourne les bulletins d'un formsemestre donné formsemestre_id : l'id d'un formesemestre """ # Fonction utilisée : app.scodoc.sco_recapcomplet.formsemestre_recapcomplet() try: # Utilisation de la fonction formsemestre_recapcomplet data = formsemestre_recapcomplet(formsemestre_id) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return jsonify(data) @bp.route("/formsemestre//jury", methods=["GET"]) def jury(formsemestre_id: int): """ Retourne le récapitulatif des décisions jury formsemestre_id : l'id d'un formsemestre """ # Fonction utilisée : app.scodoc.sco_pvjury.formsemestre_pvjury() try: # Utilisation de la fonction formsemestre_pvjury data = formsemestre_pvjury(formsemestre_id) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return jsonify(data) ############################################### Partitions ############################################################ @bp.route("/partitions/", methods=["GET"]) def partition(formsemestre_id: int): """ Retourne la liste de toutes les partitions d'un formsemestre formsemestre_id : l'id d'un formsemestre """ # Récupération de toutes les partitions partitions = models.Partition.query.filter_by(id=formsemestre_id).all() # Mise en forme des données data = [d.to_dict() for d in partitions] return jsonify(data) # return error_response(501, message="Not implemented") # @bp.route( # "/partitions/formsemestre//groups/group_ids?with_codes=&all_groups=&etat=", # methods=["GET"], # ) @bp.route("/partitions/groups/", methods=["GET"]) @bp.route("/partitions/groups//etat/", methods=["GET"]) def etud_in_group(group_id: int, etat=None): """ Retourne la liste des étudiants dans un groupe group_id : l'id d'un groupe etat : """ # Fonction utilisée : app.scodoc.sco_groups.get_group_members() if etat is None: # Si l'état n'est pas renseigné try: # Utilisation de la fonction get_group_members data = get_group_members(group_id) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") else: # Si l'état est renseigné try: # Utilisation de la fonction get_group_members data = get_group_members(group_id, etat) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return jsonify(data) @bp.route( "/partitions/set_groups?partition_id=&groups_lists=&" "groups_to_create=&groups_to_delete=", methods=["POST"], ) @token_auth.login_required def set_groups(partition_id: int, groups_lists: int, groups_to_delete: int, groups_to_create: int): """ Set les groups partition_id : l'id d'une partition groups_lists : groups_ti_delete : les groupes à supprimer groups_to_create : les groupes à créer """ # Fonction utilisée : app.scodoc.sco_groups.setGroups() try: # Utilisation de la fonction setGroups setGroups(partition_id, groups_lists, groups_to_create, groups_to_delete) return error_response(200, message="Groups set") except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") ############################################### Evaluations ########################################################### @bp.route("/evaluations/", methods=["GET"]) def evaluations(moduleimpl_id: int): """ Retourne la liste des évaluations à partir de l'id d'un moduleimpl moduleimpl_id : l'id d'un moduleimpl """ # Récupération de toutes les évaluations evals = models.Evaluation.query.filter_by(id=moduleimpl_id).all() # Mise en forme des données data = [d.to_dict() for d in evals] return jsonify(data) # return error_response(501, message="Not implemented") @bp.route("/evaluations/eval_notes/", methods=["GET"]) def evaluation_notes(evaluation_id: int): """ Retourne la liste des notes à partir de l'id d'une évaluation donnée evaluation_id : l'id d'une évaluation """ # Fonction utilisée : app.scodoc.sco_evaluation_db.do_evaluation_get_all_notes() try: # Utilisation de la fonction do_evaluation_get_all_notes data = do_evaluation_get_all_notes(evaluation_id) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return jsonify(data) @bp.route("/evaluations/eval_set_notes?eval_id=&etudid=¬e=", methods=["POST"]) @bp.route("/evaluations/eval_set_notes?eval_id=&nip=¬e=", methods=["POST"]) @bp.route("/evaluations/eval_set_notes?eval_id=&ine=¬e=", methods=["POST"]) @token_auth.login_required def evaluation_set_notes(eval_id: int, note: float, etudid: int = None, nip: int = None, ine: int = None): """ Set les notes d'une évaluation pour un étudiant donnée eval_id : l'id d'une évaluation note : la note à attribuer etudid : l'etudid d'un étudiant nip : le code nip d'un étudiant ine : le code ine d'un étudiant """ # Fonction utilisée : app.scodoc.sco_saisie_notes.notes_add() # Qu'est ce qu'un user ??? # notes_add() return error_response(501, message="Not implemented") #################################################### Jury ############################################################# @bp.route("/jury/formsemestre//preparation_jury", methods=["GET"]) def jury_preparation(formsemestre_id: int): # XXX TODO check à quoi resemble le retour de la fonction """ Retourne la feuille de préparation du jury formsemestre_id : l'id d'un formsemestre """ # Fonction utilisée : app.scodoc.sco_prepajury.feuille_preparation_jury() # Utilisation de la fonction feuille_preparation_jury prepa_jury = feuille_preparation_jury(formsemestre_id) return error_response(501, message="Not implemented") @bp.route("/jury/formsemestre//decisions_jury", methods=["GET"]) def jury_decisions(formsemestre_id: int): # XXX TODO check à quoi resemble le retour de la fonction """ Retourne les décisions du jury suivant un formsemestre donné formsemestre_id : l'id d'un formsemestre """ # Fonction utilisée : app.scodoc.sco_pvjury.formsemestre_pvjury() # Utilisation de la fonction formsemestre_pvjury decision_jury = formsemestre_pvjury(formsemestre_id) return error_response(501, message="Not implemented") @bp.route("/jury/set_decision/etudid?etudid=&formsemestre_id=" "&jury=&devenir=&assiduite=", methods=["POST"]) @bp.route("/jury/set_decision/nip?etudid=&formsemestre_id=" "&jury=&devenir=&assiduite=", methods=["POST"]) @bp.route("/jury/set_decision/ine?etudid=&formsemestre_id=" "&jury=&devenir=&assiduite=", methods=["POST"]) def set_decision_jury(formsemestre_id: int, decision_jury: str, devenir_jury: str, assiduite: bool, etudid: int = None, nip: int = None, ine: int = None): """ Attribuer la décision du jury et le devenir à un etudiant formsemestre_id : l'id d'un formsemestre decision_jury : la décision du jury devenir_jury : le devenir du jury assiduite : True ou False etudid : l'etudid d'un étudiant nip: le code nip d'un étudiant ine : le code ine d'un étudiant """ return error_response(501, message="Not implemented") @bp.route("/jury/etudid//formsemestre//annule_decision", methods=["DELETE"]) @bp.route("/jury/nip//formsemestre//annule_decision", methods=["DELETE"]) @bp.route("/jury/ine//formsemestre//annule_decision", methods=["DELETE"]) def annule_decision_jury(formsemestre_id: int, etudid: int = None, nip: int = None, ine: int = None): """ Supprime la déciosion du jury pour un étudiant 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 """ return error_response(501, message="Not implemented") #################################################### Absences ######################################################### @bp.route("/absences/etudid/", methods=["GET"]) @bp.route("/absences/nip/", methods=["GET"]) @bp.route("/absences/ine/", methods=["GET"]) def absences(etudid: int = None, nip: int = None, ine: int = None): """ Retourne la liste des absences d'un étudiant donné etudid : l'etudid d'un étudiant nip: le code nip d'un étudiant ine : le code ine d'un étudiant """ abs = None if etudid is not None: # Si route etudid # Récupération des absences de l'étudiant abs = models.Absence.query.filter_by(etudid=etudid).all() else: if nip is not None: # Si route nip # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_nip=nip).first() # Récupération des absences de l'étudiant abs = models.Absence.query.filter_by(etudid=etu.etudid).all() if ine is not None: # Si route ine # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_ine=ine).first() # Récupération des absences de l'étudiant abs = models.Absence.query.filter_by(etudid=etu.etudid).all() if abs is not None: # Si des absences ont bien été trouvé # Mise en forme des données data = [d.to_dict() for d in abs] return jsonify(data) return error_response(501, message="Not implemented") @bp.route("/absences/etudid//abs_just_only", methods=["GET"]) @bp.route("/absences/nip//abs_just_only", methods=["GET"]) @bp.route("/absences/ine//abs_just_only", methods=["GET"]) def absences_justify(etudid: int = None, nip: int = None, ine: int = None): """ Retourne la liste des absences justifiées d'un étudiant donné etudid : l'etudid d'un étudiant nip: le code nip d'un étudiant ine : le code ine d'un étudiant """ abs = None if etudid is not None: # Si route etudid # Récupération des absences justifiées de l'étudiant abs = models.Absence.query.filter_by(etudid=etudid, estjust=True).all() else: if nip is not None: # Si route nip # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_nip=nip).first() # Récupération des absences justifiées de l'étudiant abs = models.Absence.query.filter_by(etudid=etu.etudid, estjust=True).all() if ine is not None: # Si route ine # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_ine=ine).first() # Récupération des absences justifiées de l'étudiant abs = models.Absence.query.filter_by(etudid=etu.etudid, estjust=True).all() if abs is not None: # Si des absences ont bien été trouvé # Mise en forme des données data = [d.to_dict() for d in abs] return jsonify(data) return error_response(501, message="Not implemented") @bp.route("/absences/abs_signale?etudid=&date=&matin=&justif=" "&description=", methods=["POST"]) @bp.route("/absences/abs_signale?nip=&date=&matin=&justif=" "&description=", methods=["POST"]) @bp.route("/absences/abs_signale?ine=&date=&matin=&justif=" "&description=", methods=["POST"]) @bp.route("/absences/abs_signale?ine=&date=&matin=&justif=" "&description=&moduleimpl_id=", methods=["POST"]) @token_auth.login_required def abs_signale(date: datetime, matin: bool, justif: bool, etudid: int = None, nip: int = None, ine: int = None, description: str = None, moduleimpl_id: int = None): """ Permet d'ajouter une absence en base date : la date de l'absence matin : True ou False justif : True ou False etudid : l'etudid d'un étudiant nip: le code nip d'un étudiant ine : le code ine d'un étudiant description : description possible à ajouter sur l'absence moduleimpl_id : l'id d'un moduleimpl """ # Fonctions utilisées : app.scodoc.sco_abs.add_absence() et app.scodoc.sco_abs.add_justif() if description is not None: # Si la description a été renseignée if moduleimpl_id is not None: # Si le moduleimpl a été renseigné if etudid is not None: # Si route etudid try: # Utilisation de la fonction add_absence add_absence(etudid, date, matin, justif, description, moduleimpl_id) # Utilisation de la fonction add_justif add_justif(etudid, date, matin, description) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") if nip is not None: # Si route nip # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_nip=nip).first() try: # Utilisation de la fonction add_absence add_absence(etu.etudid, date, matin, justif, description, moduleimpl_id) # Utilisation de la fonction add_justif add_justif(etu.etudid, date, matin, description) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") if ine is not None: # Si route ine # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_ine=ine).first() try: # Utilisation de la fonction add_absence add_absence(etu.etudid, date, matin, justif, description, moduleimpl_id) # Utilisation de la fonction add_justif add_justif(etu.etudid, date, matin, description) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return error_response(409, message="La requête ne peut être traitée en l’état actuel") else: # Si le moduleimpl n'a pas été renseigné if etudid is not None: # Si route etudid try: # Utilisation de la fonction add_absence add_absence(etudid, date, matin, justif, description) # Utilisation de la fonction add_justif add_justif(etudid, date, matin, description) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") if nip is not None: # Si route nip # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_nip=nip).first() try: # Utilisation de la fonction add_absence add_absence(etu.etudid, date, matin, justif, description) # Utilisation de la fonction add_justif add_justif(etu.etudid, date, matin, description) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") if ine is not None: # Si route ine # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_ine=ine).first() try: # Utilisation de la fonction add_absence add_absence(etu.etudid, date, matin, justif, description) # Utilisation de la fonction add_justif add_justif(etu.etudid, date, matin, description) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return error_response(409, message="La requête ne peut être traitée en l’état actuel") else: if etudid is not None: # Si route etudid try: # Utilisation de la fonction add_absence add_absence(etudid, date, matin, justif) # Utilisation de la fonction add_justif add_justif(etudid, date, matin) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") if nip is not None: # Si route nip # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_nip=nip).first() try: # Utilisation de la fonction add_absence add_absence(etu.etudid, date, matin, justif) # Utilisation de la fonction add_justif add_justif(etu.etudid, date, matin) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") if ine is not None: # Si route ine # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_ine=ine).first() try: # Utilisation de la fonction add_absence add_absence(etu.etudid, date, matin, justif) # Utilisation de la fonction add_justif add_justif(etu.etudid, date, matin) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return error_response(200, message="OK") @bp.route("/absences/abs_annule?etudid=&jour=&matin=", methods=["POST"]) @bp.route("/absences/abs_annule?nip=&jour=&matin=", methods=["POST"]) @bp.route("/absences/abs_annule?ine=&jour=&matin=", methods=["POST"]) @token_auth.login_required def abs_annule(jour: datetime, matin: str, etudid: int = None, nip: int = None, ine: int = None): """ Retourne un html jour : la date de l'absence a annulé matin : True ou False etudid : l'etudid d'un étudiant nip: le code nip d'un étudiant ine : le code ine d'un étudiant """ # Fonction utilisée : app.scodoc.sco_abs.annule_absence() if etudid is None: if nip is not None: # Si route nip # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_nip=nip).first() # Récupération de l'etudid de l'étudiant etudid = etu.etudid if ine is not None: # Si route ine # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_ine=ine).first() # Récupération de l'etudid de l'étudiant etudid = etu.etudid try: # Utilisation de la fonction annule_absence annule_absence(etudid, jour, matin) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return error_response(200, message="OK") @bp.route("/absences/abs_annule_justif?etudid=&jour=&matin=", methods=["POST"]) @bp.route("/absences/abs_annule_justif?nip=&jour=&matin=", methods=["POST"]) @bp.route("/absences/abs_annule_justif?ine=&jour=&matin=", methods=["POST"]) @token_auth.login_required def abs_annule_justif(jour: datetime, matin: str, etudid: int = None, nip: int = None, ine: int = None): """ Retourne un html jour : la date de l'absence a annulé matin : True ou False etudid : l'etudid d'un étudiant nip: le code nip d'un étudiant ine : le code ine d'un étudiant """ # Fonction utilisée : app.scodoc.sco_abs.annule_justif() if etudid is None: if nip is not None: # Si route nip # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_nip=nip).first() # Récupération de l'etudid de l'étudiant etudid = etu.etudid if ine is not None: # Si route ine # Récupération de l'étudiant etu = models.Identite.query.filter_by(code_ine=ine).first() # Récupération de l'etudid de l'étudiant etudid = etu.etudid try: # Utilisation de la fonction annule_justif annule_justif(etudid, jour, matin) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") return error_response(200, message="OK") @bp.route("/absences/abs_group_etat/?group_id=&date_debut=date_debut&date_fin=date_fin", methods=["GET"]) def abs_groupe_etat(group_id: int, date_debut, date_fin, with_boursier=True, format="html"): """ Retoune la liste des absences d'un ou plusieurs groupes entre deux dates """ # Fonction utilisée : app.scodoc.sco_groups.get_group_members() et app.scodoc.sco_abs.list_abs_date() try: # Utilisation de la fonction get_group_members members = get_group_members(group_id) except ValueError: return error_response(409, message="La requête ne peut être traitée en l’état actuel") data = [] # Filtre entre les deux dates renseignées for member in members: abs = list_abs_date(member.id, date_debut, date_fin) data.append(abs) # return jsonify(data) # XXX TODO faire en sorte de pouvoir renvoyer sa (ex to_dict() dans absences) return error_response(501, message="Not implemented") ###################################################### Logos ########################################################## # XXX TODO voir get_logo déjà existant dans app/views/scodoc.py @bp.route("/logos", methods=["GET"]) def liste_logos(format="json"): """ Liste des logos définis pour le site scodoc. """ # fonction to use : list_logos() # try: # res = list_logos() # except ValueError: # return error_response(409, message="La requête ne peut être traitée en l’état actuel") # # if res is None: # return error_response(200, message="Aucun logo trouvé correspondant aux informations renseignés") # # return res @bp.route("/logos/", methods=["GET"]) def recup_logo_global(logo_name: str): """ Retourne l'image au format png ou jpg logo_name : le nom du logo rechercher """ # fonction to use find_logo # try: # res = find_logo(logo_name) # except ValueError: # return error_response(409, message="La requête ne peut être traitée en l’état actuel") # # if res is None: # return error_response(200, message="Aucun logo trouvé correspondant aux informations renseignés") # # return res @bp.route("/departements//logos", methods=["GET"]) def logo_dept(dept: str): """ Liste des logos définis pour le département visé. dept : l'id d'un département """ # fonction to use: _list_dept_logos # dept_id = models.Departement.query.filter_by(acronym=dept).first() # try: # res = _list_dept_logos(dept_id.id) # except ValueError: # return error_response(409, message="La requête ne peut être traitée en l’état actuel") # # if res is None: # return error_response(200, message="Aucun logo trouvé correspondant aux informations renseignés") # # return res @bp.route("/departement//logos/", methods=["GET"]) def recup_logo_dept_global(dept: str, logo_name: str): """ L'image format png ou jpg dept : l'id d'un département logo_name : le nom du logo rechercher """ # fonction to use find_logo # dept_id = models.Departement.query.filter_by(acronym=dept).first() # try: # res = find_logo(logo_name, dept_id.id) # except ValueError: # return error_response(409, message="La requête ne peut être traitée en l’état actuel") # # if res is None: # return error_response(200, message="Aucun logo trouvé correspondant aux informations renseignés") # # return res ################################################## Tests ############################################################## import requests import os SCODOC_USER = "" SCODOC_PASSWORD = "" SCODOC_URL = "" CHECK_CERTIFICATE = bool(int(os.environ.get("CHECK_CERTIFICATE", False))) # r0 = requests.post( # SCODOC_URL + "/ScoDoc/api/tokens", auth=(SCODOC_USER, SCODOC_PASSWORD) # ) # token = r0.json()["token"] # HEADERS = {"Authorization": f"Bearer {token}"} DEPT = None FORMSEMESTRE = None ETU = None @bp.route("/test_dept", methods=["GET"]) def get_departement(): """ Retourne un département pour les tests """ r = requests.get( SCODOC_URL + "/ScoDoc/api/departements", auth=(SCODOC_USER, SCODOC_PASSWORD) ) if r.status_code == 200: dept_id = r.json()[0] # print(dept_id) dept = models.Departement.query.filter_by(id=dept_id).first() dept = dept.to_dict() if "id" in dept: if "acronym" in dept: if "description" in dept: if "visible" in dept: if "date_creation" in dept: global DEPT DEPT = dept return error_response(200, "OK") else: return error_response(501, "date_creation field missing") else: return error_response(501, "visible field missing") else: return error_response(501, "description field missing") else: return error_response(501, "acronym field missing") else: return error_response(501, "id field missing") return error_response(409, "La requête ne peut être traitée en l’état actuel") @bp.route("/test_formsemestre", methods=["GET"]) def get_formsemestre(): """ Retourne un formsemestre pour les tests """ global DEPT dept_acronym = DEPT["acronym"] r = requests.get( SCODOC_URL + "/ScoDoc/api/departements/" + dept_acronym + "/semestres_courant", auth=(SCODOC_USER, SCODOC_PASSWORD) ) if r.status_code == 200: formsemestre = r.json()[0] # print(r.json()[0]) if "titre" in formsemestre: if "gestion_semestrielle" in formsemestre: if "scodoc7_id" in formsemestre: if "date_debut" in formsemestre: if "bul_bgcolor" in formsemestre: if "date_fin" in formsemestre: if "resp_can_edit" in formsemestre: if "semestre_id" in formsemestre: if "bul_hide_xml" in formsemestre: if "elt_annee_apo" in formsemestre: if "block_moyennes" in formsemestre: if "formsemestre_id" in formsemestre: if "titre_num" in formsemestre: if "date_debut_iso" in formsemestre: if "date_fin_iso" in formsemestre: if "responsables" in formsemestre: global FORMSEMESTRE FORMSEMESTRE = formsemestre # print(FORMSEMESTRE) return error_response(200, "OK") else: return error_response(501, "responsables field " "missing") else: return error_response(501, "date_fin_iso field missing") else: return error_response(501, "date_debut_iso field missing") else: return error_response(501, "titre_num field missing") else: return error_response(501, "formsemestre_id field missing") else: return error_response(501, "block_moyennes field missing") else: return error_response(501, "elt_annee_apo field missing") else: return error_response(501, "bul_hide_xml field missing") else: return error_response(501, "semestre_id field missing") else: return error_response(501, "resp_can_edit field missing") else: return error_response(501, "date_fin field missing") else: return error_response(501, "bul_bgcolor field missing") else: return error_response(501, "date_debut field missing") else: return error_response(501, "scodoc7_id field missing") else: return error_response(501, "gestion_semestrielle field missing") else: return error_response(501, "titre field missing") return error_response(409, "La requête ne peut être traitée en l’état actuel") @bp.route("/test_etu", methods=["GET"]) def get_etudiant(): """ Retourne un étudiant pour les tests """ # print(DEPT.get_data().decode("utf-8")) # dept = DEPT r = requests.get( SCODOC_URL + "/ScoDoc/api/etudiants", auth=(SCODOC_USER, SCODOC_PASSWORD) ) if r.status_code == 200: etu = r.json()[0] if "civilite" in etu: if "code_ine" in etu: if "code_nip" in etu: if "date_naissance" in etu: if "email" in etu: if "emailperso" in etu: if "etudid" in etu: if "nom" in etu: if "prenom" in etu: global ETU ETU = etu # print(ETU) return error_response(200, "OK") else: return error_response(501, "prenom field missing") else: return error_response(501, "nom field missing") else: return error_response(501, "etudid field missing") else: return error_response(501, "emailperso field missing") else: return error_response(501, "email field missing") else: return error_response(501, "date_naissance field missing") else: return error_response(501, "code_nip field missing") else: return error_response(501, "code_ine field missing") else: return error_response(501, "civilite field missing") return error_response(409, "La requête ne peut être traitée en l’état actuel") def test_routes_departements(): """ Test les routes de la partie Département """ # departements r1 = requests.get( SCODOC_URL + "/ScoDoc/api/departements", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # liste_etudiants r2 = requests.post( SCODOC_URL + "/ScoDoc/api/departements//etudiants/liste/", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # liste_semestres_courant r3 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # referenciel_competences r4 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # semestre_index r5 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) def test_routes_etudiants(): """ Test les routes de la partie Etudiants """ # etudiants r1 = requests.get( SCODOC_URL + "/ScoDoc/api/etudiants", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # etudiants_courant r2 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # etudiant r3 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # etudiant_formsemestres r4 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # etudiant_bulletin_semestre r5 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # etudiant_groups r6 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) def test_routes_formation(): """ Test les routes de la partie Formation """ # formations r1 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # formations_by_id r2 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # formation_export_by_formation_id r3 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # formsemestre_apo r4 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # moduleimpls r5 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # moduleimpls_sem r6 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) def test_routes_formsemestres(): """ Test les routes de la partie Formsemestres """ # formsemestre r1 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # etudiant_bulletin r2 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # bulletins r3 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # jury r4 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) def test_routes_partitions(): """ Test les routes de la partie Partitions """ # partition r1 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # etud_in_group r2 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # set_groups r3 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) def test_routes_evaluations(): """ Test les routes de la partie Evaluations """ # evaluations r1 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # evaluation_notes r2 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # evaluation_set_notes r3 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) def test_routes_jury(): """ Test les routes de la partie Jury """ # jury_preparation r1 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # jury_decisions r2 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # set_decision_jury r3 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # annule_decision_jury r4 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) def test_routes_absences(): """ Test les routes de la partie Absences """ # absences r1 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # absences_justify r2 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # abs_signale r3 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # abs_annule r4 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # abs_annule_justif r5 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # abs_groupe_etat r6 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) def test_routes_logos(): """ Test les routes de la partie Logos """ # liste_logos r1 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # recup_logo_global r2 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # logo_dept r3 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) ) # recup_logo_dept_global r4 = requests.post( SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD) )