PDF: affiche liste polices dispo, meilleurs messages d'erreur

This commit is contained in:
Emmanuel Viennet 2022-03-24 09:59:44 +01:00
parent 1b887858bb
commit 41778d5918
7 changed files with 104 additions and 95 deletions

View File

@ -6,15 +6,13 @@
"""Génération bulletin BUT au format PDF standard """Génération bulletin BUT au format PDF standard
""" """
from reportlab.lib.colors import blue
from reportlab.lib.units import cm, mm
from reportlab.platypus import Paragraph, Spacer from reportlab.platypus import Paragraph, Spacer
from app.scodoc.sco_pdf import blue, cm, mm from app.scodoc.sco_bulletins_standard import BulletinGeneratorStandard
from app.scodoc import gen_tables from app.scodoc import gen_tables
from app.scodoc.sco_codes_parcours import UE_SPORT from app.scodoc.sco_codes_parcours import UE_SPORT
from app.scodoc.sco_utils import fmt_note
from app.scodoc.sco_bulletins_standard import BulletinGeneratorStandard
class BulletinGeneratorStandardBUT(BulletinGeneratorStandard): class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):

View File

@ -34,17 +34,19 @@
CE FORMAT N'EVOLUERA PLUS ET EST CONSIDERE COMME OBSOLETE. CE FORMAT N'EVOLUERA PLUS ET EST CONSIDERE COMME OBSOLETE.
""" """
from reportlab.lib.colors import Color, blue
from reportlab.lib.units import cm, mm
from reportlab.platypus import Paragraph, Spacer, Table
import app.scodoc.sco_utils as scu
from app.scodoc.sco_permissions import Permission
from app.scodoc import sco_formsemestre
from app.scodoc import sco_pdf
from app.scodoc.sco_pdf import Color, Paragraph, Spacer, Table
from app.scodoc.sco_pdf import blue, cm, mm
from app.scodoc.sco_pdf import SU
from app.scodoc import sco_preferences
from app.scodoc import sco_bulletins_generator from app.scodoc import sco_bulletins_generator
from app.scodoc import sco_bulletins_pdf from app.scodoc import sco_bulletins_pdf
from app.scodoc import sco_formsemestre
from app.scodoc.sco_permissions import Permission
from app.scodoc import sco_pdf
from app.scodoc.sco_pdf import SU
from app.scodoc import sco_preferences
import app.scodoc.sco_utils as scu
# Important: Le nom de la classe ne doit pas changer (bien le choisir), car il sera stocké en base de données (dans les préférences) # Important: Le nom de la classe ne doit pas changer (bien le choisir), car il sera stocké en base de données (dans les préférences)
class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator): class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):

View File

@ -32,16 +32,12 @@ On redéfini la table centrale du bulletin de note et hérite de tout le reste d
E. Viennet, juillet 2011 E. Viennet, juillet 2011
""" """
from reportlab.lib.colors import Color
from reportlab.lib.units import mm
import app.scodoc.sco_utils as scu
from app.scodoc.sco_pdf import blue, cm, mm
from app.scodoc.sco_pdf import Color, Paragraph, Spacer, Table
from app.scodoc import sco_preferences
from app.scodoc import sco_bulletins_generator
from app.scodoc import sco_bulletins_standard from app.scodoc import sco_bulletins_standard
from app.scodoc import gen_tables from app.scodoc import sco_preferences
import app.scodoc.sco_utils as scu
class BulletinGeneratorUCAC(sco_bulletins_standard.BulletinGeneratorStandard): class BulletinGeneratorUCAC(sco_bulletins_standard.BulletinGeneratorStandard):

View File

