minor changes

This commit is contained in:
Jean-Marie Place 2021-09-17 09:44:47 +02:00
parent 0ef822cfd8
commit b6cc251c94

View File

@ -30,57 +30,50 @@
Contribution M. Salomon, UFC / IUT DE BELFORT-MONTBÉLIARD, 2016 Contribution M. Salomon, UFC / IUT DE BELFORT-MONTBÉLIARD, 2016
""" """
import six.moves.urllib.request, six.moves.urllib.parse, six.moves.urllib.error
import random import random
import time import time
from copy import copy from copy import copy
import wtforms.validators import wtforms.validators
from flask import request, render_template, url_for from flask import request, render_template
from flask_login import current_user from flask_login import current_user
from werkzeug import Response
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from openpyxl.styles import PatternFill, Alignment, Border, Side, Font
from wtforms import ( from wtforms import (
StringField, StringField,
PasswordField,
BooleanField,
SubmitField, SubmitField,
SelectField, SelectField,
RadioField, RadioField,
HiddenField, HiddenField,
SelectMultipleField, SelectMultipleField,
validators,
) )
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
from app.scodoc.sco_exceptions import ScoValueError
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc import html_sco_header from app import ScoValueError
from app.scodoc import html_sco_header, sco_preferences
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_excel from app.scodoc import sco_excel
from app.scodoc.sco_excel import ScoExcelBook, COLORS
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
from app.scodoc import sco_permissions_check from app.scodoc import sco_permissions_check
from app.scodoc import sco_preferences from app.scodoc.gen_tables import GenTable
from app.scodoc import sco_saisie_notes
from app.scodoc import sco_etud from app.scodoc import sco_etud
import sco_version import sco_version
from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_excel import * # XXX à vérifier
from app.scodoc.TrivialFormulator import TrivialFormulator
_ = lambda x: x # sans babel # _ = lambda x: x # sans babel
_l = _ # _l = _
COORD = "Coordonnées" COORD = "Coordonnées"
SEQ = "Continue" SEQ = "Continue"
class PlacementForm(FlaskForm): class PlacementForm(FlaskForm):
"""Formulaire pour placement des étudiants en Salle"""
TOUS = "Tous" TOUS = "Tous"
evaluation_id = HiddenField("evaluation_id") evaluation_id = HiddenField("evaluation_id")
file_format = RadioField( file_format = RadioField(
@ -112,10 +105,10 @@ class PlacementForm(FlaskForm):
submit = SubmitField("OK") submit = SubmitField("OK")
def set_evaluation_infos(self, evaluation_id): def set_evaluation_infos(self, evaluation_id):
"""Initialise les données du formulaire avec les données de l'évaluation."""
eval_data = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id}) eval_data = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})
if not eval_data: if not eval_data:
raise ScoValueError("invalid evaluation_id") raise ScoValueError("invalid evaluation_id")
eval_data = eval_data[0]
# groupes # groupes
groups = sco_groups.do_evaluation_listegroupes( groups = sco_groups.do_evaluation_listegroupes(
evaluation_id, include_default=True evaluation_id, include_default=True
@ -123,7 +116,7 @@ class PlacementForm(FlaskForm):
self.groups_tree = {} self.groups_tree = {}
self.has_groups = False self.has_groups = False
for group in groups: for group in groups:
partition = group["partition_name"] or self.TOUS # TODO check required partition = group["partition_name"] or self.TOUS
group_id = group["group_id"] group_id = group["group_id"]
group_name = group["group_name"] or self.TOUS group_name = group["group_name"] or self.TOUS
if partition not in self.groups_tree: if partition not in self.groups_tree:
@ -136,8 +129,8 @@ class PlacementForm(FlaskForm):
choices = [] choices = []
for partition in self.groups_tree: for partition in self.groups_tree:
for groupe in self.groups_tree[partition]: for groupe in self.groups_tree[partition]:
id = str(self.groups_tree[partition][groupe]) groupe_id = str(self.groups_tree[partition][groupe])
choices.append((id, "%s (%s)" % (str(groupe), partition))) choices.append((groupe_id, "%s (%s)" % (str(groupe), partition)))
self.groups.choices = choices self.groups.choices = choices
@ -188,14 +181,16 @@ def placement_eval_selectetuds(evaluation_id):
""" """
% runner.__dict__ % runner.__dict__
) )
return runner._exec_placement() # calcul et generation du fichier return runner.exec_placement() # calcul et generation du fichier
# return flask.redirect(url_for("scodoc.index")) # return flask.redirect(url_for("scodoc.index"))
H = [html_sco_header.sco_header(init_jquery_ui=True)] htmls = [
H.append(sco_evaluations.evaluation_describe(evaluation_id=evaluation_id)) html_sco_header.sco_header(init_jquery_ui=True),
H.append("<h3>Placement et émargement des étudiants</h3>") sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),
H.append(render_template("scodoc/forms/placement.html", form=form)) "<h3>Placement et émargement des étudiants</h3>",
render_template("scodoc/forms/placement.html", form=form),
]
F = html_sco_header.sco_footer() F = html_sco_header.sco_footer()
return "\n".join(H) + "<p>" + F return "\n".join(htmls) + "<p>" + F
class PlacementRunner: class PlacementRunner:
@ -235,16 +230,14 @@ class PlacementRunner:
self.evaltitre = self.eval_data["description"] self.evaltitre = self.eval_data["description"]
else: else:
self.evaltitre = "évaluation du %s" % self.eval_data["jour"] self.evaltitre = "évaluation du %s" % self.eval_data["jour"]
self.desceval = [ self.desceval = [ # une liste de chaines: description de l'evaluation
["%s" % self.sem["titreannee"]], "%s" % self.sem["titreannee"],
["Module : %s - %s" % (self.Mod["code"], self.Mod["abbrev"])], "Module : %s - %s" % (self.Mod["code"], self.Mod["abbrev"]),
["Surveillants : %s" % self.surveillants], "Surveillants : %s" % self.surveillants,
["Batiment : %(batiment)s - Salle : %(salle)s" % self.__dict__], "Batiment : %(batiment)s - Salle : %(salle)s" % self.__dict__,
[
"Controle : %s (coef. %g)" "Controle : %s (coef. %g)"
% (self.evaltitre, self.eval_data["coefficient"]) % (self.evaltitre, self.eval_data["coefficient"]),
], ]
] # une liste de liste de chaines: description de l'evaluation
def check_placement(self): def check_placement(self):
# Check access (admin, respformation, and responsable_id) # Check access (admin, respformation, and responsable_id)
@ -252,7 +245,7 @@ class PlacementRunner:
self.current_user, self.moduleimpl_id self.current_user, self.moduleimpl_id
) )
def _exec_placement(self): def exec_placement(self):
self._repartition() self._repartition()
if self.file_format == "xls": if self.file_format == "xls":
return self._production_xls() return self._production_xls()
@ -271,7 +264,6 @@ class PlacementRunner:
def _build_listetud(self): def _build_listetud(self):
if None in [g["group_name"] for g in self.groups]: # tous les etudiants if None in [g["group_name"] for g in self.groups]: # tous les etudiants
getallstudents = True getallstudents = True
gr_title_filename = "tous"
else: else:
getallstudents = False getallstudents = False
etudids = sco_groups.do_evaluation_listeetuds_groups( etudids = sco_groups.do_evaluation_listeetuds_groups(
@ -310,18 +302,21 @@ class PlacementRunner:
return plan return plan
def _production_xls(self): def _production_xls(self):
filename = "placement_%s_%s%s" % (self.evalname, self.gr_title_filename, scu.XLSX_SUFFIX) filename = "placement_%s_%s%s" % (
self.evalname,
self.gr_title_filename,
scu.XLSX_SUFFIX,
)
xls = self._excel_feuille_placement() xls = self._excel_feuille_placement()
return sco_excel.send_from_flask(xls, filename) return sco_excel.send_from_flask(xls, filename)
def _production_pdf(self): def _production_pdf(self):
pdf_title = self.desceval pdf_title = "<br/>".join(self.desceval)
pdf_title += ( pdf_title += (
"Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s" "\nDate : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s"
% self.eval_data % self.eval_data
) )
breakpoint() filename = "placement_%(evalname)s_%(gr_title_filename)s" % self.__dict__
filename = "placement_%(evalname)s_%(gr_title_filename)s.pdf" % self.__dict__
titles = { titles = {
"nom": "Nom", "nom": "Nom",
"prenom": "Prenom", "prenom": "Prenom",
@ -329,7 +324,6 @@ class PlacementRunner:
"ligne": "Ligne", "ligne": "Ligne",
"place": "Place", "place": "Place",
} }
nb_rangs = int(self.nb_rangs)
if self.etiquetage == COORD: if self.etiquetage == COORD:
columns_ids = ["nom", "prenom", "colonne", "ligne"] columns_ids = ["nom", "prenom", "colonne", "ligne"]
else: else:
@ -348,7 +342,6 @@ class PlacementRunner:
) )
else: else:
rows.append({"nom": etud[0][0], "prenom": etud[0][1], "place": etud[1]}) rows.append({"nom": etud[0][0], "prenom": etud[0][1], "place": etud[1]})
tab = GenTable( tab = GenTable(
titles=titles, titles=titles,
columns_ids=columns_ids, columns_ids=columns_ids,
@ -359,10 +352,11 @@ class PlacementRunner:
+ "", + "",
pdf_title=pdf_title, pdf_title=pdf_title,
# pdf_shorttitle = '', # pdf_shorttitle = '',
preferences=sco_preferences.SemPreferences(self.moduleimpl_data["formsemestre_id"]), preferences=sco_preferences.SemPreferences(
# html_generate_cells=False # la derniere ligne (moyennes) est incomplete self.moduleimpl_data["formsemestre_id"]
),
) )
t = tab.make_page(format="pdf", with_html_headers=False, REQUEST=REQUEST) t = tab.make_page(format="pdf", with_html_headers=False)
return t return t
def _one_header(self, ws): def _one_header(self, ws):
@ -459,15 +453,6 @@ class PlacementRunner:
), ),
} }
def _init_lines(self, maxlines):
return [
[] for _ in range(maxlines)
] # lines[no_ligne] -> liste des cellules de la ligne (no_lignes de 1..maxlines
def _write_lines(self, ws, lines):
for line in lines:
ws.append_row(line)
def _titres(self, ws): def _titres(self, ws):
dt = time.strftime("%d/%m/%Y a %Hh%M") dt = time.strftime("%d/%m/%Y a %Hh%M")
ws.append_single_cell_row( ws.append_single_cell_row(
@ -476,7 +461,7 @@ class PlacementRunner:
for line, desceval in enumerate(self.desceval): for line, desceval in enumerate(self.desceval):
if line in [1, 4, 7]: if line in [1, 4, 7]:
ws.append_blank_row() ws.append_blank_row()
ws.append_single_cell_row(desceval[0], self.styles["titres"]) ws.append_single_cell_row(desceval, self.styles["titres"])
ws.append_single_cell_row( ws.append_single_cell_row(
"Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s" "Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s"
% self.eval_data, % self.eval_data,
@ -517,7 +502,9 @@ class PlacementRunner:
ws0.append_row(cells_a) # on affiche les 3 lignes construites ws0.append_row(cells_a) # on affiche les 3 lignes construites
ws0.append_row(cells_b) ws0.append_row(cells_b)
ws0.append_row(cells_c) ws0.append_row(cells_c)
cells_a = [ws0.make_cell(rang, self.styles["2b"])] # on réinitialise les 3 lignes cells_a = [
ws0.make_cell(rang, self.styles["2b"])
] # on réinitialise les 3 lignes
cells_b = [ws0.make_cell("", self.styles["2b"])] cells_b = [ws0.make_cell("", self.styles["2b"])]
cells_c = [ws0.make_cell("", self.styles["2b"])] cells_c = [ws0.make_cell("", self.styles["2b"])]
col = 0 col = 0
@ -528,7 +515,7 @@ class PlacementRunner:
ws0.append_row(cells_c) ws0.append_row(cells_c)
ws0.set_row_dimension_height(row, space / 25) ws0.set_row_dimension_height(row, space / 25)
def _next_page(ws): def _next_page(self, ws):
pass pass
def _feuille1(self, ws, maxlines): def _feuille1(self, ws, maxlines):
@ -554,27 +541,28 @@ class PlacementRunner:
self._headers(ws, nb_listes) self._headers(ws, nb_listes)
# construction liste alphabétique # construction liste alphabétique
# Affichage # Affichage
lines = self._init_lines(maxlines) lines = [[] for _ in range(maxlines)]
line = 0 lineno = 0
col = 0 col = 0
for etud in sorted(self.plan, key=lambda e: e[0][0]): # tri alphabétique for etud in sorted(self.plan, key=lambda e: e[0][0]): # tri alphabétique
# check for skip of list or page # check for skip of list or page
if col > 0: # add a empty cell between lists if col > 0: # add a empty cell between lists
lines[line].append(ws.make_cell()) lines[lineno].append(ws.make_cell())
lines[line].append(ws.make_cell(etud[0][0], self.styles["2l"])) lines[lineno].append(ws.make_cell(etud[0][0], self.styles["2l"]))
lines[line].append(ws.make_cell(etud[0][1], self.styles["2m1"])) lines[lineno].append(ws.make_cell(etud[0][1], self.styles["2m1"]))
if self.etiquetage == COORD: if self.etiquetage == COORD:
lines[line].append(ws.make_cell(etud[1][1], self.styles["2m2"])) lines[lineno].append(ws.make_cell(etud[1][1], self.styles["2m2"]))
lines[line].append(ws.make_cell(etud[1][0], self.styles["2r"])) lines[lineno].append(ws.make_cell(etud[1][0], self.styles["2r"]))
else: else:
lines[line].append(ws.make_cell(etud[1], self.styles["2r"])) lines[lineno].append(ws.make_cell(etud[1], self.styles["2r"]))
line = line + 1 lineno = lineno + 1
if line >= maxlines: # fin de liste if lineno >= maxlines: # fin de liste
col = col + 1 col = col + 1
line = 0 lineno = 0
if col >= maxlistes: # fin de page if col >= maxlistes: # fin de page
self._write_lines(ws, lines) for line_cells in lines:
lines = self._init_lines(maxlines) ws.append_row(line_cells)
lines = [[] for _ in range(maxlines)]
col = 0 col = 0
ws.append_blank_row() ws.append_blank_row()
nb_etu_restant -= maxlistes * maxlines nb_etu_restant -= maxlistes * maxlines
@ -582,7 +570,8 @@ class PlacementRunner:
maxlistes, nb_etu_restant // maxlines + 1 maxlistes, nb_etu_restant // maxlines + 1
) # nombre de colonnes dans la page ) # nombre de colonnes dans la page
self._headers(ws, nb_listes) self._headers(ws, nb_listes)
self._write_lines(ws, lines) for line_cells in lines:
ws.append_row(line_cells)
def _excel_feuille_placement(self): def _excel_feuille_placement(self):
"""Genere feuille excel pour placement des etudiants. """Genere feuille excel pour placement des etudiants.
@ -610,7 +599,7 @@ class PlacementRunner:
ws0.set_column_dimension_width("A", 750 * column_width_ratio) ws0.set_column_dimension_width("A", 750 * column_width_ratio)
for col in range(nb_rangs): for col in range(nb_rangs):
ws0.set_column_dimension_width( ws0.set_column_dimension_width(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[col + 1 : col + 2], width "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[col + 1: col + 2], width
) )
SheetName1 = "Positions" SheetName1 = "Positions"