diff --git a/app/scodoc/sco_placement.py b/app/scodoc/sco_placement.py index 32f89437..acc888ee 100644 --- a/app/scodoc/sco_placement.py +++ b/app/scodoc/sco_placement.py @@ -30,57 +30,50 @@ 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 time from copy import copy import wtforms.validators -from flask import request, render_template, url_for +from flask import request, render_template from flask_login import current_user -from werkzeug import Response from flask_wtf import FlaskForm +from openpyxl.styles import PatternFill, Alignment, Border, Side, Font from wtforms import ( StringField, - PasswordField, - BooleanField, SubmitField, SelectField, RadioField, HiddenField, 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.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_evaluations 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_inscriptions from app.scodoc import sco_groups from app.scodoc import sco_moduleimpl from app.scodoc import sco_permissions_check -from app.scodoc import sco_preferences -from app.scodoc import sco_saisie_notes +from app.scodoc.gen_tables import GenTable from app.scodoc import sco_etud 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 -_l = _ +# _ = lambda x: x # sans babel +# _l = _ COORD = "Coordonnées" SEQ = "Continue" class PlacementForm(FlaskForm): + """Formulaire pour placement des étudiants en Salle""" + TOUS = "Tous" evaluation_id = HiddenField("evaluation_id") file_format = RadioField( @@ -112,10 +105,10 @@ class PlacementForm(FlaskForm): submit = SubmitField("OK") 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}) if not eval_data: raise ScoValueError("invalid evaluation_id") - eval_data = eval_data[0] # groupes groups = sco_groups.do_evaluation_listegroupes( evaluation_id, include_default=True @@ -123,7 +116,7 @@ class PlacementForm(FlaskForm): self.groups_tree = {} self.has_groups = False 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_name = group["group_name"] or self.TOUS if partition not in self.groups_tree: @@ -136,8 +129,8 @@ class PlacementForm(FlaskForm): choices = [] for partition in self.groups_tree: for groupe in self.groups_tree[partition]: - id = str(self.groups_tree[partition][groupe]) - choices.append((id, "%s (%s)" % (str(groupe), partition))) + groupe_id = str(self.groups_tree[partition][groupe]) + choices.append((groupe_id, "%s (%s)" % (str(groupe), partition))) self.groups.choices = choices @@ -188,14 +181,16 @@ def placement_eval_selectetuds(evaluation_id): """ % 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")) - H = [html_sco_header.sco_header(init_jquery_ui=True)] - H.append(sco_evaluations.evaluation_describe(evaluation_id=evaluation_id)) - H.append("
" + F + return "\n".join(htmls) + "
" + F
class PlacementRunner:
@@ -235,16 +230,14 @@ class PlacementRunner:
self.evaltitre = self.eval_data["description"]
else:
self.evaltitre = "évaluation du %s" % self.eval_data["jour"]
- self.desceval = [
- ["%s" % self.sem["titreannee"]],
- ["Module : %s - %s" % (self.Mod["code"], self.Mod["abbrev"])],
- ["Surveillants : %s" % self.surveillants],
- ["Batiment : %(batiment)s - Salle : %(salle)s" % self.__dict__],
- [
- "Controle : %s (coef. %g)"
- % (self.evaltitre, self.eval_data["coefficient"])
- ],
- ] # une liste de liste de chaines: description de l'evaluation
+ self.desceval = [ # une liste de chaines: description de l'evaluation
+ "%s" % self.sem["titreannee"],
+ "Module : %s - %s" % (self.Mod["code"], self.Mod["abbrev"]),
+ "Surveillants : %s" % self.surveillants,
+ "Batiment : %(batiment)s - Salle : %(salle)s" % self.__dict__,
+ "Controle : %s (coef. %g)"
+ % (self.evaltitre, self.eval_data["coefficient"]),
+ ]
def check_placement(self):
# Check access (admin, respformation, and responsable_id)
@@ -252,7 +245,7 @@ class PlacementRunner:
self.current_user, self.moduleimpl_id
)
- def _exec_placement(self):
+ def exec_placement(self):
self._repartition()
if self.file_format == "xls":
return self._production_xls()
@@ -271,7 +264,6 @@ class PlacementRunner:
def _build_listetud(self):
if None in [g["group_name"] for g in self.groups]: # tous les etudiants
getallstudents = True
- gr_title_filename = "tous"
else:
getallstudents = False
etudids = sco_groups.do_evaluation_listeetuds_groups(
@@ -310,18 +302,21 @@ class PlacementRunner:
return plan
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()
return sco_excel.send_from_flask(xls, filename)
def _production_pdf(self):
- pdf_title = self.desceval
+ pdf_title = "
".join(self.desceval)
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
)
- breakpoint()
- filename = "placement_%(evalname)s_%(gr_title_filename)s.pdf" % self.__dict__
+ filename = "placement_%(evalname)s_%(gr_title_filename)s" % self.__dict__
titles = {
"nom": "Nom",
"prenom": "Prenom",
@@ -329,7 +324,6 @@ class PlacementRunner:
"ligne": "Ligne",
"place": "Place",
}
- nb_rangs = int(self.nb_rangs)
if self.etiquetage == COORD:
columns_ids = ["nom", "prenom", "colonne", "ligne"]
else:
@@ -348,7 +342,6 @@ class PlacementRunner:
)
else:
rows.append({"nom": etud[0][0], "prenom": etud[0][1], "place": etud[1]})
-
tab = GenTable(
titles=titles,
columns_ids=columns_ids,
@@ -359,10 +352,11 @@ class PlacementRunner:
+ "",
pdf_title=pdf_title,
# pdf_shorttitle = '',
- preferences=sco_preferences.SemPreferences(self.moduleimpl_data["formsemestre_id"]),
- # html_generate_cells=False # la derniere ligne (moyennes) est incomplete
+ preferences=sco_preferences.SemPreferences(
+ 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
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):
dt = time.strftime("%d/%m/%Y a %Hh%M")
ws.append_single_cell_row(
@@ -476,7 +461,7 @@ class PlacementRunner:
for line, desceval in enumerate(self.desceval):
if line in [1, 4, 7]:
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(
"Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s"
% self.eval_data,
@@ -514,10 +499,12 @@ class PlacementRunner:
row += 3
col += 1
if col == self.nb_rangs: # On a fini la rangée courante
- 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_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_c = [ws0.make_cell("", self.styles["2b"])]
col = 0
@@ -528,7 +515,7 @@ class PlacementRunner:
ws0.append_row(cells_c)
ws0.set_row_dimension_height(row, space / 25)
- def _next_page(ws):
+ def _next_page(self, ws):
pass
def _feuille1(self, ws, maxlines):
@@ -554,27 +541,28 @@ class PlacementRunner:
self._headers(ws, nb_listes)
# construction liste alphabétique
# Affichage
- lines = self._init_lines(maxlines)
- line = 0
+ lines = [[] for _ in range(maxlines)]
+ lineno = 0
col = 0
for etud in sorted(self.plan, key=lambda e: e[0][0]): # tri alphabétique
# check for skip of list or page
if col > 0: # add a empty cell between lists
- lines[line].append(ws.make_cell())
- lines[line].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())
+ lines[lineno].append(ws.make_cell(etud[0][0], self.styles["2l"]))
+ lines[lineno].append(ws.make_cell(etud[0][1], self.styles["2m1"]))
if self.etiquetage == COORD:
- lines[line].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][1], self.styles["2m2"]))
+ lines[lineno].append(ws.make_cell(etud[1][0], self.styles["2r"]))
else:
- lines[line].append(ws.make_cell(etud[1], self.styles["2r"]))
- line = line + 1
- if line >= maxlines: # fin de liste
+ lines[lineno].append(ws.make_cell(etud[1], self.styles["2r"]))
+ lineno = lineno + 1
+ if lineno >= maxlines: # fin de liste
col = col + 1
- line = 0
+ lineno = 0
if col >= maxlistes: # fin de page
- self._write_lines(ws, lines)
- lines = self._init_lines(maxlines)
+ for line_cells in lines:
+ ws.append_row(line_cells)
+ lines = [[] for _ in range(maxlines)]
col = 0
ws.append_blank_row()
nb_etu_restant -= maxlistes * maxlines
@@ -582,7 +570,8 @@ class PlacementRunner:
maxlistes, nb_etu_restant // maxlines + 1
) # nombre de colonnes dans la page
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):
"""Genere feuille excel pour placement des etudiants.
@@ -610,7 +599,7 @@ class PlacementRunner:
ws0.set_column_dimension_width("A", 750 * column_width_ratio)
for col in range(nb_rangs):
ws0.set_column_dimension_width(
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[col + 1 : col + 2], width
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[col + 1: col + 2], width
)
SheetName1 = "Positions"