@ -44,22 +44,17 @@ import traceback
import unicodedata import unicodedata
import reportlab import reportlab
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle, Image, KeepInFrame from reportlab.platypus import Paragraph, Frame
from reportlab.platypus.flowables import Flowable from reportlab.platypus.flowables import Flowable
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize # pylint: disable=no-name-in-module from reportlab.rl_config import defaultPageSize # pylint: disable=no-name-in-module
from reportlab.lib.units import inch, cm, mm from reportlab.lib.units import inch, cm, mm
from reportlab.lib.colors import pink, black, red, blue, green, magenta, red
from reportlab.lib.colors import Color
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.lib import styles from reportlab.lib import styles
from reportlab.lib.pagesizes import letter, A4, landscape
from flask import g from flask import g
import app.scodoc.sco_utils as scu
from app.scodoc.sco_utils import CONFIG from app.scodoc.sco_utils import CONFIG
from app import log from app import log
from app.scodoc.sco_exceptions import ScoGenError, ScoValueError from app.scodoc.sco_exceptions import ScoGenError, ScoValueError
@ -89,6 +84,12 @@ def SU(s):
return s return s
def get_available_font_names() -> list[str]:
"""List installed font names"""
can = canvas.Canvas(io.StringIO())
return can.getAvailableFonts()
def _splitPara(txt): def _splitPara(txt):
"split a string, returns a list of <para > ... </para>" "split a string, returns a list of <para > ... </para>"
L = [] L = []
@ -147,12 +148,26 @@ def makeParas(txt, style, suppress_empty=False):
except Exception as e: except Exception as e:
log(traceback.format_exc()) log(traceback.format_exc())
log("Invalid pdf para format: %s" % txt) log("Invalid pdf para format: %s" % txt)
result = [ try:
Paragraph( result = [
SU('<font color="red"><i>Erreur: format invalide</i></font>'), Paragraph(
style, SU('<font color="red"><i>Erreur: format invalide</i></font>'),
) style,
] )
]
except ValueError as e: # probleme font ? essaye sans style
# recupere font en cause ?
m = re.match(r".*family/bold/italic for (.*)", e.args[0], re.DOTALL)
if m:
message = f"police non disponible: {m[1]}"
else:
message = "format invalide"
return [
Paragraph(
SU(f'<font color="red"><b>Erreur: {message}</b></font>'),
reportlab.lib.styles.ParagraphStyle({}),
)
]
return result return result
@ -166,7 +181,6 @@ def bold_paras(L, tag="b", close=None):
if hasattr(L, "keys"): if hasattr(L, "keys"):
# L is a dict # L is a dict
for k in L: for k in L:
x = L[k]
if k[0] != "_": if k[0] != "_":
L[k] = b + L[k] or "" + close L[k] = b + L[k] or "" + close
return L return L
@ -256,7 +270,7 @@ class ScoDocPageTemplate(PageTemplate):
if logo is not None: if logo is not None:
self.background_image_filename = logo.filepath self.background_image_filename = logo.filepath
def beforeDrawPage(self, canvas, doc): def beforeDrawPage(self, canv, doc):
"""Draws (optional) background, logo and contribution message on each page. """Draws (optional) background, logo and contribution message on each page.
day : Day of the month as a decimal number [01,31] day : Day of the month as a decimal number [01,31]
@ -271,10 +285,10 @@ class ScoDocPageTemplate(PageTemplate):
""" """
if not self.preferences: if not self.preferences:
return return
canvas.saveState() canv.saveState()
# ---- Background image # ---- Background image
if self.background_image_filename and self.with_page_background: if self.background_image_filename and self.with_page_background:
canvas.drawImage( canv.drawImage(
self.background_image_filename, 0, 0, doc.pagesize[0], doc.pagesize[1] self.background_image_filename, 0, 0, doc.pagesize[0], doc.pagesize[1]
) )
@ -285,32 +299,32 @@ class ScoDocPageTemplate(PageTemplate):
(width, height), (width, height),
image, image,
) = self.logo ) = self.logo
canvas.drawImage(image, inch, doc.pagesize[1] - inch, width, height) canv.drawImage(image, inch, doc.pagesize[1] - inch, width, height)
# ---- Add some meta data and bookmarks # ---- Add some meta data and bookmarks
if self.pdfmeta_author: if self.pdfmeta_author:
canvas.setAuthor(SU(self.pdfmeta_author)) canv.setAuthor(SU(self.pdfmeta_author))
if self.pdfmeta_title: if self.pdfmeta_title:
canvas.setTitle(SU(self.pdfmeta_title)) canv.setTitle(SU(self.pdfmeta_title))
if self.pdfmeta_subject: if self.pdfmeta_subject:
canvas.setSubject(SU(self.pdfmeta_subject)) canv.setSubject(SU(self.pdfmeta_subject))
bookmark = self.pagesbookmarks.get(doc.page, None) bookmark = self.pagesbookmarks.get(doc.page, None)
if bookmark: if bookmark:
canvas.bookmarkPage(bookmark) canv.bookmarkPage(bookmark)
canvas.addOutlineEntry(SU(bookmark), bookmark) canv.addOutlineEntry(SU(bookmark), bookmark)
def draw_footer(self, canvas, content): def draw_footer(self, canv, content):
"""Print the footer""" """Print the footer"""
canvas.setFont( canv.setFont(
self.preferences["SCOLAR_FONT"], self.preferences["SCOLAR_FONT_SIZE_FOOT"] self.preferences["SCOLAR_FONT"], self.preferences["SCOLAR_FONT_SIZE_FOOT"]
) )
canvas.drawString( canv.drawString(
self.preferences["pdf_footer_x"] * mm, self.preferences["pdf_footer_x"] * mm,
self.preferences["pdf_footer_y"] * mm, self.preferences["pdf_footer_y"] * mm,
content, content,
) )
canvas.restoreState() canv.restoreState()
def footer_string(self) -> str: def footer_string(self) -> str:
"""String contenu du pied de page""" """String contenu du pied de page"""
@ -319,14 +333,14 @@ class ScoDocPageTemplate(PageTemplate):
d["server_url"] = self.server_name d["server_url"] = self.server_name
return SU(self.footer_template % d) return SU(self.footer_template % d)
def afterDrawPage(self, canvas, doc): def afterDrawPage(self, canv, doc):
if not self.preferences: if not self.preferences:
return return
# ---- Footer # ---- Footer
foot_content = None foot_content = None
if hasattr(doc, "current_footer"): if hasattr(doc, "current_footer"):
foot_content = doc.current_footer foot_content = doc.current_footer
self.draw_footer(canvas, foot_content or self.footer_string()) self.draw_footer(canv, foot_content or self.footer_string())
# ---- Filigranne (texte en diagonal en haut a gauche de chaque page) # ---- Filigranne (texte en diagonal en haut a gauche de chaque page)
filigranne = None filigranne = None
if hasattr(doc, "filigranne"): if hasattr(doc, "filigranne"):
@ -338,13 +352,13 @@ class ScoDocPageTemplate(PageTemplate):
else: else:
filigranne = self.filigranne.get(doc.page, None) filigranne = self.filigranne.get(doc.page, None)
if filigranne: if filigranne:
canvas.saveState() canv.saveState()
canvas.translate(9 * cm, 27.6 * cm) canv.translate(9 * cm, 27.6 * cm)
canvas.rotate(30) canv.rotate(30)
canvas.scale(4.5, 4.5) canv.scale(4.5, 4.5)
canvas.setFillColorRGB(1.0, 0.65, 0.65, alpha=0.6) canv.setFillColorRGB(1.0, 0.65, 0.65, alpha=0.6)
canvas.drawRightString(0, 0, SU(filigranne)) canv.drawRightString(0, 0, SU(filigranne))
canvas.restoreState() canv.restoreState()
doc.filigranne = None doc.filigranne = None
def afterPage(self): def afterPage(self):
@ -443,8 +457,8 @@ class PDFLock(object):
return # deja lock pour ce thread return # deja lock pour ce thread
try: try:
self.Q.put(1, True, self.timeout) self.Q.put(1, True, self.timeout)
except queue.Full: except queue.Full as e:
raise ScoGenError(msg="Traitement PDF occupé: ré-essayez") raise ScoGenError(msg="Traitement PDF occupé: ré-essayez") from e
self.current_thread = threading.get_ident() self.current_thread = threading.get_ident()
self.nref = 1 self.nref = 1
log("PDFLock: granted to %s" % self.current_thread) log("PDFLock: granted to %s" % self.current_thread)
@ -471,7 +485,6 @@ class WatchLock:
def release(self): def release(self):
t = threading.current_thread() t = threading.current_thread()
assert (self.native_id == t.native_id) and (self.ident == t.ident) assert (self.native_id == t.native_id) and (self.ident == t.ident)
pass
class FakeLock: class FakeLock:

