forked from ScoDoc/ScoDoc
before refactoring
This commit is contained in:
parent
ed07e42222
commit
7f63ab222b
@ -35,6 +35,7 @@ from enum import Enum
|
|||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
import openpyxl.utils.datetime
|
import openpyxl.utils.datetime
|
||||||
|
from flask import make_response
|
||||||
from openpyxl import Workbook, load_workbook
|
from openpyxl import Workbook, load_workbook
|
||||||
from openpyxl.cell import WriteOnlyCell
|
from openpyxl.cell import WriteOnlyCell
|
||||||
from openpyxl.styles import Font, Border, Side, Alignment, PatternFill
|
from openpyxl.styles import Font, Border, Side, Alignment, PatternFill
|
||||||
@ -64,14 +65,21 @@ class COLORS(Enum):
|
|||||||
LIGHT_YELLOW = "FFFFFF99"
|
LIGHT_YELLOW = "FFFFFF99"
|
||||||
|
|
||||||
|
|
||||||
|
def send_from_flask(data, filename, mime=scu.XLSX_MIMETYPE):
|
||||||
|
scu.make_filename(filename)
|
||||||
|
response = make_response(data)
|
||||||
|
response.headers['Content-Type'] = mime
|
||||||
|
response.headers['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
||||||
|
|
||||||
|
|
||||||
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.
|
||||||
(on ne doit rien avoir émis avant, car ici sont générés les entetes)
|
(on ne doit rien avoir émis avant, car ici sont générés les entetes)
|
||||||
"""
|
"""
|
||||||
filename = (
|
filename = (
|
||||||
scu.unescape_html(scu.suppress_accents(filename))
|
scu.unescape_html(scu.suppress_accents(filename))
|
||||||
.replace("&", "")
|
.replace("&", "")
|
||||||
.replace(" ", "_")
|
.replace(" ", "_")
|
||||||
)
|
)
|
||||||
request.RESPONSE.setHeader("content-type", mime)
|
request.RESPONSE.setHeader("content-type", mime)
|
||||||
request.RESPONSE.setHeader(
|
request.RESPONSE.setHeader(
|
||||||
@ -136,16 +144,16 @@ class ScoExcelBook:
|
|||||||
|
|
||||||
|
|
||||||
def excel_make_style(
|
def excel_make_style(
|
||||||
bold=False,
|
bold=False,
|
||||||
italic=False,
|
italic=False,
|
||||||
outline=False,
|
outline=False,
|
||||||
color: COLORS = COLORS.BLACK,
|
color: COLORS = COLORS.BLACK,
|
||||||
bgcolor: COLORS = None,
|
bgcolor: COLORS = None,
|
||||||
halign=None,
|
halign=None,
|
||||||
valign=None,
|
valign=None,
|
||||||
number_format=None,
|
number_format=None,
|
||||||
font_name="Arial",
|
font_name="Arial",
|
||||||
size=10,
|
size=10,
|
||||||
):
|
):
|
||||||
"""Contruit un style.
|
"""Contruit un style.
|
||||||
Les couleurs peuvent être spécfiées soit par une valeur de COLORS,
|
Les couleurs peuvent être spécfiées soit par une valeur de COLORS,
|
||||||
@ -228,12 +236,12 @@ class ScoExcelSheet:
|
|||||||
self.row_dimensions = {}
|
self.row_dimensions = {}
|
||||||
|
|
||||||
def excel_make_composite_style(
|
def excel_make_composite_style(
|
||||||
self,
|
self,
|
||||||
alignment=None,
|
alignment=None,
|
||||||
border=None,
|
border=None,
|
||||||
fill=None,
|
fill=None,
|
||||||
number_format=None,
|
number_format=None,
|
||||||
font=None,
|
font=None,
|
||||||
):
|
):
|
||||||
style = {}
|
style = {}
|
||||||
if font is not None:
|
if font is not None:
|
||||||
@ -374,7 +382,7 @@ class ScoExcelSheet:
|
|||||||
|
|
||||||
|
|
||||||
def excel_simple_table(
|
def excel_simple_table(
|
||||||
titles=None, lines=None, sheet_name=b"feuille", titles_styles=None, comments=None
|
titles=None, lines=None, sheet_name=b"feuille", titles_styles=None, comments=None
|
||||||
):
|
):
|
||||||
"""Export simple type 'CSV': 1ere ligne en gras, le reste tel quel"""
|
"""Export simple type 'CSV': 1ere ligne en gras, le reste tel quel"""
|
||||||
ws = ScoExcelSheet(sheet_name)
|
ws = ScoExcelSheet(sheet_name)
|
||||||
@ -643,13 +651,13 @@ def _excel_to_list(filelike): # we may need 'encoding' argument ?
|
|||||||
|
|
||||||
|
|
||||||
def excel_feuille_listeappel(
|
def excel_feuille_listeappel(
|
||||||
sem,
|
sem,
|
||||||
groupname,
|
groupname,
|
||||||
lines,
|
lines,
|
||||||
partitions=None,
|
partitions=None,
|
||||||
with_codes=False,
|
with_codes=False,
|
||||||
with_paiement=False,
|
with_paiement=False,
|
||||||
server_name=None,
|
server_name=None,
|
||||||
):
|
):
|
||||||
"""generation feuille appel"""
|
"""generation feuille appel"""
|
||||||
if partitions is None:
|
if partitions is None:
|
||||||
@ -751,7 +759,7 @@ def excel_feuille_listeappel(
|
|||||||
for t in lines:
|
for t in lines:
|
||||||
n += 1
|
n += 1
|
||||||
nomprenom = (
|
nomprenom = (
|
||||||
t["civilite_str"] + " " + t["nom"] + " " + t["prenom"].lower().capitalize()
|
t["civilite_str"] + " " + t["nom"] + " " + t["prenom"].lower().capitalize()
|
||||||
)
|
)
|
||||||
style_nom = style2t3
|
style_nom = style2t3
|
||||||
if with_paiement:
|
if with_paiement:
|
||||||
|
@ -35,9 +35,8 @@ import random
|
|||||||
import time
|
import time
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
|
||||||
import flask
|
|
||||||
import wtforms.validators
|
import wtforms.validators
|
||||||
from flask import request, render_template
|
from flask import request, render_template, url_for
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from werkzeug import Response
|
from werkzeug import Response
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
@ -141,273 +140,7 @@ class PlacementForm(FlaskForm):
|
|||||||
self.groups.choices = choices
|
self.groups.choices = choices
|
||||||
|
|
||||||
|
|
||||||
def placement_eval_selectetuds(evaluation_id):
|
class _DistributeurContinu:
|
||||||
"""Creation de l'écran de placement"""
|
|
||||||
form = PlacementForm(
|
|
||||||
request.form,
|
|
||||||
data={"evaluation_id": int(evaluation_id), "groups": PlacementForm.TOUS},
|
|
||||||
)
|
|
||||||
form.set_evaluation_infos(evaluation_id)
|
|
||||||
if form.validate_on_submit():
|
|
||||||
exec_placement(form) # calcul et generation du fichier
|
|
||||||
return flask.redirect(titi())
|
|
||||||
H = [html_sco_header.sco_header(init_jquery_ui=True)]
|
|
||||||
H.append(sco_evaluations.evaluation_describe(evaluation_id=evaluation_id))
|
|
||||||
H.append("<h3>Placement et émargement des étudiants</h3>")
|
|
||||||
H.append(render_template("forms/placement.html", form=form))
|
|
||||||
F = html_sco_header.sco_footer()
|
|
||||||
return "\n".join(H) + "<p>" + F
|
|
||||||
|
|
||||||
|
|
||||||
# def do_placement_selectetuds():
|
|
||||||
# """
|
|
||||||
# Choisi les étudiants et les infos sur la salle pour leur placement.
|
|
||||||
# """
|
|
||||||
# # M = sco_moduleimpl.do_moduleimpl_list( moduleimpl_id=E["moduleimpl_id"])[0]
|
|
||||||
# # description de l'evaluation
|
|
||||||
# H = [
|
|
||||||
# sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),
|
|
||||||
# "<h3>Placement et émargement des étudiants</h3>",
|
|
||||||
# ]
|
|
||||||
# #
|
|
||||||
# descr = [
|
|
||||||
# ("evaluation_id", {"default": evaluation_id, "input_type": "hidden"}),
|
|
||||||
# (
|
|
||||||
# "placement_method",
|
|
||||||
# {
|
|
||||||
# "input_type": "radio",
|
|
||||||
# "default": "xls",
|
|
||||||
# "allow_null": False,
|
|
||||||
# "allowed_values": ["pdf", "xls"],
|
|
||||||
# "labels": ["fichier pdf", "fichier xls"],
|
|
||||||
# "title": "Format de fichier :",
|
|
||||||
# },
|
|
||||||
# ),
|
|
||||||
# ("teachers", {"size": 25, "title": "Surveillants :"}),
|
|
||||||
# ("building", {"size": 25, "title": "Batiment :"}),
|
|
||||||
# ("room", {"size": 10, "title": "Salle :"}),
|
|
||||||
# (
|
|
||||||
# "columns",
|
|
||||||
# {
|
|
||||||
# "input_type": "radio",
|
|
||||||
# "default": "5",
|
|
||||||
# "allow_null": False,
|
|
||||||
# "allowed_values": ["3", "4", "5", "6", "7", "8"],
|
|
||||||
# "labels": [
|
|
||||||
# "3 colonnes",
|
|
||||||
# "4 colonnes",
|
|
||||||
# "5 colonnes",
|
|
||||||
# "6 colonnes",
|
|
||||||
# "7 colonnes",
|
|
||||||
# "8 colonnes",
|
|
||||||
# ],
|
|
||||||
# "title": "Nombre de colonnes :",
|
|
||||||
# },
|
|
||||||
# ),
|
|
||||||
# (
|
|
||||||
# "numbering",
|
|
||||||
# {
|
|
||||||
# "input_type": "radio",
|
|
||||||
# "default": "coordinate",
|
|
||||||
# "allow_null": False,
|
|
||||||
# "allowed_values": ["continuous", "coordinate"],
|
|
||||||
# "labels": ["continue", "coordonnées"],
|
|
||||||
# "title": "Numérotation :",
|
|
||||||
# },
|
|
||||||
# ),
|
|
||||||
# ]
|
|
||||||
# if no_groups:
|
|
||||||
# submitbuttonattributes = []
|
|
||||||
# descr += [
|
|
||||||
# (
|
|
||||||
# "group_ids",
|
|
||||||
# {
|
|
||||||
# "default": [
|
|
||||||
# g["group_id"] # pylint: disable=invalid-sequence-index
|
|
||||||
# for g in groups
|
|
||||||
# ],
|
|
||||||
# "input_type": "hidden",
|
|
||||||
# "type": "list",
|
|
||||||
# },
|
|
||||||
# )
|
|
||||||
# ]
|
|
||||||
# else:
|
|
||||||
# descr += [
|
|
||||||
# (
|
|
||||||
# "group_ids",
|
|
||||||
# {
|
|
||||||
# "input_type": "checkbox",
|
|
||||||
# "title": "Choix groupe(s) d'étudiants :",
|
|
||||||
# "allowed_values": grnams,
|
|
||||||
# "labels": grlabs,
|
|
||||||
# "attributes": ['onchange="gr_change(this);"'],
|
|
||||||
# },
|
|
||||||
# )
|
|
||||||
# ]
|
|
||||||
#
|
|
||||||
# if not ("group_ids" in REQUEST.form and REQUEST.form["group_ids"]):
|
|
||||||
# submitbuttonattributes = ['disabled="1"']
|
|
||||||
# else:
|
|
||||||
# submitbuttonattributes = [] # groupe(s) preselectionnés
|
|
||||||
# H.append(
|
|
||||||
# # JS pour desactiver le bouton OK si aucun groupe selectionné
|
|
||||||
# """<script type="text/javascript">
|
|
||||||
# function gr_change(e) {
|
|
||||||
# var boxes = document.getElementsByName("group_ids:list");
|
|
||||||
# var nbchecked = 0;
|
|
||||||
# for (var i=0; i < boxes.length; i++) {
|
|
||||||
# if (boxes[i].checked)
|
|
||||||
# nbchecked++;
|
|
||||||
# }
|
|
||||||
# if (nbchecked > 0) {
|
|
||||||
# document.getElementsByName('gr_submit')[0].disabled=false;
|
|
||||||
# } else {
|
|
||||||
# document.getElementsByName('gr_submit')[0].disabled=true;
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# </script>
|
|
||||||
# """
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# tf = TrivialFormulator(
|
|
||||||
# REQUEST.URL0,
|
|
||||||
# REQUEST.form,
|
|
||||||
# descr,
|
|
||||||
# cancelbutton="Annuler",
|
|
||||||
# submitbuttonattributes=submitbuttonattributes,
|
|
||||||
# submitlabel="OK",
|
|
||||||
# formid="gr",
|
|
||||||
# )
|
|
||||||
# if tf[0] == 0:
|
|
||||||
# # H.append( """<div class="saisienote_etape1">
|
|
||||||
# # <span class="titredivplacementetudiants">Choix du groupe et de la localisation</span>
|
|
||||||
# # """)
|
|
||||||
# H.append("""<div class="saisienote_etape1">""")
|
|
||||||
# return "\n".join(H) + "\n" + tf[1] + "\n</div>"
|
|
||||||
# elif tf[0] == -1:
|
|
||||||
# return flask.redirect(
|
|
||||||
# "%s/Notes/moduleimpl_status?moduleimpl_id=%s"
|
|
||||||
# % (scu.ScoURL(), E["moduleimpl_id"])
|
|
||||||
# )
|
|
||||||
# else:
|
|
||||||
# placement_method = tf[2]["placement_method"]
|
|
||||||
# teachers = tf[2]["teachers"]
|
|
||||||
# building = tf[2]["building"]
|
|
||||||
# room = tf[2]["room"]
|
|
||||||
# group_ids = tf[2]["group_ids"]
|
|
||||||
# columns = tf[2]["columns"]
|
|
||||||
# numbering = tf[2]["numbering"]
|
|
||||||
# if columns in ("3", "4", "5", "6", "7", "8"):
|
|
||||||
# gs = [
|
|
||||||
# ("group_ids%3Alist=" + six.moves.urllib.parse.quote_plus(x))
|
|
||||||
# for x in group_ids
|
|
||||||
# ]
|
|
||||||
# query = (
|
|
||||||
# "evaluation_id=%s&placement_method=%s&teachers=%s&building=%s&room=%s&columns=%s&numbering=%s&"
|
|
||||||
# % (
|
|
||||||
# evaluation_id,
|
|
||||||
# placement_method,
|
|
||||||
# teachers,
|
|
||||||
# building,
|
|
||||||
# room,
|
|
||||||
# columns,
|
|
||||||
# numbering,
|
|
||||||
# )
|
|
||||||
# + "&".join(gs)
|
|
||||||
# )
|
|
||||||
# return flask.redirect(scu.NotesURL() + "/do_placement?" + query)
|
|
||||||
# else:
|
|
||||||
# raise ValueError(
|
|
||||||
# "invalid placement_method (%s)" % tf[2]["placement_method"]
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
def exec_placement(form):
|
|
||||||
"""Calcul et génération du fichier sur la base des données du formulaire"""
|
|
||||||
d = {
|
|
||||||
"evaluation_id": form["evaluation_id"].data,
|
|
||||||
"etiquetage": form["etiquetage"].data,
|
|
||||||
"surveillants": form["surveillants"].data,
|
|
||||||
"batiment": form["batiment"].data,
|
|
||||||
"salle": form["salle"].data,
|
|
||||||
"nb_rangs": form["nb_rangs"].data,
|
|
||||||
"groups": form["groups"].data,
|
|
||||||
}
|
|
||||||
breakpoint()
|
|
||||||
d["eval_data"] = sco_evaluations.do_evaluation_list(d)[0]
|
|
||||||
# Check access (admin, respformation, and responsable_id)
|
|
||||||
d["current_user"] = current_user
|
|
||||||
d["moduleimpl_id"] = d["eval_data"]["moduleimpl_id"]
|
|
||||||
if not sco_permissions_check.can_edit_notes(d["current_user"], d["moduleimpl_id"]):
|
|
||||||
return (
|
|
||||||
"""<h2>Génération du placement impossible pour %(current_user)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=%(module_id)s">Continuer</a></p>
|
|
||||||
"""
|
|
||||||
% d
|
|
||||||
)
|
|
||||||
d["cnx"] = ndb.GetDBConnexion()
|
|
||||||
d["plan"] = repartition(d)
|
|
||||||
d["gr_title_filename"] = sco_groups.listgroups_filename(d['groups'])
|
|
||||||
# gr_title = sco_groups.listgroups_abbrev(d['groups'])
|
|
||||||
d["moduleimpl_data"] = sco_moduleimpl.do_moduleimpl_list(moduleimpl_id=d["moduleimpl_id"])
|
|
||||||
d["Mod"] = sco_edit_module.do_module_list(args={"module_id": d["moduleimpl_id"]})[0]
|
|
||||||
d["sem"] = sco_formsemestre.get_formsemestre(d["moduleimpl_data"]["formsemestre_id"])
|
|
||||||
d["evalname"] = "%s-%s" % (d["Mod"]["code"], ndb.DateDMYtoISO(eval_data["jour"]))
|
|
||||||
if d["eval_data"]["description"]:
|
|
||||||
d["evaltitre"] = d["eval_data"]["description"]
|
|
||||||
else:
|
|
||||||
d["evaltitre"] = "évaluation du %s" % eval_data["jour"]
|
|
||||||
d["desceval"] = [
|
|
||||||
["%s" % d["sem"]["titreannee"]],
|
|
||||||
["Module : %s - %s" % (d["Mod"]["code"], d["Mod"]["abbrev"])],
|
|
||||||
["Surveillants : %(surveillant)s" % d],
|
|
||||||
["Batiment : %(batiment)s - Salle : %(salle)s" % d],
|
|
||||||
["Controle : %s (coef. %g)" % (d["evaltitre"], d["eval_data"]["coefficient"])],
|
|
||||||
] # une liste de liste de chaines: description de l'evaluation
|
|
||||||
if form["file_format"].data == "xls":
|
|
||||||
production_xls(d)
|
|
||||||
else:
|
|
||||||
production_pdf(d)
|
|
||||||
|
|
||||||
|
|
||||||
def repartition(d):
|
|
||||||
"""
|
|
||||||
Calcule le placement. retourne une liste de couples ((nom, prenom), position)
|
|
||||||
"""
|
|
||||||
# Construit liste des etudiants
|
|
||||||
groups = sco_groups.listgroups(d["groups"])
|
|
||||||
d["listetud"] = build_listetud(d)
|
|
||||||
return affectation_places(d)
|
|
||||||
|
|
||||||
|
|
||||||
def build_listetud(cnx, groups, evaluation_id, moduleimpl_data):
|
|
||||||
if None in [g["group_name"] for g in groups]: # tous les etudiants
|
|
||||||
getallstudents = True
|
|
||||||
gr_title_filename = "tous"
|
|
||||||
else:
|
|
||||||
getallstudents = False
|
|
||||||
etudids = sco_groups.do_evaluation_listeetuds_groups(
|
|
||||||
evaluation_id, groups, getallstudents=getallstudents, include_dems=True
|
|
||||||
)
|
|
||||||
listetud = [] # liste de couples (nom,prenom)
|
|
||||||
for etudid in etudids:
|
|
||||||
# infos identite etudiant (xxx sous-optimal: 1/select par etudiant)
|
|
||||||
ident = sco_etud.etudident_list(cnx, {"etudid": etudid})[0]
|
|
||||||
# infos inscription
|
|
||||||
inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
|
|
||||||
{"etudid": etudid, "formsemestre_id": moduleimpl_data["formsemestre_id"]}
|
|
||||||
)[0]
|
|
||||||
if inscr["etat"] != "D":
|
|
||||||
nom = ident["nom"].upper()
|
|
||||||
prenom = ident["prenom"].lower().capitalize()
|
|
||||||
listetud.append((nom, prenom))
|
|
||||||
random.shuffle(listetud)
|
|
||||||
return listetud
|
|
||||||
|
|
||||||
|
|
||||||
class DistributeurContinu:
|
|
||||||
"""Distribue les places selon un ordre numérique."""
|
"""Distribue les places selon un ordre numérique."""
|
||||||
|
|
||||||
def __init(self):
|
def __init(self):
|
||||||
@ -419,7 +152,7 @@ class DistributeurContinu:
|
|||||||
return retour
|
return retour
|
||||||
|
|
||||||
|
|
||||||
class Distributeur2D:
|
class _Distributeur2D:
|
||||||
"""Distribue les places selon des coordonnées sur nb_rangs."""
|
"""Distribue les places selon des coordonnées sur nb_rangs."""
|
||||||
|
|
||||||
def __init__(self, nb_rangs):
|
def __init__(self, nb_rangs):
|
||||||
@ -436,19 +169,140 @@ class Distributeur2D:
|
|||||||
return retour
|
return retour
|
||||||
|
|
||||||
|
|
||||||
def affectation_places(d):
|
def placement_eval_selectetuds(evaluation_id):
|
||||||
|
"""Creation de l'écran de placement"""
|
||||||
|
form = PlacementForm(
|
||||||
|
request.form,
|
||||||
|
data={"evaluation_id": int(evaluation_id), "groups": PlacementForm.TOUS},
|
||||||
|
)
|
||||||
|
form.set_evaluation_infos(evaluation_id)
|
||||||
|
if form.validate_on_submit():
|
||||||
|
return _exec_placement(form) # 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("<h3>Placement et émargement des étudiants</h3>")
|
||||||
|
H.append(render_template("forms/placement.html", form=form))
|
||||||
|
F = html_sco_header.sco_footer()
|
||||||
|
return "\n".join(H) + "<p>" + F
|
||||||
|
|
||||||
|
|
||||||
|
def _exec_placement(form):
|
||||||
|
"""Calcul et génération du fichier sur la base des données du formulaire"""
|
||||||
|
d = {
|
||||||
|
"evaluation_id": form["evaluation_id"].data,
|
||||||
|
"etiquetage": form["etiquetage"].data,
|
||||||
|
"surveillants": form["surveillants"].data,
|
||||||
|
"batiment": form["batiment"].data,
|
||||||
|
"salle": form["salle"].data,
|
||||||
|
"nb_rangs": form["nb_rangs"].data,
|
||||||
|
"groups_ids": form["groups"].data,
|
||||||
|
}
|
||||||
|
d["eval_data"] = sco_evaluations.do_evaluation_list(
|
||||||
|
{"evaluation_id": d["evaluation_id"]}
|
||||||
|
)[0]
|
||||||
|
# Check access (admin, respformation, and responsable_id)
|
||||||
|
d["current_user"] = current_user
|
||||||
|
d["moduleimpl_id"] = d["eval_data"]["moduleimpl_id"]
|
||||||
|
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'])
|
||||||
|
d["moduleimpl_data"] = sco_moduleimpl.do_moduleimpl_list(
|
||||||
|
moduleimpl_id=d["moduleimpl_id"]
|
||||||
|
)[0]
|
||||||
|
d["Mod"] = sco_edit_module.do_module_list(
|
||||||
|
args={"module_id": d["moduleimpl_data"]["module_id"]}
|
||||||
|
)[0]
|
||||||
|
d["sem"] = sco_formsemestre.get_formsemestre(
|
||||||
|
d["moduleimpl_data"]["formsemestre_id"]
|
||||||
|
)
|
||||||
|
d["evalname"] = "%s-%s" % (
|
||||||
|
d["Mod"]["code"],
|
||||||
|
ndb.DateDMYtoISO(d["eval_data"]["jour"]),
|
||||||
|
)
|
||||||
|
if d["eval_data"]["description"]:
|
||||||
|
d["evaltitre"] = d["eval_data"]["description"]
|
||||||
|
else:
|
||||||
|
d["evaltitre"] = "évaluation du %s" % d["eval_data"]["jour"]
|
||||||
|
d["desceval"] = [
|
||||||
|
["%s" % d["sem"]["titreannee"]],
|
||||||
|
["Module : %s - %s" % (d["Mod"]["code"], d["Mod"]["abbrev"])],
|
||||||
|
["Surveillants : %(surveillants)s" % d],
|
||||||
|
["Batiment : %(batiment)s - Salle : %(salle)s" % d],
|
||||||
|
["Controle : %s (coef. %g)" % (d["evaltitre"], d["eval_data"]["coefficient"])],
|
||||||
|
] # une liste de liste de chaines: description de l'evaluation
|
||||||
|
d["plan"] = _repartition(d)
|
||||||
|
if form["file_format"].data == "xls":
|
||||||
|
return _production_xls(d)
|
||||||
|
else:
|
||||||
|
return _production_pdf(d)
|
||||||
|
|
||||||
|
|
||||||
|
def _repartition(d):
|
||||||
|
"""
|
||||||
|
Calcule le placement. retourne une liste de couples ((nom, prenom), position)
|
||||||
|
"""
|
||||||
|
# Construit liste des etudiants
|
||||||
|
d["groups"] = sco_groups.listgroups(d["groups_ids"])
|
||||||
|
d["listetud"] = _build_listetud(d)
|
||||||
|
return _affectation_places(d)
|
||||||
|
|
||||||
|
|
||||||
|
def _build_listetud(d):
|
||||||
|
if None in [g["group_name"] for g in d["groups"]]: # tous les etudiants
|
||||||
|
getallstudents = True
|
||||||
|
gr_title_filename = "tous"
|
||||||
|
else:
|
||||||
|
getallstudents = False
|
||||||
|
etudids = sco_groups.do_evaluation_listeetuds_groups(
|
||||||
|
d["evaluation_id"],
|
||||||
|
d["groups"],
|
||||||
|
getallstudents=getallstudents,
|
||||||
|
include_dems=True,
|
||||||
|
)
|
||||||
|
listetud = [] # liste de couples (nom,prenom)
|
||||||
|
for etudid in etudids:
|
||||||
|
# infos identite etudiant (xxx sous-optimal: 1/select par etudiant)
|
||||||
|
ident = sco_etud.etudident_list(d["cnx"], {"etudid": etudid})[0]
|
||||||
|
# infos inscription
|
||||||
|
inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
|
||||||
|
{
|
||||||
|
"etudid": etudid,
|
||||||
|
"formsemestre_id": d["moduleimpl_data"]["formsemestre_id"],
|
||||||
|
}
|
||||||
|
)[0]
|
||||||
|
if inscr["etat"] != "D":
|
||||||
|
nom = ident["nom"].upper()
|
||||||
|
prenom = ident["prenom"].lower().capitalize()
|
||||||
|
listetud.append((nom, prenom))
|
||||||
|
random.shuffle(listetud)
|
||||||
|
return listetud
|
||||||
|
|
||||||
|
|
||||||
|
def _affectation_places(d):
|
||||||
plan = []
|
plan = []
|
||||||
if d["etiquetage"] == "continu":
|
if d["etiquetage"] == "continu":
|
||||||
distributeur = DistributeurContinu()
|
distributeur = _DistributeurContinu()
|
||||||
else:
|
else:
|
||||||
distributeur = Distributeur2D(d["nb_rangs"])
|
distributeur = _Distributeur2D(d["nb_rangs"])
|
||||||
for etud in d["listetud"]:
|
for etud in d["listetud"]:
|
||||||
plan.append((etud, distributeur.suivant()))
|
plan.append((etud, distributeur.suivant()))
|
||||||
return plan
|
return plan
|
||||||
|
|
||||||
|
|
||||||
def production_xls(d):
|
def _production_xls(d):
|
||||||
filename = f"placement_{evalname}_{gr_title_filename}{scu.XLSX_SUFFIX}"
|
breakpoint()
|
||||||
|
filename = scu.make_filename("placement_%(evalname)s_%(gr_title_filename)s{scu.XLSX_SUFFIX}" % d)
|
||||||
xls = _excel_feuille_placement(
|
xls = _excel_feuille_placement(
|
||||||
d["eval_data"],
|
d["eval_data"],
|
||||||
d["desceval"],
|
d["desceval"],
|
||||||
@ -458,13 +312,13 @@ def production_xls(d):
|
|||||||
d["salle"],
|
d["salle"],
|
||||||
d["etiquetage"],
|
d["etiquetage"],
|
||||||
)
|
)
|
||||||
return sco_excel.send_excel_file(REQUEST, xls, filename)
|
return sco_excel.send_from_flask(xls, filename)
|
||||||
|
|
||||||
|
|
||||||
def production_pdf(d):
|
def _production_pdf(d):
|
||||||
pdf_title = d["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" % d["eval_data"]
|
||||||
)
|
)
|
||||||
|
|
||||||
filename = "placement_%(evalname)s_%(gr_title_filename)s.pdf" % d
|
filename = "placement_%(evalname)s_%(gr_title_filename)s.pdf" % d
|
||||||
@ -517,8 +371,8 @@ def production_pdf(d):
|
|||||||
rows=rows,
|
rows=rows,
|
||||||
filename=filename,
|
filename=filename,
|
||||||
origin="Généré par %s le " % sco_version.SCONAME
|
origin="Généré par %s le " % sco_version.SCONAME
|
||||||
+ scu.timedate_human_repr()
|
+ scu.timedate_human_repr()
|
||||||
+ "",
|
+ "",
|
||||||
pdf_title=pdf_title,
|
pdf_title=pdf_title,
|
||||||
# pdf_shorttitle = '',
|
# pdf_shorttitle = '',
|
||||||
preferences=sco_preferences.SemPreferences(M["formsemestre_id"]),
|
preferences=sco_preferences.SemPreferences(M["formsemestre_id"]),
|
||||||
@ -528,42 +382,6 @@ def production_pdf(d):
|
|||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
||||||
def placement_eval_selectetuds_old(evaluation_id, REQUEST=None):
|
|
||||||
"""Dialogue placement etudiants: choix methode et localisation"""
|
|
||||||
evals = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})
|
|
||||||
if not evals:
|
|
||||||
raise ScoValueError("invalid evaluation_id")
|
|
||||||
theeval = evals[0]
|
|
||||||
|
|
||||||
if theeval["description"]:
|
|
||||||
page_title = 'Placement "%s"' % theeval["description"]
|
|
||||||
else:
|
|
||||||
page_title = "Placement des étudiants"
|
|
||||||
H = [html_sco_header.sco_header(page_title=page_title)]
|
|
||||||
|
|
||||||
formid = "placementfile"
|
|
||||||
if not REQUEST.form.get("%s-submitted" % formid, False):
|
|
||||||
# not submitted, choix groupe
|
|
||||||
r = do_placement_selectetuds()
|
|
||||||
if r:
|
|
||||||
if isinstance(r, str):
|
|
||||||
H.append(r)
|
|
||||||
elif isinstance(r, Response):
|
|
||||||
H.append(r.get_data().decode("utf-8"))
|
|
||||||
H.append(
|
|
||||||
"""<h3>Explications</h3> <ul> <li>Choisir le format du fichier résultat :</li> <ul> <li>le format pdf
|
|
||||||
consiste en un tableau précisant pour chaque étudiant la localisation de sa table;</li> <li>le format xls
|
|
||||||
produit un classeur avec deux onglets</li> <ul> <li>le premier onglet donne une vue de la salle avec la
|
|
||||||
localisation des étudiants et peut servir de feuille d'émargement;</li> <li>le second onglet est un tableau
|
|
||||||
similaire à celui du fichier pdf;</li> </ul> </ul> <li>préciser les surveillants et la localisation (bâtiment
|
|
||||||
et salle) et indiquer le nombre de colonnes;</li> <li>deux types de placements sont possibles :</li> <ul>
|
|
||||||
<li>continue suppose que les tables ont toutes un numéro unique;</li> <li>coordonnées localise chaque table
|
|
||||||
via un numéro de colonne et un numéro de ligne (ou rangée).</li> </ul> </ul> """
|
|
||||||
)
|
|
||||||
H.append(html_sco_header.sco_footer())
|
|
||||||
return "\n".join(H)
|
|
||||||
|
|
||||||
|
|
||||||
def _one_header(ws, numbering, styles):
|
def _one_header(ws, numbering, styles):
|
||||||
cells = []
|
cells = []
|
||||||
if numbering == "coordinate":
|
if numbering == "coordinate":
|
||||||
@ -691,16 +509,16 @@ def _titres(ws, description, evaluation, building, room, styles):
|
|||||||
|
|
||||||
|
|
||||||
def _feuille0(
|
def _feuille0(
|
||||||
ws0,
|
ws0,
|
||||||
description,
|
description,
|
||||||
evaluation,
|
evaluation,
|
||||||
styles,
|
styles,
|
||||||
numbering,
|
numbering,
|
||||||
listetud,
|
listetud,
|
||||||
nbcolumns,
|
nbcolumns,
|
||||||
building,
|
building,
|
||||||
room,
|
room,
|
||||||
space,
|
space,
|
||||||
):
|
):
|
||||||
_titres(ws0, description, evaluation, building, room, styles)
|
_titres(ws0, description, evaluation, building, room, styles)
|
||||||
# entetes colonnes - feuille0
|
# entetes colonnes - feuille0
|
||||||
@ -788,16 +606,16 @@ def _next_page(ws):
|
|||||||
|
|
||||||
|
|
||||||
def _feuille1(
|
def _feuille1(
|
||||||
ws,
|
ws,
|
||||||
description,
|
description,
|
||||||
evaluation,
|
evaluation,
|
||||||
styles,
|
styles,
|
||||||
numbering,
|
numbering,
|
||||||
maxlines,
|
maxlines,
|
||||||
nbcolumns,
|
nbcolumns,
|
||||||
building,
|
building,
|
||||||
room,
|
room,
|
||||||
listetud,
|
listetud,
|
||||||
):
|
):
|
||||||
# etudiants - feuille1
|
# etudiants - feuille1
|
||||||
# structuration:
|
# structuration:
|
||||||
@ -854,15 +672,13 @@ def _feuille1(
|
|||||||
|
|
||||||
|
|
||||||
def _excel_feuille_placement(
|
def _excel_feuille_placement(
|
||||||
evaluation,
|
evaluation,
|
||||||
description,
|
description,
|
||||||
listetud,
|
listetud,
|
||||||
columns,
|
columns,
|
||||||
space,
|
building,
|
||||||
maxlines,
|
room,
|
||||||
building,
|
numbering,
|
||||||
room,
|
|
||||||
numbering,
|
|
||||||
):
|
):
|
||||||
"""Genere feuille excel pour placement des etudiants.
|
"""Genere feuille excel pour placement des etudiants.
|
||||||
E: evaluation (dict)
|
E: evaluation (dict)
|
||||||
@ -887,7 +703,7 @@ def _excel_feuille_placement(
|
|||||||
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(nbcolumns):
|
||||||
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"
|
||||||
|
Loading…
Reference in New Issue
Block a user