ScoDoc/app/api/operations.py

101 lines
3.3 KiB
Python

##############################################################################
# ScoDoc
# Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved.
# See LICENSE
##############################################################################
"""
ScoDoc 9 API : liste opérations effectuées par un utilisateur
CATEGORY
--------
Operations
"""
from flask import url_for
from flask_json import as_json
from flask_login import login_required
import app
from app import db
from app.api import api_bp as bp, api_web_bp
from app.api import api_permission_required as permission_required
from app.decorators import scodoc
from app.models import NotesNotes
from app.scodoc.sco_permissions import Permission
from app.scodoc import sco_utils as scu
MAX_QUERY_LENGTH = 10000
@bp.route("/operations/user/<int:uid>/notes")
@api_web_bp.route("/operations/user/<int:uid>/notes")
@login_required
@scodoc
@permission_required(Permission.ScoView)
@as_json
def operations_user_notes(uid: int):
"""Liste les opérations de saisie de notes effectuées par utilisateur.
QUERY
-----
start: indice de début de la liste
length: nombre d'éléments à retourner
draw: numéro de la requête (pour pagination, renvoyé tel quel)
order[dir]: desc ou asc
search[value]: chaîne à chercher (dans évaluation et étudiant)
PARAMS
-----
uid: l'id de l'utilisateur
"""
start = int(app.request.args.get("start", 0))
length = min(int(app.request.args.get("length", 10)), MAX_QUERY_LENGTH)
order = app.request.args.get("order[dir]", "desc")
draw = int(app.request.args.get("draw", 1))
search = app.request.args.get("search[value]", "")
query = db.session.query(NotesNotes).filter(NotesNotes.uid == uid)
if order == "asc":
query = query.order_by(NotesNotes.date.asc())
else:
query = query.order_by(NotesNotes.date.desc())
# Pour l'efficacité, limite si pas de recherche en python
limited_query = query.offset(start).limit(length) if not search else query
data = []
for note in limited_query:
obj = {
"date": note.date.isoformat(),
"date_dmy": note.date.strftime(scu.DATEATIME_FMT),
"operation": "Saisie de note",
"value": scu.fmt_note(note.value),
"id": note.id,
"uid": note.uid,
"etudiant": note.etudiant.to_dict_short(),
"etudiant_link": note.etudiant.html_link_fiche(),
"evaluation": note.evaluation.to_dict_api(),
"evaluation_link": f"""<a href="{
url_for('notes.evaluation_listenotes',
scodoc_dept=note.evaluation.moduleimpl.formsemestre.departement.acronym,
evaluation_id=note.evaluation_id)
}">{note.evaluation.descr()}</a>""",
}
if search:
search = search.lower()
if (
search not in note.etudiant.nomprenom.lower()
and search not in note.evaluation.descr().lower()
and search not in obj["date_dmy"]
):
continue # skip
data.append(obj)
result = data[start : start + length] if search else data
return {
"draw": draw,
"recordsTotal": query.count(), # unfiltered
"recordsFiltered": len(data) if search else query.count(),
"data": result,
}