From d6ebb55b95ea2d72d46409b242cc862d5432b61a Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sun, 12 Dec 2021 15:55:04 +0100 Subject: [PATCH] support old json export for BUT, using format=oldjson --- app/but/bulletin_but.py | 98 +++++++++++++++++++++++++++++++- app/models/moduleimpls.py | 1 + app/scodoc/notes_table.py | 2 +- app/scodoc/sco_bulletins_json.py | 13 ++++- app/views/notes.py | 4 +- 5 files changed, 113 insertions(+), 5 deletions(-) diff --git a/app/but/bulletin_but.py b/app/but/bulletin_but.py index 49c419f26..df9409e5c 100644 --- a/app/but/bulletin_but.py +++ b/app/but/bulletin_but.py @@ -4,6 +4,7 @@ # See LICENSE ############################################################################## +from collections import defaultdict import datetime from flask import url_for, g import numpy as np @@ -11,7 +12,8 @@ import pandas as pd from app import db -from app.comp import df_cache, moy_ue, moy_sem, inscr_mod +from app.comp import moy_ue, moy_sem, inscr_mod +from app.models import ModuleImpl from app.scodoc import sco_utils as scu from app.scodoc.sco_cache import ResultatsSemestreBUTCache from app.scodoc.sco_exceptions import ScoFormatError @@ -280,3 +282,97 @@ def bulletin_option_affichage(formsemestre): ) # on enlève le "bul_" de la clé: return {field[4:]: prefs[field] for field in fields} + + +# Pour raccorder le code des anciens bulletins qui attendent une NoteTable +class APCNotesTableCompat: + """Implementation partielle de NotesTable pour les formations APC + Accès aux notes et rangs. + """ + + def __init__(self, formsemestre): + self.results = ResultatsSemestreBUT(formsemestre) + nb_etuds = len(self.results.etuds) + self.rangs = self.results.etud_moy_gen_ranks + self.moy_min = self.results.etud_moy_gen.min() + self.moy_max = self.results.etud_moy_gen.max() + self.moy_moy = self.results.etud_moy_gen.mean() + self.bonus = defaultdict(lambda: 0.0) # XXX + self.ue_rangs = { + u.id: (defaultdict(lambda: 0.0), nb_etuds) for u in self.results.ues + } + self.mod_rangs = { + m.id: (defaultdict(lambda: 0), nb_etuds) for m in self.results.modimpls + } + + def get_ues(self): + ues = [] + for ue in self.results.ues: + d = ue.to_dict() + d.update( + { + "max": self.results.etud_moy_ue[ue.id].max(), + "min": self.results.etud_moy_ue[ue.id].min(), + "moy": self.results.etud_moy_ue[ue.id].mean(), + "nb_moy": len(self.results.etud_moy_ue), + } + ) + ues.append(d) + return ues + + def get_modimpls(self): + return [m.to_dict() for m in self.results.modimpls] + + def get_etud_moy_gen(self, etudid): + return self.results.etud_moy_gen[etudid] + + def get_moduleimpls_attente(self): + return [] # XXX TODO + + def get_etud_rang(self, etudid): + return self.rangs[etudid] + + def get_etud_rang_group(self, etudid, group_id): + return (None, 0) # XXX unimplemented TODO + + def get_etud_ue_status(self, etudid, ue_id): + return { + "cur_moy_ue": self.results.etud_moy_ue[ue_id][etudid], + "is_capitalized": False, # XXX TODO + } + + def get_etud_mod_moy(self, moduleimpl_id, etudid): + mod_idx = self.results.modimpl_coefs_df.columns.get_loc(moduleimpl_id) + etud_idx = self.results.etud_index[etudid] + # moyenne sur les UE: + self.results.sem_cube[etud_idx, mod_idx].mean() + + def get_mod_stats(self, moduleimpl_id): + return { + "moy": "-", + "max": "-", + "min": "-", + "nb_notes": "-", + "nb_missing": "-", + "nb_valid_evals": "-", + } + + def get_evals_in_mod(self, moduleimpl_id): + mi = ModuleImpl.query.get(moduleimpl_id) + evals_results = [] + for e in mi.evaluations: + d = e.to_dict() + d["heure_debut"] = e.heure_debut # datetime.time + d["heure_fin"] = e.heure_fin + d["jour"] = e.jour # datetime + d["notes"] = { + etud.id: { + "etudid": etud.id, + "value": self.results.modimpls_evals_notes[e.moduleimpl_id][e.id][ + etud.id + ], + } + for etud in self.results.etuds + } + evals_results.append(d) + return evals_results diff --git a/app/models/moduleimpls.py b/app/models/moduleimpls.py index 2da7cb01f..172fe0767 100644 --- a/app/models/moduleimpls.py +++ b/app/models/moduleimpls.py @@ -84,6 +84,7 @@ class ModuleImpl(db.Model): e["ens"] = [ {"moduleimpl_id": self.id, "ens_id": e.id} for e in self.enseignants ] + e["module"] = self.module.to_dict() return e diff --git a/app/scodoc/notes_table.py b/app/scodoc/notes_table.py index cabc373b9..7a6cfd050 100644 --- a/app/scodoc/notes_table.py +++ b/app/scodoc/notes_table.py @@ -143,7 +143,7 @@ def comp_etud_sum_coef_modules_ue(formsemestre_id, etudid, ue_id): return s -class NotesTable(object): +class NotesTable: """Une NotesTable représente un tableau de notes pour un semestre de formation. Les colonnes sont des modules. Les lignes des étudiants. diff --git a/app/scodoc/sco_bulletins_json.py b/app/scodoc/sco_bulletins_json.py index 7ad1653b9..c79591807 100644 --- a/app/scodoc/sco_bulletins_json.py +++ b/app/scodoc/sco_bulletins_json.py @@ -31,6 +31,9 @@ import datetime import json +from app.but import bulletin_but +from app.models.formsemestre import FormSemestre + import app.scodoc.sco_utils as scu import app.scodoc.notesdb as ndb from app.scodoc import sco_abs @@ -82,9 +85,16 @@ def formsemestre_bulletinetud_published_dict( """ from app.scodoc import sco_bulletins + formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + sem = sco_formsemestre.get_formsemestre(formsemestre_id) + + if formsemestre.formation.is_apc(): + nt = bulletin_but.APCNotesTableCompat(formsemestre) + else: + nt = sco_cache.NotesTableCache.get(formsemestre_id) + d = {} - sem = sco_formsemestre.get_formsemestre(formsemestre_id) if (not sem["bul_hide_xml"]) or force_publishing: published = 1 else: @@ -136,7 +146,6 @@ def formsemestre_bulletinetud_published_dict( pid = partition["partition_id"] partitions_etud_groups[pid] = sco_groups.get_etud_groups_in_partition(pid) - nt = sco_cache.NotesTableCache.get(formsemestre_id) # > toutes notes ues = nt.get_ues() modimpls = nt.get_modimpls() nbetuds = len(nt.rangs) diff --git a/app/views/notes.py b/app/views/notes.py index 98117d3a6..9a8797e61 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -286,7 +286,7 @@ def formsemestre_bulletinetud( code_nip=None, ): formsemestre = FormSemestre.query.get_or_404(formsemestre_id) - if formsemestre.formation.is_apc(): + if formsemestre.formation.is_apc() and format != "oldjson": if etudid: etud = models.Identite.query.get_or_404(etudid) elif code_nip: @@ -312,6 +312,8 @@ def formsemestre_bulletinetud( if not (etudid or code_nip): raise ScoValueError("Paramètre manquant: spécifier code_nip ou etudid") + if format == "oldjson": + format = "json" return sco_bulletins.formsemestre_bulletinetud( etudid=etudid, formsemestre_id=formsemestre_id,