############################################################################## # ScoDoc # Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved. # See LICENSE ############################################################################## """ ScoDoc 9 API : partitions """ from flask import abort, jsonify, request from app import db from app.api import bp from app.api.auth import token_auth, token_permission_required from app.models import FormSemestre, FormSemestreInscription, Identite from app.models import GroupDescr, Partition from app.models.groups import group_membership from app.scodoc.sco_permissions import Permission from app.scodoc import sco_utils as scu @bp.route("/partition/", methods=["GET"]) @token_auth.login_required @token_permission_required(Permission.APIView) def partition_info(partition_id: int): """ Exemple de résultat : ``` { 'bul_show_rank': False, 'formsemestre_id': 39, 'groups': [ {'id': 268, 'name': 'A', 'partition_id': 100}, {'id': 269, 'name': 'B', 'partition_id': 100} ], 'groups_editable': True, 'id': 100, 'numero': 100, 'partition_name': 'TD', 'show_in_lists': True } ``` """ partition = Partition.query.get_or_404(partition_id) return jsonify(partition.to_dict(with_groups=True)) @bp.route("/formsemestre//partitions", methods=["GET"]) @token_auth.login_required @token_permission_required(Permission.APIView) def formsemestre_partitions(formsemestre_id: int): """ Retourne la liste de toutes les partitions d'un formsemestre formsemestre_id : l'id d'un formsemestre """ formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) return jsonify( [partition.to_dict(with_groups=True) for partition in formsemestre.partitions] ) @bp.route("/group//etudiants", methods=["GET"]) @token_auth.login_required @token_permission_required(Permission.APIView) def etud_in_group(group_id: int): """ Retourne la liste des étudiants dans un groupe group_id : l'id d'un groupe Exemple de résultat : [ { 'civilite': 'M', 'id': 123456, 'ine': None, 'nip': '987654321', 'nom': 'MARTIN', 'nom_usuel': null, 'prenom': 'JEAN'} }, ... ] """ group = GroupDescr.query.get_or_404(group_id) return jsonify([etud.to_dict_short() for etud in group.etuds]) @bp.route("/group//etudiants/query", methods=["GET"]) @token_auth.login_required @token_permission_required(Permission.APIView) def etud_in_group_query(group_id: int): """Etudiants du groupe, filtrés par état""" etat = request.get("etat", "") if etat not in {scu.INSCRIT, scu.DEMISSION, scu.DEF}: abort(404, "etat invalid") group = GroupDescr.query.get_or_404(group_id) query = ( Identite.query.join(FormSemestreInscription) .filter_by(formsemestre_id=group.partition.formsemestre_id, etat=etat) .join(group_membership) .filter_by(group_id=group_id) ) return jsonify([etud.to_dict_short() for etud in query]) @bp.route("/group//set_etudiant/", methods=["POST"]) @token_auth.login_required @token_permission_required(Permission.APIEditGroups) def set_etud_group(etudid: int, group_id: int): """Affecte l'étudiant au groupe indiqué""" etud = Identite.query.get_or_404(etudid) group = GroupDescr.query.get_or_404(group_id) if etud.id not in {e.id for e in group.partition.formsemestre.etuds}: abort(404, "etud non inscrit au formsemestre du groupe") groups = ( GroupDescr.query.filter_by(partition_id=group.partition.id) .join(group_membership) .filter_by(etudid=etudid) ) ok = False for group in groups: if group.id == group_id: ok = True else: group.etuds.remove(etud) if not ok: group.etuds.append(etud) db.session.commit() return jsonify({"group_id": group_id, "etudid": etudid}) @bp.route("/partition//group/create", methods=["POST"]) @token_auth.login_required @token_permission_required(Permission.APIEditGroups) def group_create(partition_id: int): """Création d'un groupe dans une partition The request content type should be "application/json": { "group_name" : nom_du_groupe, } """ partition: Partition = Partition.query.get_or_404(partition_id) data = request.get_json(force=True) # may raise 400 Bad Request group_name = data.get("group_name") if group_name is None: abort(404, "missing group name or invalid data format") if not GroupDescr.check_name(partition, group_name): abort(404, "invalid group_name") group_name = group_name.strip() group = GroupDescr(group_name=group_name, partition_id=partition_id) db.session.add(group) db.session.commit() return jsonify(group.to_dict(with_partition=True)) @bp.route("/group//delete", methods=["POST"]) @token_auth.login_required @token_permission_required(Permission.APIEditGroups) def group_delete(group_id: int): """Delete group""" group = GroupDescr.query.get_or_404(group_id) db.session.delete(group) db.session.commit() return jsonify({"OK": 1}) @bp.route("/group//edit", methods=["POST"]) @token_auth.login_required @token_permission_required(Permission.APIEditGroups) def group_edit(group_id: int): """Edit a group""" group: GroupDescr = GroupDescr.query.get_or_404(group_id) data = request.get_json(force=True) # may raise 400 Bad Request group_name = data.get("group_name") if group_name is not None: if not GroupDescr.check_name(group.partition, group_name, existing=True): abort(404, "invalid group_name") group.group_name = group_name.strip() db.session.add(group) db.session.commit() return jsonify(group.to_dict(with_partition=True))