############################################################################## # 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//notes") @api_web_bp.route("/operations/user//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 """ # --- Permission: restreint au superadmin ou à l'utilisateur lui-même if not app.current_user.is_administrator() and app.current_user.id != uid: return {"error": "Permission denied"}, 403 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"""{note.evaluation.descr()}""", } 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, }