ScoDoc-PE/app/api/partitions.py

188 lines
6.0 KiB
Python

##############################################################################
# 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/<int:partition_id>", 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/<int:formsemestre_id>/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/<int:group_id>/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/<int:group_id>/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/<int:group_id>/set_etudiant/<int:etudid>", 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/<int:partition_id>/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/<int:group_id>/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/<init:group_id>/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))