forked from ScoDoc/ScoDoc
481 lines
16 KiB
Python
481 lines
16 KiB
Python
# -*- mode: python -*-
|
|
# -*- coding: utf-8 -*-
|
|
|
|
##############################################################################
|
|
#
|
|
# Gestion scolarite IUT
|
|
#
|
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
#
|
|
# Emmanuel Viennet emmanuel.viennet@viennet.net
|
|
#
|
|
##############################################################################
|
|
|
|
"""Photos: trombinoscopes - Version IUT Tours
|
|
Code contribué par Jérôme Billoue, IUT de Tours, 2014
|
|
Modification Jérome Billoue,Vincent Grimaud, IUT de Tours, 2017
|
|
"""
|
|
|
|
import io
|
|
|
|
from reportlab.lib import colors
|
|
from reportlab.lib.colors import black
|
|
from reportlab.lib.pagesizes import A4, A3
|
|
from reportlab.lib import styles
|
|
from reportlab.lib.pagesizes import landscape
|
|
from reportlab.lib.units import cm
|
|
from reportlab.platypus import KeepInFrame, Paragraph, Table, TableStyle
|
|
from reportlab.platypus.doctemplate import BaseDocTemplate
|
|
|
|
from app.scodoc import sco_abs
|
|
from app.scodoc import sco_etud
|
|
from app.scodoc.sco_exceptions import ScoPDFFormatError
|
|
from app.scodoc import sco_groups
|
|
from app.scodoc import sco_groups_view
|
|
from app.scodoc import sco_preferences
|
|
from app.scodoc import sco_trombino
|
|
import app.scodoc.sco_utils as scu
|
|
from app.scodoc.sco_pdf import SU, ScoDocPageTemplate
|
|
|
|
# Paramétrage de l'aspect graphique:
|
|
PHOTOWIDTH = 2.8 * cm
|
|
COLWIDTH = 3.4 * cm
|
|
N_PER_ROW = 5
|
|
|
|
|
|
def pdf_trombino_tours(
|
|
group_ids=(), # liste des groupes à afficher
|
|
formsemestre_id=None, # utilisé si pas de groupes selectionné
|
|
):
|
|
"""Generation du trombinoscope en fichier PDF"""
|
|
# Informations sur les groupes à afficher:
|
|
groups_infos = sco_groups_view.DisplayedGroupsInfos(
|
|
group_ids, formsemestre_id=formsemestre_id
|
|
)
|
|
|
|
DeptName = sco_preferences.get_preference("DeptName")
|
|
DeptFullName = sco_preferences.get_preference("DeptFullName")
|
|
InstituteName = sco_preferences.get_preference("InstituteName")
|
|
# Generate PDF page
|
|
StyleSheet = styles.getSampleStyleSheet()
|
|
objects = []
|
|
T = Table(
|
|
[
|
|
[Paragraph(SU(InstituteName), StyleSheet["Heading3"])],
|
|
[
|
|
Paragraph(
|
|
SU("Département " + DeptFullName or "(?)"), StyleSheet["Heading3"]
|
|
)
|
|
],
|
|
[
|
|
Paragraph(
|
|
SU("Date ............ / ............ / ......................"),
|
|
StyleSheet["Normal"],
|
|
),
|
|
Paragraph(
|
|
SU(
|
|
"Module ......................................................."
|
|
),
|
|
StyleSheet["Normal"],
|
|
),
|
|
],
|
|
[
|
|
Paragraph(
|
|
SU("de ............h............ à ............h............ "),
|
|
StyleSheet["Normal"],
|
|
),
|
|
Paragraph(
|
|
SU("Enseignant ................................................."),
|
|
StyleSheet["Normal"],
|
|
),
|
|
],
|
|
[
|
|
Table(
|
|
[
|
|
[
|
|
"Séance notée :",
|
|
" ",
|
|
"DS ",
|
|
" ",
|
|
"TP Contrôle ",
|
|
" ",
|
|
"Autre cas (TD ou TP noté, QCM, etc...)",
|
|
]
|
|
],
|
|
style=TableStyle(
|
|
[
|
|
("ALIGN", (0, 0), (-1, -1), "LEFT"),
|
|
("BOX", (1, 0), (1, 0), 0.75, black),
|
|
("BOX", (3, 0), (3, 0), 0.75, black),
|
|
("BOX", (5, 0), (5, 0), 0.75, black),
|
|
]
|
|
),
|
|
)
|
|
],
|
|
],
|
|
colWidths=(COLWIDTH * N_PER_ROW) / 2,
|
|
style=TableStyle(
|
|
[
|
|
("ALIGN", (0, 0), (-1, -1), "LEFT"),
|
|
("SPAN", (0, 1), (1, 1)),
|
|
("SPAN", (0, 4), (1, 4)),
|
|
("BOTTOMPADDING", (0, -1), (-1, -1), 10),
|
|
("BOX", (0, 0), (-1, -1), 0.75, black),
|
|
]
|
|
),
|
|
)
|
|
|
|
objects.append(T)
|
|
|
|
groups = ""
|
|
|
|
for group_id in groups_infos.group_ids:
|
|
if group_id != "None":
|
|
members, _, group_tit, sem, _ = sco_groups.get_group_infos(
|
|
group_id, scu.INSCRIT
|
|
)
|
|
groups += " %s" % group_tit
|
|
L = []
|
|
currow = []
|
|
|
|
if sem["semestre_id"] != -1:
|
|
currow = [
|
|
Paragraph(
|
|
SU(
|
|
"<para align=center>Semestre %s</para>" % sem["semestre_id"]
|
|
),
|
|
StyleSheet["Normal"],
|
|
)
|
|
]
|
|
currow += [" "] * (N_PER_ROW - len(currow) - 1)
|
|
currow += [
|
|
Paragraph(
|
|
SU("<para align=center>%s</para>" % sem["anneescolaire"]),
|
|
StyleSheet["Normal"],
|
|
)
|
|
]
|
|
L.append(currow)
|
|
currow = [" "] * N_PER_ROW
|
|
L.append(currow)
|
|
|
|
currow = []
|
|
currow.append(
|
|
Paragraph(
|
|
SU("<para align=center><b>" + group_tit + "</b></para>"),
|
|
StyleSheet["Heading3"],
|
|
)
|
|
)
|
|
n = 1
|
|
for m in members:
|
|
img = sco_trombino._get_etud_platypus_image(m, image_width=PHOTOWIDTH)
|
|
etud_main_group = sco_groups.get_etud_main_group(
|
|
m["etudid"], sem["formsemestre_id"]
|
|
)
|
|
if group_id != etud_main_group["group_id"]:
|
|
text_group = " (" + etud_main_group["group_name"] + ")"
|
|
else:
|
|
text_group = ""
|
|
elem = Table(
|
|
[
|
|
[img],
|
|
[
|
|
Paragraph(
|
|
SU(
|
|
"<para align=center><font size=8>"
|
|
+ sco_etud.format_prenom(m["prenom"])
|
|
+ " "
|
|
+ sco_etud.format_nom(m["nom"])
|
|
+ text_group
|
|
+ "</font></para>"
|
|
),
|
|
StyleSheet["Normal"],
|
|
)
|
|
],
|
|
],
|
|
colWidths=[COLWIDTH],
|
|
style=TableStyle([("ALIGN", (0, 0), (-1, -1), "CENTER")]),
|
|
)
|
|
currow.append(elem)
|
|
if n == (N_PER_ROW - 1):
|
|
L.append(currow)
|
|
currow = []
|
|
n = (n + 1) % N_PER_ROW
|
|
if currow:
|
|
currow += [" "] * (N_PER_ROW - len(currow))
|
|
L.append(currow)
|
|
if not L:
|
|
T = Paragraph(SU("Aucune photo à exporter !"), StyleSheet["Normal"])
|
|
else:
|
|
T = Table(
|
|
L,
|
|
colWidths=[COLWIDTH] * N_PER_ROW,
|
|
style=TableStyle(
|
|
[
|
|
("LEFTPADDING", (0, 0), (-1, -1), 0),
|
|
("RIGHTPADDING", (0, 0), (-1, -1), 0),
|
|
("BOTTOMPADDING", (0, 0), (-1, -1), 0),
|
|
("TOPPADDING", (0, 1), (-1, -1), 0),
|
|
("TOPPADDING", (0, 0), (-1, 0), 10),
|
|
("LINEBELOW", (1, 0), (-2, 0), 0.75, black),
|
|
("VALIGN", (0, 0), (-1, 1), "MIDDLE"),
|
|
("VALIGN", (0, 2), (-1, -1), "TOP"),
|
|
("VALIGN", (0, 2), (0, 2), "MIDDLE"),
|
|
("SPAN", (0, 0), (0, 1)),
|
|
("SPAN", (-1, 0), (-1, 1)),
|
|
]
|
|
),
|
|
)
|
|
|
|
objects.append(T)
|
|
|
|
T = Table(
|
|
[
|
|
[
|
|
Paragraph(
|
|
SU(
|
|
"Nombre d'absents : ................. (Merci d'entourer les absents SVP)"
|
|
),
|
|
StyleSheet["Normal"],
|
|
)
|
|
]
|
|
],
|
|
colWidths=(COLWIDTH * N_PER_ROW),
|
|
style=TableStyle(
|
|
[
|
|
("ALIGN", (0, 0), (-1, -1), "CENTER"),
|
|
("BOTTOMPADDING", (0, -1), (-1, -1), 10),
|
|
("BOX", (0, 0), (-1, -1), 0.75, black),
|
|
]
|
|
),
|
|
)
|
|
|
|
objects.append(T)
|
|
|
|
# Réduit sur une page
|
|
objects = [KeepInFrame(0, 0, objects, mode="shrink")]
|
|
# Build document
|
|
report = io.BytesIO() # in-memory document, no disk file
|
|
filename = "trombino-%s-%s.pdf" % (DeptName, groups_infos.groups_filename)
|
|
document = BaseDocTemplate(report)
|
|
document.addPageTemplates(
|
|
ScoDocPageTemplate(
|
|
document,
|
|
preferences=sco_preferences.SemPreferences(),
|
|
)
|
|
)
|
|
try:
|
|
document.build(objects)
|
|
except (ValueError, KeyError) as exc:
|
|
raise ScoPDFFormatError(str(exc)) from exc
|
|
data = report.getvalue()
|
|
|
|
return scu.sendPDFFile(data, filename)
|
|
|
|
|
|
# Feuille d'absences en pdf avec photos:
|
|
|
|
|
|
def pdf_feuille_releve_absences(
|
|
group_ids=(), # liste des groupes à afficher
|
|
formsemestre_id=None, # utilisé si pas de groupes selectionné
|
|
):
|
|
"""Generation de la feuille d'absence en fichier PDF, avec photos"""
|
|
|
|
NB_CELL_AM = sco_preferences.get_preference("feuille_releve_abs_AM")
|
|
NB_CELL_PM = sco_preferences.get_preference("feuille_releve_abs_PM")
|
|
col_width = 0.85 * cm
|
|
if sco_preferences.get_preference("feuille_releve_abs_samedi"):
|
|
days = sco_abs.DAYNAMES[:6] # Lundi, ..., Samedi
|
|
else:
|
|
days = sco_abs.DAYNAMES[:5] # Lundi, ..., Vendredi
|
|
nb_days = len(days)
|
|
|
|
# Informations sur les groupes à afficher:
|
|
groups_infos = sco_groups_view.DisplayedGroupsInfos(
|
|
group_ids, formsemestre_id=formsemestre_id
|
|
)
|
|
|
|
DeptName = sco_preferences.get_preference("DeptName")
|
|
DeptFullName = sco_preferences.get_preference("DeptFullName")
|
|
InstituteName = sco_preferences.get_preference("InstituteName")
|
|
# Generate PDF page
|
|
StyleSheet = styles.getSampleStyleSheet()
|
|
objects = [
|
|
Table(
|
|
[
|
|
[
|
|
Paragraph(SU(InstituteName), StyleSheet["Heading3"]),
|
|
Paragraph(
|
|
SU(
|
|
"<para align=right>Semaine ..................................................................</para>"
|
|
),
|
|
StyleSheet["Normal"],
|
|
),
|
|
],
|
|
[
|
|
Paragraph(
|
|
SU("Département " + (DeptFullName or "(?)")),
|
|
StyleSheet["Heading3"],
|
|
),
|
|
"",
|
|
],
|
|
],
|
|
style=TableStyle(
|
|
[("SPAN", (0, 1), (1, 1)), ("BOTTOMPADDING", (0, -1), (-1, -1), 10)]
|
|
),
|
|
)
|
|
]
|
|
|
|
currow = [""] * (NB_CELL_AM + 1 + NB_CELL_PM + 1)
|
|
elem_day = Table(
|
|
[currow],
|
|
colWidths=([col_width] * (NB_CELL_AM + 1 + NB_CELL_PM + 1)),
|
|
style=TableStyle(
|
|
[
|
|
("GRID", (0, 0), (NB_CELL_AM - 1, 0), 0.25, black),
|
|
(
|
|
"GRID",
|
|
(NB_CELL_AM + 1, 0),
|
|
(NB_CELL_AM + NB_CELL_PM, 0),
|
|
0.25,
|
|
black,
|
|
),
|
|
]
|
|
),
|
|
)
|
|
W = []
|
|
currow = []
|
|
for n in range(nb_days):
|
|
currow.append(elem_day)
|
|
W.append(currow)
|
|
|
|
elem_week = Table(
|
|
W,
|
|
colWidths=([col_width * (NB_CELL_AM + 1 + NB_CELL_PM + 1)] * nb_days),
|
|
style=TableStyle(
|
|
[
|
|
("LEFTPADDING", (0, 0), (-1, -1), 0),
|
|
("RIGHTPADDING", (0, 0), (-1, -1), 0),
|
|
("BOTTOMPADDING", (0, 0), (-1, -1), 0),
|
|
("TOPPADDING", (0, 0), (-1, -1), 0),
|
|
]
|
|
),
|
|
)
|
|
currow = []
|
|
for n in range(nb_days):
|
|
currow += [Paragraph(SU("<b>" + days[n] + "</b>"), StyleSheet["Normal"])]
|
|
|
|
elem_day_name = Table(
|
|
[currow],
|
|
colWidths=([col_width * (NB_CELL_AM + 1 + NB_CELL_PM + 1)] * nb_days),
|
|
style=TableStyle(
|
|
[
|
|
("LEFTPADDING", (0, 0), (-1, -1), 0),
|
|
("RIGHTPADDING", (0, 0), (-1, -1), 0),
|
|
("BOTTOMPADDING", (0, 0), (-1, -1), 0),
|
|
("TOPPADDING", (0, 0), (-1, -1), 0),
|
|
]
|
|
),
|
|
)
|
|
|
|
for group_id in groups_infos.group_ids:
|
|
members, _, group_tit, _, _ = sco_groups.get_group_infos(group_id, scu.INSCRIT)
|
|
L = []
|
|
|
|
currow = [
|
|
Paragraph(SU("<b>Groupe " + group_tit + "</b>"), StyleSheet["Normal"])
|
|
]
|
|
currow.append(elem_day_name)
|
|
L.append(currow)
|
|
|
|
currow = [Paragraph(SU("Initiales enseignant :"), StyleSheet["Normal"])]
|
|
currow.append(elem_week)
|
|
L.append(currow)
|
|
|
|
currow = [Paragraph(SU("Initiales module :"), StyleSheet["Normal"])]
|
|
currow.append(elem_week)
|
|
L.append(currow)
|
|
|
|
for m in members:
|
|
currow = [
|
|
Paragraph(
|
|
SU(
|
|
sco_etud.format_nom(m["nom"])
|
|
+ " "
|
|
+ sco_etud.format_prenom(m["prenom"])
|
|
),
|
|
StyleSheet["Normal"],
|
|
)
|
|
]
|
|
currow.append(elem_week)
|
|
L.append(currow)
|
|
|
|
if not L:
|
|
T = Paragraph(SU("Aucun étudiant !"), StyleSheet["Normal"])
|
|
else:
|
|
T = Table(
|
|
L,
|
|
colWidths=(
|
|
[
|
|
5.0 * cm,
|
|
(col_width * (NB_CELL_AM + 1 + NB_CELL_PM + 1) * nb_days),
|
|
]
|
|
),
|
|
style=TableStyle(
|
|
[
|
|
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
|
|
("LEFTPADDING", (0, 0), (-1, -1), 0),
|
|
("RIGHTPADDING", (0, 0), (-1, -1), 0),
|
|
("BOTTOMPADDING", (0, 0), (-1, -1), 3),
|
|
("TOPPADDING", (0, 0), (-1, -1), 3),
|
|
("BOTTOMPADDING", (0, -1), (-1, -1), 10),
|
|
(
|
|
"ROWBACKGROUNDS",
|
|
(0, 2),
|
|
(-1, -1),
|
|
(colors.white, colors.lightgrey),
|
|
),
|
|
]
|
|
),
|
|
)
|
|
|
|
objects.append(T)
|
|
|
|
# Réduit sur une page
|
|
objects = [KeepInFrame(0, 0, objects, mode="shrink")]
|
|
# Build document
|
|
report = io.BytesIO() # in-memory document, no disk file
|
|
filename = "absences-%s-%s.pdf" % (DeptName, groups_infos.groups_filename)
|
|
if sco_preferences.get_preference("feuille_releve_abs_taille") == "A3":
|
|
taille = A3
|
|
elif sco_preferences.get_preference("feuille_releve_abs_taille") == "A4":
|
|
taille = A4
|
|
if sco_preferences.get_preference("feuille_releve_abs_format") == "Paysage":
|
|
document = BaseDocTemplate(report, pagesize=landscape(taille))
|
|
else:
|
|
document = BaseDocTemplate(report, pagesize=taille)
|
|
document.addPageTemplates(
|
|
ScoDocPageTemplate(
|
|
document,
|
|
preferences=sco_preferences.SemPreferences(),
|
|
)
|
|
)
|
|
document.build(objects)
|
|
data = report.getvalue()
|
|
|
|
return scu.sendPDFFile(data, filename)
|