View File

@ -121,6 +121,7 @@ from app import log
from app.scodoc.sco_exceptions import ScoValueError, ScoException from app.scodoc.sco_exceptions import ScoValueError, ScoException
from app.scodoc.TrivialFormulator import TrivialFormulator from app.scodoc.TrivialFormulator import TrivialFormulator
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc import sco_pdf
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
@ -194,6 +195,8 @@ def _get_pref_default_value_from_config(name, pref_spec):
return value return value
_INSTALLED_FONTS = ", ".join(sco_pdf.get_available_font_names())
PREF_CATEGORIES = ( PREF_CATEGORIES = (
# sur page "Paramètres" # sur page "Paramètres"
("general", {}), ("general", {}),
@ -777,7 +780,7 @@ class BasePreferences(object):
{ {
"initvalue": "Helvetica", "initvalue": "Helvetica",
"title": "Police de caractère principale", "title": "Police de caractère principale",
"explanation": "pour les pdf (Helvetica est recommandée)", "explanation": f"pour les pdf (Helvetica est recommandée, parmi {_INSTALLED_FONTS})",
"size": 25, "size": 25,
"category": "pdf", "category": "pdf",
}, },
@ -1140,7 +1143,7 @@ class BasePreferences(object):
{ {
"initvalue": "Times-Roman", "initvalue": "Times-Roman",
"title": "Police de caractère pour les PV", "title": "Police de caractère pour les PV",
"explanation": "pour les pdf", "explanation": f"pour les pdf ({_INSTALLED_FONTS})",
"size": 25, "size": 25,
"category": "pvpdf", "category": "pvpdf",
}, },
@ -1542,7 +1545,7 @@ class BasePreferences(object):
{ {
"initvalue": "Times-Roman", "initvalue": "Times-Roman",
"title": "Police titres bulletins", "title": "Police titres bulletins",
"explanation": "pour les pdf", "explanation": f"pour les pdf ({_INSTALLED_FONTS})",
"size": 25, "size": 25,
"category": "bul", "category": "bul",
}, },

View File

@ -28,15 +28,13 @@
"""Edition des PV de jury """Edition des PV de jury
""" """
import io import io
import os
import re import re
import reportlab import reportlab
from reportlab.lib.units import cm, mm from reportlab.lib.units import cm, mm
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY from reportlab.lib.enums import TA_RIGHT, TA_JUSTIFY
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak from reportlab.platypus import Paragraph, Spacer, Frame, PageBreak
from reportlab.platypus import Table, TableStyle, Image, KeepInFrame from reportlab.platypus import Table, TableStyle, Image
from reportlab.platypus.flowables import Flowable
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from reportlab.lib.pagesizes import A4, landscape from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib import styles from reportlab.lib import styles
@ -53,7 +51,6 @@ from app.scodoc import sco_preferences
from app.scodoc import sco_etud from app.scodoc import sco_etud
import sco_version import sco_version
from app.scodoc.sco_logos import find_logo from app.scodoc.sco_logos import find_logo
from app.scodoc.sco_pdf import PDFLOCK
from app.scodoc.sco_pdf import SU from app.scodoc.sco_pdf import SU
LOGO_FOOTER_ASPECT = scu.CONFIG.LOGO_FOOTER_ASPECT # XXX A AUTOMATISER LOGO_FOOTER_ASPECT = scu.CONFIG.LOGO_FOOTER_ASPECT # XXX A AUTOMATISER
@ -317,14 +314,14 @@ class PVTemplate(CourrierIndividuelTemplate):
self.with_footer = self.preferences["PV_WITH_FOOTER"] self.with_footer = self.preferences["PV_WITH_FOOTER"]
self.with_page_background = self.preferences["PV_WITH_BACKGROUND"] self.with_page_background = self.preferences["PV_WITH_BACKGROUND"]
def afterDrawPage(self, canvas, doc): def afterDrawPage(self, canv, doc):
"""Called after all flowables have been drawn on a page""" """Called after all flowables have been drawn on a page"""
pass pass
def beforeDrawPage(self, canvas, doc): def beforeDrawPage(self, canv, doc):
"""Called before any flowables are drawn on a page""" """Called before any flowables are drawn on a page"""
# If the page number is even, force a page break # If the page number is even, force a page break
CourrierIndividuelTemplate.beforeDrawPage(self, canvas, doc) CourrierIndividuelTemplate.beforeDrawPage(self, canv, doc)
# Note: on cherche un moyen de generer un saut de page double # Note: on cherche un moyen de generer un saut de page double
# (redémarrer sur page impaire, nouvelle feuille en recto/verso). Pas trouvé en Platypus. # (redémarrer sur page impaire, nouvelle feuille en recto/verso). Pas trouvé en Platypus.
# #

View File

@ -33,20 +33,23 @@
import io import io
from reportlab.lib import colors from reportlab.lib import colors
from reportlab.lib import pagesizes from reportlab.lib.colors import black
from reportlab.lib.pagesizes import A4, A3 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
import app.scodoc.sco_utils as scu
from app import log
from app.scodoc import sco_abs 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
from app.scodoc import sco_groups_view from app.scodoc import sco_groups_view
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_trombino from app.scodoc import sco_trombino
from app.scodoc import sco_etud import app.scodoc.sco_utils as scu
from app.scodoc.sco_exceptions import ScoPDFFormatError from app.scodoc.sco_pdf import SU, ScoDocPageTemplate
from app.scodoc.sco_pdf import *
# Paramétrage de l'aspect graphique: # Paramétrage de l'aspect graphique:
PHOTOWIDTH = 2.8 * cm PHOTOWIDTH = 2.8 * cm
@ -55,7 +58,7 @@ N_PER_ROW = 5
def pdf_trombino_tours( def pdf_trombino_tours(
group_ids=[], # liste des groupes à afficher group_ids=(), # liste des groupes à afficher
formsemestre_id=None, # utilisé si pas de groupes selectionné formsemestre_id=None, # utilisé si pas de groupes selectionné
): ):
"""Generation du trombinoscope en fichier PDF""" """Generation du trombinoscope en fichier PDF"""
@ -66,7 +69,6 @@ def pdf_trombino_tours(
DeptName = sco_preferences.get_preference("DeptName") DeptName = sco_preferences.get_preference("DeptName")
DeptFullName = sco_preferences.get_preference("DeptFullName") DeptFullName = sco_preferences.get_preference("DeptFullName")
UnivName = sco_preferences.get_preference("UnivName")
InstituteName = sco_preferences.get_preference("InstituteName") InstituteName = sco_preferences.get_preference("InstituteName")
# Generate PDF page # Generate PDF page
StyleSheet = styles.getSampleStyleSheet() StyleSheet = styles.getSampleStyleSheet()
@ -143,9 +145,7 @@ def pdf_trombino_tours(
for group_id in groups_infos.group_ids: for group_id in groups_infos.group_ids:
if group_id != "None": if group_id != "None":
members, group, group_tit, sem, nbdem = sco_groups.get_group_infos( members, _, group_tit, sem, _ = sco_groups.get_group_infos(group_id, "I")
group_id, "I"
)
groups += " %s" % group_tit groups += " %s" % group_tit
L = [] L = []
currow = [] currow = []
@ -286,14 +286,14 @@ def pdf_trombino_tours(
def pdf_feuille_releve_absences( def pdf_feuille_releve_absences(
group_ids=[], # liste des groupes à afficher group_ids=(), # liste des groupes à afficher
formsemestre_id=None, # utilisé si pas de groupes selectionné formsemestre_id=None, # utilisé si pas de groupes selectionné
): ):
"""Generation de la feuille d'absence en fichier PDF, avec photos""" """Generation de la feuille d'absence en fichier PDF, avec photos"""
NB_CELL_AM = sco_preferences.get_preference("feuille_releve_abs_AM") NB_CELL_AM = sco_preferences.get_preference("feuille_releve_abs_AM")
NB_CELL_PM = sco_preferences.get_preference("feuille_releve_abs_PM") NB_CELL_PM = sco_preferences.get_preference("feuille_releve_abs_PM")
COLWIDTH = 0.85 * cm col_width = 0.85 * cm
if sco_preferences.get_preference("feuille_releve_abs_samedi"): if sco_preferences.get_preference("feuille_releve_abs_samedi"):
days = sco_abs.DAYNAMES[:6] # Lundi, ..., Samedi days = sco_abs.DAYNAMES[:6] # Lundi, ..., Samedi
else: else:
@ -307,7 +307,6 @@ def pdf_feuille_releve_absences(
DeptName = sco_preferences.get_preference("DeptName") DeptName = sco_preferences.get_preference("DeptName")
DeptFullName = sco_preferences.get_preference("DeptFullName") DeptFullName = sco_preferences.get_preference("DeptFullName")
UnivName = sco_preferences.get_preference("UnivName")
InstituteName = sco_preferences.get_preference("InstituteName") InstituteName = sco_preferences.get_preference("InstituteName")
# Generate PDF page # Generate PDF page
StyleSheet = styles.getSampleStyleSheet() StyleSheet = styles.getSampleStyleSheet()
@ -340,7 +339,7 @@ def pdf_feuille_releve_absences(
currow = [""] * (NB_CELL_AM + 1 + NB_CELL_PM + 1) currow = [""] * (NB_CELL_AM + 1 + NB_CELL_PM + 1)
elem_day = Table( elem_day = Table(
[currow], [currow],
colWidths=([COLWIDTH] * (NB_CELL_AM + 1 + NB_CELL_PM + 1)), colWidths=([col_width] * (NB_CELL_AM + 1 + NB_CELL_PM + 1)),
style=TableStyle( style=TableStyle(
[ [
("GRID", (0, 0), (NB_CELL_AM - 1, 0), 0.25, black), ("GRID", (0, 0), (NB_CELL_AM - 1, 0), 0.25, black),
@ -362,7 +361,7 @@ def pdf_feuille_releve_absences(
elem_week = Table( elem_week = Table(
W, W,
colWidths=([COLWIDTH * (NB_CELL_AM + 1 + NB_CELL_PM + 1)] * nb_days), colWidths=([col_width * (NB_CELL_AM + 1 + NB_CELL_PM + 1)] * nb_days),
style=TableStyle( style=TableStyle(
[ [
("LEFTPADDING", (0, 0), (-1, -1), 0), ("LEFTPADDING", (0, 0), (-1, -1), 0),
@ -378,7 +377,7 @@ def pdf_feuille_releve_absences(
elem_day_name = Table( elem_day_name = Table(
[currow], [currow],
colWidths=([COLWIDTH * (NB_CELL_AM + 1 + NB_CELL_PM + 1)] * nb_days), colWidths=([col_width * (NB_CELL_AM + 1 + NB_CELL_PM + 1)] * nb_days),
style=TableStyle( style=TableStyle(
[ [
("LEFTPADDING", (0, 0), (-1, -1), 0), ("LEFTPADDING", (0, 0), (-1, -1), 0),
@ -390,9 +389,7 @@ def pdf_feuille_releve_absences(
) )
for group_id in groups_infos.group_ids: for group_id in groups_infos.group_ids:
members, group, group_tit, sem, nbdem = sco_groups.get_group_infos( members, _, group_tit, _, _ = sco_groups.get_group_infos(group_id, "I")
group_id, "I"
)
L = [] L = []
currow = [ currow = [
@ -429,7 +426,10 @@ def pdf_feuille_releve_absences(
T = Table( T = Table(
L, L,
colWidths=( colWidths=(
[5.0 * cm, (COLWIDTH * (NB_CELL_AM + 1 + NB_CELL_PM + 1) * nb_days)] [
5.0 * cm,
(col_width * (NB_CELL_AM + 1 + NB_CELL_PM + 1) * nb_days),
]
), ),
style=TableStyle( style=TableStyle(
[ [