forked from ScoDoc/ScoDoc
excel file returned
This commit is contained in:
parent
7f63ab222b
commit
c8872bd220
@ -70,7 +70,7 @@ def send_from_flask(data, filename, mime=scu.XLSX_MIMETYPE):
|
|||||||
response = make_response(data)
|
response = make_response(data)
|
||||||
response.headers['Content-Type'] = mime
|
response.headers['Content-Type'] = mime
|
||||||
response.headers['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
response.headers['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
||||||
|
return response
|
||||||
|
|
||||||
def send_excel_file(request, data, filename, mime=scu.XLSX_MIMETYPE):
|
def send_excel_file(request, data, filename, mime=scu.XLSX_MIMETYPE):
|
||||||
"""publication fichier.
|
"""publication fichier.
|
||||||
|
@ -76,6 +76,9 @@ from app.scodoc.TrivialFormulator import TrivialFormulator
|
|||||||
_ = lambda x: x # sans babel
|
_ = lambda x: x # sans babel
|
||||||
_l = _
|
_l = _
|
||||||
|
|
||||||
|
COORD = "Coordonnées"
|
||||||
|
SEQ = "Continue"
|
||||||
|
|
||||||
|
|
||||||
class PlacementForm(FlaskForm):
|
class PlacementForm(FlaskForm):
|
||||||
TOUS = "Tous"
|
TOUS = "Tous"
|
||||||
@ -87,9 +90,7 @@ class PlacementForm(FlaskForm):
|
|||||||
wtforms.validators.DataRequired("indiquez le format du fichier attendu"),
|
wtforms.validators.DataRequired("indiquez le format du fichier attendu"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
surveillants = StringField(
|
surveillants = StringField("Surveillants", validators=[])
|
||||||
"Surveillants", validators=[wtforms.validators.DataRequired("Test")]
|
|
||||||
)
|
|
||||||
batiment = StringField("Batiment")
|
batiment = StringField("Batiment")
|
||||||
salle = StringField("Salle")
|
salle = StringField("Salle")
|
||||||
nb_rangs = SelectField(
|
nb_rangs = SelectField(
|
||||||
@ -97,7 +98,7 @@ class PlacementForm(FlaskForm):
|
|||||||
)
|
)
|
||||||
etiquetage = RadioField(
|
etiquetage = RadioField(
|
||||||
"Numérotation",
|
"Numérotation",
|
||||||
choices=["Continue", "Coordonnées"],
|
choices=[SEQ, COORD],
|
||||||
validators=[
|
validators=[
|
||||||
wtforms.validators.DataRequired("indiquez le style de numérotation"),
|
wtforms.validators.DataRequired("indiquez le style de numérotation"),
|
||||||
],
|
],
|
||||||
@ -177,7 +178,17 @@ def placement_eval_selectetuds(evaluation_id):
|
|||||||
)
|
)
|
||||||
form.set_evaluation_infos(evaluation_id)
|
form.set_evaluation_infos(evaluation_id)
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
return _exec_placement(form) # calcul et generation du fichier
|
runner = PlacementRunner(form)
|
||||||
|
if not runner.check_placement():
|
||||||
|
return (
|
||||||
|
"""<h2>Génération du placement impossible pour %s</h2>
|
||||||
|
<p>(vérifiez que le semestre n'est pas verrouillé et que vous
|
||||||
|
avez l'autorisation d'effectuer cette opération)</p>
|
||||||
|
<p><a href="moduleimpl_status?moduleimpl_id=%s">Continuer</a></p>
|
||||||
|
"""
|
||||||
|
% runner.__dict__
|
||||||
|
)
|
||||||
|
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)]
|
H = [html_sco_header.sco_header(init_jquery_ui=True)]
|
||||||
H.append(sco_evaluations.evaluation_describe(evaluation_id=evaluation_id))
|
H.append(sco_evaluations.evaluation_describe(evaluation_id=evaluation_id))
|
||||||
@ -187,141 +198,133 @@ def placement_eval_selectetuds(evaluation_id):
|
|||||||
return "\n".join(H) + "<p>" + F
|
return "\n".join(H) + "<p>" + F
|
||||||
|
|
||||||
|
|
||||||
def _exec_placement(form):
|
class PlacementRunner:
|
||||||
|
def __init__(self, form):
|
||||||
"""Calcul et génération du fichier sur la base des données du formulaire"""
|
"""Calcul et génération du fichier sur la base des données du formulaire"""
|
||||||
d = {
|
self.evaluation_id = form["evaluation_id"].data
|
||||||
"evaluation_id": form["evaluation_id"].data,
|
self.etiquetage = form["etiquetage"].data
|
||||||
"etiquetage": form["etiquetage"].data,
|
self.surveillants = form["surveillants"].data
|
||||||
"surveillants": form["surveillants"].data,
|
self.batiment = form["batiment"].data
|
||||||
"batiment": form["batiment"].data,
|
self.salle = form["salle"].data
|
||||||
"salle": form["salle"].data,
|
self.nb_rangs = form["nb_rangs"].data
|
||||||
"nb_rangs": form["nb_rangs"].data,
|
self.file_format = form["file_format"].data
|
||||||
"groups_ids": form["groups"].data,
|
self.groups_ids = form["groups"].data
|
||||||
}
|
self.eval_data = sco_evaluations.do_evaluation_list(
|
||||||
d["eval_data"] = sco_evaluations.do_evaluation_list(
|
{"evaluation_id": self.evaluation_id}
|
||||||
{"evaluation_id": d["evaluation_id"]}
|
|
||||||
)[0]
|
)[0]
|
||||||
# Check access (admin, respformation, and responsable_id)
|
self.cnx = ndb.GetDBConnexion()
|
||||||
d["current_user"] = current_user
|
self.groups = sco_groups.listgroups(self.groups_ids)
|
||||||
d["moduleimpl_id"] = d["eval_data"]["moduleimpl_id"]
|
self.gr_title_filename = sco_groups.listgroups_filename(self.groups)
|
||||||
if not sco_permissions_check.can_edit_notes(d["current_user"], d["moduleimpl_id"]):
|
|
||||||
return """<h2>Génération du placement impossible pour %s</h2>
|
|
||||||
<p>(vérifiez que le semestre n'est pas verrouillé et que vous
|
|
||||||
avez l'autorisation d'effectuer cette opération)</p>
|
|
||||||
<p><a href="moduleimpl_status?moduleimpl_id=%s">Continuer</a></p>
|
|
||||||
""" % (
|
|
||||||
d["current_user"].user_name,
|
|
||||||
d["module_id"],
|
|
||||||
)
|
|
||||||
d["cnx"] = ndb.GetDBConnexion()
|
|
||||||
d["groups"] = sco_groups.listgroups(d["groups_ids"])
|
|
||||||
d["gr_title_filename"] = sco_groups.listgroups_filename(d["groups"])
|
|
||||||
# gr_title = sco_groups.listgroups_abbrev(d['groups'])
|
# gr_title = sco_groups.listgroups_abbrev(d['groups'])
|
||||||
d["moduleimpl_data"] = sco_moduleimpl.do_moduleimpl_list(
|
self.current_user = current_user
|
||||||
moduleimpl_id=d["moduleimpl_id"]
|
self.moduleimpl_id = self.eval_data["moduleimpl_id"]
|
||||||
|
self.moduleimpl_data = sco_moduleimpl.do_moduleimpl_list(
|
||||||
|
moduleimpl_id=self.moduleimpl_id
|
||||||
)[0]
|
)[0]
|
||||||
d["Mod"] = sco_edit_module.do_module_list(
|
self.Mod = sco_edit_module.do_module_list(
|
||||||
args={"module_id": d["moduleimpl_data"]["module_id"]}
|
args={"module_id": self.moduleimpl_data["module_id"]}
|
||||||
)[0]
|
)[0]
|
||||||
d["sem"] = sco_formsemestre.get_formsemestre(
|
self.sem = sco_formsemestre.get_formsemestre(
|
||||||
d["moduleimpl_data"]["formsemestre_id"]
|
self.moduleimpl_data["formsemestre_id"]
|
||||||
)
|
)
|
||||||
d["evalname"] = "%s-%s" % (
|
self.evalname = "%s-%s" % (
|
||||||
d["Mod"]["code"],
|
self.Mod["code"],
|
||||||
ndb.DateDMYtoISO(d["eval_data"]["jour"]),
|
ndb.DateDMYtoISO(self.eval_data["jour"]),
|
||||||
)
|
)
|
||||||
if d["eval_data"]["description"]:
|
if self.eval_data["description"]:
|
||||||
d["evaltitre"] = d["eval_data"]["description"]
|
self.evaltitre = self.eval_data["description"]
|
||||||
else:
|
else:
|
||||||
d["evaltitre"] = "évaluation du %s" % d["eval_data"]["jour"]
|
self.evaltitre = "évaluation du %s" % self.eval_data["jour"]
|
||||||
d["desceval"] = [
|
self.desceval = [
|
||||||
["%s" % d["sem"]["titreannee"]],
|
["%s" % self.sem["titreannee"]],
|
||||||
["Module : %s - %s" % (d["Mod"]["code"], d["Mod"]["abbrev"])],
|
["Module : %s - %s" % (self.Mod["code"], self.Mod["abbrev"])],
|
||||||
["Surveillants : %(surveillants)s" % d],
|
["Surveillants : %s" % self.surveillants],
|
||||||
["Batiment : %(batiment)s - Salle : %(salle)s" % d],
|
["Batiment : %(batiment)s - Salle : %(salle)s" % self.__dict__],
|
||||||
["Controle : %s (coef. %g)" % (d["evaltitre"], d["eval_data"]["coefficient"])],
|
[
|
||||||
|
"Controle : %s (coef. %g)"
|
||||||
|
% (self.evaltitre, self.eval_data["coefficient"])
|
||||||
|
],
|
||||||
] # une liste de liste de chaines: description de l'evaluation
|
] # une liste de liste de chaines: description de l'evaluation
|
||||||
d["plan"] = _repartition(d)
|
|
||||||
if form["file_format"].data == "xls":
|
def check_placement(self):
|
||||||
return _production_xls(d)
|
# Check access (admin, respformation, and responsable_id)
|
||||||
|
return sco_permissions_check.can_edit_notes(
|
||||||
|
self.current_user, self.moduleimpl_id
|
||||||
|
)
|
||||||
|
|
||||||
|
def _exec_placement(self):
|
||||||
|
self._repartition()
|
||||||
|
if self.file_format == "xls":
|
||||||
|
return self._production_xls()
|
||||||
else:
|
else:
|
||||||
return _production_pdf(d)
|
return self._production_pdf()
|
||||||
|
|
||||||
|
def _repartition(self):
|
||||||
def _repartition(d):
|
|
||||||
"""
|
"""
|
||||||
Calcule le placement. retourne une liste de couples ((nom, prenom), position)
|
Calcule le placement. retourne une liste de couples ((nom, prenom), position)
|
||||||
"""
|
"""
|
||||||
# Construit liste des etudiants
|
# Construit liste des etudiants et les réparti
|
||||||
d["groups"] = sco_groups.listgroups(d["groups_ids"])
|
self.groups = sco_groups.listgroups(self.groups_ids)
|
||||||
d["listetud"] = _build_listetud(d)
|
self.listetud = self._build_listetud()
|
||||||
return _affectation_places(d)
|
self.plan = self._affectation_places()
|
||||||
|
|
||||||
|
def _build_listetud(self):
|
||||||
def _build_listetud(d):
|
if None in [g["group_name"] for g in self.groups]: # tous les etudiants
|
||||||
if None in [g["group_name"] for g in d["groups"]]: # tous les etudiants
|
|
||||||
getallstudents = True
|
getallstudents = True
|
||||||
gr_title_filename = "tous"
|
gr_title_filename = "tous"
|
||||||
else:
|
else:
|
||||||
getallstudents = False
|
getallstudents = False
|
||||||
etudids = sco_groups.do_evaluation_listeetuds_groups(
|
etudids = sco_groups.do_evaluation_listeetuds_groups(
|
||||||
d["evaluation_id"],
|
self.evaluation_id,
|
||||||
d["groups"],
|
self.groups,
|
||||||
getallstudents=getallstudents,
|
getallstudents=getallstudents,
|
||||||
include_dems=True,
|
include_dems=True,
|
||||||
)
|
)
|
||||||
listetud = [] # liste de couples (nom,prenom)
|
listetud = [] # liste de couples (nom,prenom)
|
||||||
for etudid in etudids:
|
for etudid in etudids:
|
||||||
# infos identite etudiant (xxx sous-optimal: 1/select par etudiant)
|
# infos identite etudiant (xxx sous-optimal: 1/select par etudiant)
|
||||||
ident = sco_etud.etudident_list(d["cnx"], {"etudid": etudid})[0]
|
ident = sco_etud.etudident_list(self.cnx, {"etudid": etudid})[0]
|
||||||
# infos inscription
|
# infos inscription
|
||||||
inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
|
inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
|
||||||
{
|
{
|
||||||
"etudid": etudid,
|
"etudid": etudid,
|
||||||
"formsemestre_id": d["moduleimpl_data"]["formsemestre_id"],
|
"formsemestre_id": self.moduleimpl_data["formsemestre_id"],
|
||||||
}
|
}
|
||||||
)[0]
|
)[0]
|
||||||
if inscr["etat"] != "D":
|
if inscr["etat"] != "D":
|
||||||
nom = ident["nom"].upper()
|
nom = ident["nom"].upper()
|
||||||
prenom = ident["prenom"].lower().capitalize()
|
prenom = ident["prenom"].lower().capitalize()
|
||||||
listetud.append((nom, prenom))
|
etudid = ident["etudid"]
|
||||||
|
listetud.append((nom, prenom, etudid))
|
||||||
random.shuffle(listetud)
|
random.shuffle(listetud)
|
||||||
return listetud
|
return listetud
|
||||||
|
|
||||||
|
def _affectation_places(self):
|
||||||
def _affectation_places(d):
|
|
||||||
plan = []
|
plan = []
|
||||||
if d["etiquetage"] == "continu":
|
if self.etiquetage == SEQ:
|
||||||
distributeur = _DistributeurContinu()
|
distributeur = _DistributeurContinu()
|
||||||
else:
|
else:
|
||||||
distributeur = _Distributeur2D(d["nb_rangs"])
|
distributeur = _Distributeur2D(self.nb_rangs)
|
||||||
for etud in d["listetud"]:
|
for etud in self.listetud:
|
||||||
plan.append((etud, distributeur.suivant()))
|
plan.append((etud, distributeur.suivant()))
|
||||||
return plan
|
return plan
|
||||||
|
|
||||||
|
def _production_xls(self):
|
||||||
def _production_xls(d):
|
filename = scu.make_filename(
|
||||||
breakpoint()
|
"placement_%s_%s%s"
|
||||||
filename = scu.make_filename("placement_%(evalname)s_%(gr_title_filename)s{scu.XLSX_SUFFIX}" % d)
|
% (self.evalname, self.gr_title_filename, scu.XLSX_SUFFIX)
|
||||||
xls = _excel_feuille_placement(
|
|
||||||
d["eval_data"],
|
|
||||||
d["desceval"],
|
|
||||||
d["listetud"],
|
|
||||||
d["nb_rangs"],
|
|
||||||
d["batiment"],
|
|
||||||
d["salle"],
|
|
||||||
d["etiquetage"],
|
|
||||||
)
|
)
|
||||||
|
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(d):
|
pdf_title = self.desceval
|
||||||
pdf_title = d["desceval"]
|
|
||||||
pdf_title += (
|
pdf_title += (
|
||||||
"Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s" % d["eval_data"]
|
"Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s"
|
||||||
|
% self.eval_data
|
||||||
)
|
)
|
||||||
|
|
||||||
filename = "placement_%(evalname)s_%(gr_title_filename)s.pdf" % d
|
filename = "placement_%(evalname)s_%(gr_title_filename)s.pdf" % self
|
||||||
titles = {
|
titles = {
|
||||||
"nom": "Nom",
|
"nom": "Nom",
|
||||||
"prenom": "Prenom",
|
"prenom": "Prenom",
|
||||||
@ -329,41 +332,25 @@ def _production_pdf(d):
|
|||||||
"ligne": "Ligne",
|
"ligne": "Ligne",
|
||||||
"place": "Place",
|
"place": "Place",
|
||||||
}
|
}
|
||||||
nbcolumns = int(columns)
|
nb_rangs = int(self.nb_rangs)
|
||||||
if numbering == "coordinate":
|
if self.etiquetage == COORD:
|
||||||
columns_ids = ["nom", "prenom", "colonne", "ligne"]
|
columns_ids = ["nom", "prenom", "colonne", "ligne"]
|
||||||
else:
|
else:
|
||||||
columns_ids = ["nom", "prenom", "place"]
|
columns_ids = ["nom", "prenom", "place"]
|
||||||
|
|
||||||
# etudiants
|
|
||||||
line = 1
|
|
||||||
col = 1
|
|
||||||
orderetud = []
|
|
||||||
for etudid in listetud:
|
|
||||||
if numbering == "coordinate":
|
|
||||||
orderetud.append((etudid[0], etudid[1], col, line))
|
|
||||||
else:
|
|
||||||
orderetud.append((etudid[0], etudid[1], col + (line - 1) * nbcolumns))
|
|
||||||
|
|
||||||
if col == nbcolumns:
|
|
||||||
col = 0
|
|
||||||
line += 1
|
|
||||||
col += 1
|
|
||||||
|
|
||||||
rows = []
|
rows = []
|
||||||
orderetud.sort()
|
for etud in sorted(plan, key=lambda etud: etud[0][0]): # sort by name
|
||||||
for etudid in orderetud:
|
if self.etiquetage == COORD:
|
||||||
if numbering == "coordinate":
|
|
||||||
rows.append(
|
rows.append(
|
||||||
{
|
{
|
||||||
"nom": etudid[0],
|
"nom": etud[0][0],
|
||||||
"prenom": etudid[1],
|
"prenom": etud[0][1],
|
||||||
"colonne": etudid[2],
|
"colonne": etud[1][0],
|
||||||
"ligne": etudid[3],
|
"ligne": etud[1][1],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
rows.append({"nom": etudid[0], "prenom": etudid[1], "place": etudid[2]})
|
rows.append({"nom": etud[0][0], "prenom": etud[0][1], "place": etud[1]})
|
||||||
|
|
||||||
tab = GenTable(
|
tab = GenTable(
|
||||||
titles=titles,
|
titles=titles,
|
||||||
@ -381,30 +368,26 @@ def _production_pdf(d):
|
|||||||
t = tab.make_page(format="pdf", with_html_headers=False, REQUEST=REQUEST)
|
t = tab.make_page(format="pdf", with_html_headers=False, REQUEST=REQUEST)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
def _one_header(self, ws):
|
||||||
def _one_header(ws, numbering, styles):
|
cells = [
|
||||||
cells = []
|
ws.make_cell("Nom", self.styles["2bi"]),
|
||||||
if numbering == "coordinate":
|
ws.make_cell("Prénom", self.styles["2bi"]),
|
||||||
cells.append(ws.make_cell("Nom", styles["2bi"]))
|
]
|
||||||
cells.append(ws.make_cell("Prénom", styles["2bi"]))
|
if self.etiquetage == COORD:
|
||||||
cells.append(ws.make_cell("Colonne", styles["2bi"]))
|
cells.append(ws.make_cell("Colonne", self.styles["2bi"]))
|
||||||
cells.append(ws.make_cell("Ligne", styles["2bi"]))
|
cells.append(ws.make_cell("Ligne", self.styles["2bi"]))
|
||||||
else:
|
else:
|
||||||
cells.append(ws.make_cell("Nom", styles["2bi"]))
|
cells.append(ws.make_cell("Place", self.styles["2bi"]))
|
||||||
cells.append(ws.make_cell("Prénom", styles["2bi"]))
|
|
||||||
cells.append(ws.make_cell("Place", styles["2bi"]))
|
|
||||||
return cells
|
return cells
|
||||||
|
|
||||||
|
def _headers(self, ws, nb_listes):
|
||||||
def _headers(ws, numbering, styles, nb_listes):
|
|
||||||
cells = []
|
cells = []
|
||||||
for _ in range(nb_listes):
|
for _ in range(nb_listes):
|
||||||
cells += _one_header(ws, numbering, styles)
|
cells += self._one_header(ws)
|
||||||
cells.append(ws.make_cell(""))
|
cells.append(ws.make_cell(""))
|
||||||
ws.append_row(cells)
|
ws.append_row(cells)
|
||||||
|
|
||||||
|
def _make_styles(self, ws0, ws1):
|
||||||
def _make_styles(ws0, ws1):
|
|
||||||
# polices
|
# polices
|
||||||
font0 = Font(name="Calibri", bold=True, size=12)
|
font0 = Font(name="Calibri", bold=True, size=12)
|
||||||
font1b = copy(font0)
|
font1b = copy(font0)
|
||||||
@ -426,7 +409,9 @@ def _make_styles(ws0, ws1):
|
|||||||
border2m = Border(top=side_thin, bottom=side_thin)
|
border2m = Border(top=side_thin, bottom=side_thin)
|
||||||
border2r = Border(top=side_thin, bottom=side_thin, right=side_thin)
|
border2r = Border(top=side_thin, bottom=side_thin, right=side_thin)
|
||||||
border2l = Border(left=side_thin, top=side_thin, bottom=side_thin)
|
border2l = Border(left=side_thin, top=side_thin, bottom=side_thin)
|
||||||
border2b = Border(left=side_thin, top=side_thin, bottom=side_thin, right=side_thin)
|
border2b = Border(
|
||||||
|
left=side_thin, top=side_thin, bottom=side_thin, right=side_thin
|
||||||
|
)
|
||||||
|
|
||||||
# alignements
|
# alignements
|
||||||
align_center_center = Alignment(horizontal="center", vertical="center")
|
align_center_center = Alignment(horizontal="center", vertical="center")
|
||||||
@ -440,7 +425,7 @@ def _make_styles(ws0, ws1):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# styles
|
# styles
|
||||||
styles = {
|
self.styles = {
|
||||||
"titres": sco_excel.excel_make_style(font_name="Arial", bold=True, size=12),
|
"titres": sco_excel.excel_make_style(font_name="Arial", bold=True, size=12),
|
||||||
"1t": ws0.excel_make_composite_style(
|
"1t": ws0.excel_make_composite_style(
|
||||||
font=font0, alignment=align_center_center, border=border1t
|
font=font0, alignment=align_center_center, border=border1t
|
||||||
@ -458,7 +443,10 @@ def _make_styles(ws0, ws1):
|
|||||||
font=font1i, alignment=align_center_center, border=border2b
|
font=font1i, alignment=align_center_center, border=border2b
|
||||||
),
|
),
|
||||||
"2bi": ws1.excel_make_composite_style(
|
"2bi": ws1.excel_make_composite_style(
|
||||||
font=font2bi, alignment=align_center_center, border=border2b, fill=pattern
|
font=font2bi,
|
||||||
|
alignment=align_center_center,
|
||||||
|
border=border2b,
|
||||||
|
fill=pattern,
|
||||||
),
|
),
|
||||||
"2l": ws1.excel_make_composite_style(
|
"2l": ws1.excel_make_composite_style(
|
||||||
font=font2, alignment=align_left_center, border=border2l
|
font=font2, alignment=align_left_center, border=border2l
|
||||||
@ -473,157 +461,83 @@ def _make_styles(ws0, ws1):
|
|||||||
font=font2, alignment=align_right_center, border=border2r
|
font=font2, alignment=align_right_center, border=border2r
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
return styles
|
|
||||||
|
|
||||||
|
def _init_lines(self, maxlines):
|
||||||
def _init_lines(maxlines):
|
|
||||||
return [
|
return [
|
||||||
[] for _ in range(maxlines)
|
[] for _ in range(maxlines)
|
||||||
] # lines[no_ligne] -> liste des cellules de la ligne (no_lignes de 1..maxlines
|
] # lines[no_ligne] -> liste des cellules de la ligne (no_lignes de 1..maxlines
|
||||||
|
|
||||||
|
def _write_lines(self, ws, lines):
|
||||||
def _write_lines(ws, lines):
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
ws.append_row(line)
|
ws.append_row(line)
|
||||||
|
|
||||||
|
def _titres(self, ws):
|
||||||
def _titres(ws, description, evaluation, building, room, styles):
|
|
||||||
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(
|
||||||
"Feuille placement etudiants éditée le %s" % dt, styles["titres"]
|
"Feuille placement etudiants éditée le %s" % dt, self.styles["titres"]
|
||||||
)
|
)
|
||||||
for line, desceval in enumerate(description):
|
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], styles["titres"])
|
ws.append_single_cell_row(desceval[0], self.styles["titres"])
|
||||||
ws.append_single_cell_row(
|
ws.append_single_cell_row(
|
||||||
"Date : %s - Horaire : %s à %s"
|
"Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s"
|
||||||
% (evaluation["jour"], evaluation["heure_debut"], evaluation["heure_fin"]),
|
% self.eval_data,
|
||||||
styles["titres"],
|
self.styles["titres"],
|
||||||
)
|
|
||||||
ws.append_single_cell_row(
|
|
||||||
"Date : %s - Horaire : %s à %s"
|
|
||||||
% (evaluation["jour"], evaluation["heure_debut"], evaluation["heure_fin"]),
|
|
||||||
styles["titres"],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _feuille0(self, ws0, space):
|
||||||
def _feuille0(
|
self._titres(ws0)
|
||||||
ws0,
|
|
||||||
description,
|
|
||||||
evaluation,
|
|
||||||
styles,
|
|
||||||
numbering,
|
|
||||||
listetud,
|
|
||||||
nbcolumns,
|
|
||||||
building,
|
|
||||||
room,
|
|
||||||
space,
|
|
||||||
):
|
|
||||||
_titres(ws0, description, evaluation, building, room, styles)
|
|
||||||
# entetes colonnes - feuille0
|
# entetes colonnes - feuille0
|
||||||
cells = [ws0.make_cell()]
|
cells = [ws0.make_cell()]
|
||||||
for col in range(nbcolumns):
|
for col in range(self.nb_rangs):
|
||||||
cells.append(ws0.make_cell("colonne %s" % (col + 1), styles["2b"]))
|
cells.append(ws0.make_cell("colonne %s" % (col + 1), self.styles["2b"]))
|
||||||
ws0.append_row(cells)
|
ws0.append_row(cells)
|
||||||
# etudiants
|
|
||||||
line = 1
|
|
||||||
col = 1
|
|
||||||
linetud = []
|
|
||||||
orderetud = []
|
|
||||||
placementetud = []
|
|
||||||
for etudid in listetud:
|
|
||||||
linetud.append(etudid)
|
|
||||||
if numbering == "coordinate":
|
|
||||||
orderetud.append((etudid[0], etudid[1], col, line))
|
|
||||||
else:
|
|
||||||
orderetud.append((etudid[0], etudid[1], col + (line - 1) * nbcolumns))
|
|
||||||
|
|
||||||
if col == nbcolumns:
|
|
||||||
placementetud.append(linetud)
|
|
||||||
linetud = []
|
|
||||||
col = 0
|
|
||||||
line += 1
|
|
||||||
col += 1
|
|
||||||
if len(linetud) > 0:
|
|
||||||
placementetud.append(linetud)
|
|
||||||
|
|
||||||
# etudiants - feuille0
|
# etudiants - feuille0
|
||||||
place = 1
|
place = 1
|
||||||
for rang, linetud in enumerate(placementetud, start=1):
|
for rang, linetud in enumerate(self.plan, start=1):
|
||||||
# Chaque rang est affiché sur 3 lignes xlsx (notées A, B, C)
|
# Chaque rang est affiché sur 3 lignes xlsx (notées A, B, C)
|
||||||
# ligne A: le nom, ligne B: le prénom, ligne C: un espace ou la place
|
# ligne A: le nom, ligne B: le prénom, ligne C: un espace ou la place
|
||||||
cells_a = [ws0.make_cell(rang, styles["2b"])]
|
cells_a = [ws0.make_cell(rang, self.styles["2b"])]
|
||||||
cells_b = [ws0.make_cell("", styles["2b"])]
|
cells_b = [ws0.make_cell("", self.styles["2b"])]
|
||||||
cells_c = [ws0.make_cell("", styles["2b"])]
|
cells_c = [ws0.make_cell("", self.styles["2b"])]
|
||||||
row = 14 # premieère ligne de signature
|
row = 14 # premieère ligne de signature
|
||||||
for etudid in linetud:
|
for etudid in linetud:
|
||||||
cells_a.append(ws0.make_cell(etudid[0], styles["1t"]))
|
cells_a.append(ws0.make_cell(etudid[0], self.styles["1t"]))
|
||||||
cells_b.append(ws0.make_cell(etudid[1], styles["1m"]))
|
cells_b.append(ws0.make_cell(etudid[1], self.styles["1m"]))
|
||||||
if numbering == "coordinate":
|
if self.etiquetage == COORD:
|
||||||
cell_c = ws0.make_cell("", styles["1bb"])
|
cell_c = ws0.make_cell("", self.styles["1bb"])
|
||||||
else:
|
else:
|
||||||
cell_c = ws0.make_cell("place %s" % place, styles["1bb"])
|
cell_c = ws0.make_cell("place %s" % place, self.styles["1bb"])
|
||||||
cells_c.append(cell_c)
|
cells_c.append(cell_c)
|
||||||
ws0.set_row_dimension_height(row, space / 25)
|
ws0.set_row_dimension_height(row, space / 25)
|
||||||
row += 3
|
row += 3
|
||||||
place = place + 1
|
place = place + 1
|
||||||
if col == nbcolumns:
|
if col == self.nb_rangs:
|
||||||
ws0.append_row(cells_a)
|
ws0.append_row(cells_a)
|
||||||
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, styles["2b"])]
|
cells_a = [ws0.make_cell(rang, self.styles["2b"])]
|
||||||
cells_b = [ws0.make_cell("", styles["2b"])]
|
cells_b = [ws0.make_cell("", self.styles["2b"])]
|
||||||
cells_c = [ws0.make_cell("", styles["2b"])]
|
cells_c = [ws0.make_cell("", self.styles["2b"])]
|
||||||
# publication du rang final incomplet
|
# publication du rang final incomplet
|
||||||
ws0.append_row(cells_a)
|
ws0.append_row(cells_a)
|
||||||
ws0.append_row(cells_b)
|
ws0.append_row(cells_b)
|
||||||
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 _compute_ordretud(listetud, nbcolumns, numbering):
|
|
||||||
orderetud = []
|
|
||||||
line = 1
|
|
||||||
col = 1
|
|
||||||
for etudid in listetud:
|
|
||||||
if numbering == "coordinate":
|
|
||||||
orderetud.append((etudid[0], etudid[1], col, line))
|
|
||||||
else:
|
|
||||||
orderetud.append(
|
|
||||||
(etudid[0], etudid[1], "%s" % (col + (line - 1) * nbcolumns))
|
|
||||||
)
|
|
||||||
col += 1
|
|
||||||
if col > nbcolumns:
|
|
||||||
col = 1
|
|
||||||
line += 1
|
|
||||||
orderetud.sort()
|
|
||||||
return orderetud
|
|
||||||
|
|
||||||
|
|
||||||
def _next_page(ws):
|
def _next_page(ws):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def _feuille1(self, ws, maxlines):
|
||||||
def _feuille1(
|
|
||||||
ws,
|
|
||||||
description,
|
|
||||||
evaluation,
|
|
||||||
styles,
|
|
||||||
numbering,
|
|
||||||
maxlines,
|
|
||||||
nbcolumns,
|
|
||||||
building,
|
|
||||||
room,
|
|
||||||
listetud,
|
|
||||||
):
|
|
||||||
# etudiants - feuille1
|
# etudiants - feuille1
|
||||||
# structuration:
|
# structuration:
|
||||||
# 1 page = maxlistes listes
|
# 1 page = maxlistes listes
|
||||||
# 1 liste = 3 ou 4 colonnes(excel) (selon numbering) et (maximum maxlines) lignes
|
# 1 liste = 3 ou 4 colonnes(excel) (selon numbering) et (maximum maxlines) lignes
|
||||||
maxlistes = 2 # nombre de listes par page
|
maxlistes = 2 # nombre de listes par page
|
||||||
# computes excel columns widths
|
# computes excel columns widths
|
||||||
if numbering == "coordinate":
|
if self.etiquetage == COORD:
|
||||||
gabarit = [16, 18, 6, 6, 2]
|
gabarit = [16, 18, 6, 6, 2]
|
||||||
else:
|
else:
|
||||||
gabarit = [16, 18, 12, 2]
|
gabarit = [16, 18, 12, 2]
|
||||||
@ -631,65 +545,58 @@ def _feuille1(
|
|||||||
for _ in range(maxlistes):
|
for _ in range(maxlistes):
|
||||||
widths += gabarit
|
widths += gabarit
|
||||||
ws.set_column_dimension_width(value=widths)
|
ws.set_column_dimension_width(value=widths)
|
||||||
nb_etu_restant = len(listetud)
|
nb_etu_restant = len(self.listetud)
|
||||||
_titres(ws, description, evaluation, building, room, styles)
|
self._titres(ws)
|
||||||
nb_listes = min(
|
nb_listes = min(
|
||||||
maxlistes, nb_etu_restant // maxlines + 1
|
maxlistes, nb_etu_restant // maxlines + 1
|
||||||
) # nombre de colonnes dans la page
|
) # nombre de colonnes dans la page
|
||||||
_headers(ws, numbering, styles, nb_listes)
|
self._headers(ws, nb_listes)
|
||||||
# construction liste alphabétique
|
# construction liste alphabétique
|
||||||
# Affichage
|
# Affichage
|
||||||
lines = _init_lines(maxlines)
|
lines = self._init_lines(maxlines)
|
||||||
orderetud = _compute_ordretud(listetud, nbcolumns, numbering)
|
|
||||||
line = 0
|
line = 0
|
||||||
col = 0
|
col = 0
|
||||||
for etudid in orderetud:
|
for etud in sorted(self.plan, key=lambda etud: etud[0][0]):
|
||||||
# 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[line].append(ws.make_cell())
|
||||||
lines[line].append(ws.make_cell(etudid[0], styles["2l"]))
|
lines[line].append(ws.make_cell(etud[0][0], self.styles["2l"]))
|
||||||
lines[line].append(ws.make_cell(etudid[1], styles["2m1"]))
|
lines[line].append(ws.make_cell(etud[0][1], self.styles["2m1"]))
|
||||||
if numbering == "coordinate":
|
if self.etiquetage == COORD:
|
||||||
lines[line].append(ws.make_cell(etudid[2], styles["2m2"]))
|
lines[line].append(ws.make_cell(etud[1][0], self.styles["2m2"]))
|
||||||
lines[line].append(ws.make_cell(etudid[3], styles["2r"]))
|
lines[line].append(ws.make_cell(etud[1][1], self.styles["2r"]))
|
||||||
else:
|
else:
|
||||||
lines[line].append(ws.make_cell(etudid[2], styles["2r"]))
|
lines[line].append(ws.make_cell(etud[1], self.styles["2r"]))
|
||||||
line = line + 1
|
line = line + 1
|
||||||
if line >= maxlines: # fin de liste
|
if line >= maxlines: # fin de liste
|
||||||
col = col + 1
|
col = col + 1
|
||||||
line = 0
|
line = 0
|
||||||
if col >= maxlistes: # fin de page
|
if col >= maxlistes: # fin de page
|
||||||
_write_lines(ws, lines)
|
self._write_lines(ws, lines)
|
||||||
lines = _init_lines(maxlines)
|
lines = self._init_lines(maxlines)
|
||||||
col = 0
|
col = 0
|
||||||
ws.append_blank_row()
|
ws.append_blank_row()
|
||||||
nb_etu_restant -= maxlistes * maxlines
|
nb_etu_restant -= maxlistes * maxlines
|
||||||
nb_listes = min(
|
nb_listes = min(
|
||||||
maxlistes, nb_etu_restant // maxlines + 1
|
maxlistes, nb_etu_restant // maxlines + 1
|
||||||
) # nombre de colonnes dans la page
|
) # nombre de colonnes dans la page
|
||||||
_headers(ws, numbering, styles, nb_listes)
|
self._headers(ws, nb_listes)
|
||||||
_write_lines(ws, lines)
|
self._write_lines(ws, lines)
|
||||||
|
|
||||||
|
def _excel_feuille_placement(self):
|
||||||
def _excel_feuille_placement(
|
|
||||||
evaluation,
|
|
||||||
description,
|
|
||||||
listetud,
|
|
||||||
columns,
|
|
||||||
building,
|
|
||||||
room,
|
|
||||||
numbering,
|
|
||||||
):
|
|
||||||
"""Genere feuille excel pour placement des etudiants.
|
"""Genere feuille excel pour placement des etudiants.
|
||||||
E: evaluation (dict)
|
E: evaluation (dict)
|
||||||
lines: liste de tuples
|
lines: liste de tuples
|
||||||
(etudid, nom, prenom, etat, groupe, val, explanation)
|
(etudid, nom, prenom, etat, groupe, val, explanation)
|
||||||
"""
|
"""
|
||||||
|
breakpoint()
|
||||||
sem_preferences = sco_preferences.SemPreferences()
|
sem_preferences = sco_preferences.SemPreferences()
|
||||||
space = sem_preferences.get("feuille_placement_emargement")
|
space = sem_preferences.get("feuille_placement_emargement")
|
||||||
maxlines = sem_preferences.get("feuille_placement_positions")
|
maxlines = sem_preferences.get("feuille_placement_positions")
|
||||||
nbcolumns = int(columns)
|
nb_rangs = int(self.nb_rangs)
|
||||||
column_width_ratio = 1 / 250 # changement d unités entre pyExcelerator et openpyxl
|
column_width_ratio = (
|
||||||
|
1 / 250
|
||||||
|
) # changement d unités entre pyExcelerator et openpyxl
|
||||||
|
|
||||||
wb = ScoExcelBook()
|
wb = ScoExcelBook()
|
||||||
|
|
||||||
@ -697,11 +604,11 @@ def _excel_feuille_placement(
|
|||||||
ws0 = wb.create_sheet(SheetName0)
|
ws0 = wb.create_sheet(SheetName0)
|
||||||
# ajuste largeurs colonnes (unite inconnue, empirique)
|
# ajuste largeurs colonnes (unite inconnue, empirique)
|
||||||
width = 4500 * column_width_ratio
|
width = 4500 * column_width_ratio
|
||||||
if nbcolumns > 5:
|
if nb_rangs > 5:
|
||||||
width = 22500 * column_width_ratio // nbcolumns
|
width = 22500 * column_width_ratio // nb_rangs
|
||||||
|
|
||||||
ws0.set_column_dimension_width("A", 750 * column_width_ratio)
|
ws0.set_column_dimension_width("A", 750 * column_width_ratio)
|
||||||
for col in range(nbcolumns):
|
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
|
||||||
)
|
)
|
||||||
@ -709,29 +616,7 @@ def _excel_feuille_placement(
|
|||||||
SheetName1 = "Positions"
|
SheetName1 = "Positions"
|
||||||
ws1 = wb.create_sheet(SheetName1)
|
ws1 = wb.create_sheet(SheetName1)
|
||||||
|
|
||||||
styles = _make_styles(ws0, ws1)
|
self._make_styles(ws0, ws1)
|
||||||
_feuille0(
|
self._feuille0(ws0, space)
|
||||||
ws0,
|
self._feuille1(ws1, maxlines)
|
||||||
description,
|
|
||||||
evaluation,
|
|
||||||
styles,
|
|
||||||
numbering,
|
|
||||||
listetud,
|
|
||||||
nbcolumns,
|
|
||||||
building,
|
|
||||||
room,
|
|
||||||
space,
|
|
||||||
)
|
|
||||||
_feuille1(
|
|
||||||
ws1,
|
|
||||||
description,
|
|
||||||
evaluation,
|
|
||||||
styles,
|
|
||||||
numbering,
|
|
||||||
maxlines,
|
|
||||||
nbcolumns,
|
|
||||||
building,
|
|
||||||
room,
|
|
||||||
listetud,
|
|
||||||
)
|
|
||||||
return wb.generate()
|
return wb.generate()
|
||||||
|
Loading…
Reference in New Issue
Block a user