From 233a11ad14c8a43e58c6067ce4d66f25f53f74a4 Mon Sep 17 00:00:00 2001 From: viennet Date: Wed, 21 Oct 2020 22:56:25 +0200 Subject: [PATCH] background image on pdf bulletins --- gen_tables.py | 10 +++++----- sco_bulletins_generator.py | 1 + sco_bulletins_pdf.py | 9 +++++---- sco_pdf.py | 28 ++++++++++++++++++++++++++-- sco_preferences.py | 10 ++++++++++ sco_trombino.py | 30 +++++++++++++++++------------- 6 files changed, 64 insertions(+), 24 deletions(-) diff --git a/gen_tables.py b/gen_tables.py index 0e14585f7..3d15ee91b 100644 --- a/gen_tables.py +++ b/gen_tables.py @@ -51,8 +51,7 @@ from sco_pdf import * def mark_paras(L, tags): - """Put each (string) element of L between - """ + """Put each (string) element of L between """ for tag in tags: b = "<" + tag + ">" c = "" @@ -584,8 +583,7 @@ class GenTable: return repr(doc) def json(self): - """JSON representation of the table. - """ + """JSON representation of the table.""" d = [] for row in self.rows: r = {} @@ -639,7 +637,9 @@ class GenTable: return "\n".join(H) elif format == "pdf": objects = self.pdf() - doc = pdf_basic_page(objects, title=title, preferences=self.preferences) + doc = pdf_basic_page( + objects, title=title, preferences=self.preferences, context=context + ) if publish: return sendPDFFile(REQUEST, doc, filename + ".pdf") else: diff --git a/sco_bulletins_generator.py b/sco_bulletins_generator.py index f89645bcc..3c4cf6380 100644 --- a/sco_bulletins_generator.py +++ b/sco_bulletins_generator.py @@ -198,6 +198,7 @@ class BulletinGenerator: document.addPageTemplates( ScolarsPageTemplate( document, + self.context, author="%s %s (E. Viennet) [%s]" % (SCONAME, SCOVERSION, self.description), title="Bulletin %s de %s" diff --git a/sco_bulletins_pdf.py b/sco_bulletins_pdf.py index 7e6750ebe..a3a2f1793 100644 --- a/sco_bulletins_pdf.py +++ b/sco_bulletins_pdf.py @@ -86,6 +86,7 @@ def pdfassemblebulletins( document.addPageTemplates( ScolarsPageTemplate( document, + context, author="%s %s (E. Viennet)" % (SCONAME, SCOVERSION), title="Bulletin %s" % bul_title, subject="Bulletin de note", @@ -107,13 +108,13 @@ def process_field( """Process a field given in preferences, returns - if format = 'pdf': a list of Platypus objects - if format = 'html' : a string - - Substitutes all %()s markup + + Substitutes all %()s markup Remove potentialy harmful tags Replaces by - If format = 'html', replaces by

. HTML does not allow logos. + If format = 'html', replaces by

. HTML does not allow logos. """ try: text = (field or "") % WrapDict( @@ -136,7 +137,7 @@ def process_field( # handle logos: image_dir = SCODOC_LOGOS_DIR + "/logos_" + context.DeptId() + "/" if not os.path.exists(image_dir): - image_dir = SCODOC_LOGOS_DIR + "/" # use global logos + image_dir = SCODOC_LOGOS_DIR + "/" # use global logos text = re.sub( r"<(\s*)logo(.*?)src\s*=\s*(.*?)>", r"<\1logo\2\3>", text ) # remove forbidden src attribute diff --git a/sco_pdf.py b/sco_pdf.py index 90dc07638..a4d3cbc6a 100644 --- a/sco_pdf.py +++ b/sco_pdf.py @@ -159,6 +159,7 @@ class ScolarsPageTemplate(PageTemplate): def __init__( self, document, + context=None, pagesbookmarks={}, author=None, title=None, @@ -178,6 +179,8 @@ class ScolarsPageTemplate(PageTemplate): self.server_name = server_name self.filigranne = filigranne self.footer_template = footer_template + self.with_page_background = self.preferences["bul_pdf_with_background"] + self.background_image_filename = None # Our doc is made of a single frame left, top, right, bottom = [float(x) for x in margins] content = Frame( @@ -188,9 +191,23 @@ class ScolarsPageTemplate(PageTemplate): ) PageTemplate.__init__(self, "ScolarsPageTemplate", [content]) self.logo = None + # XXX COPIED from sco_pvpdf, to be refactored (no time now) + # Search background in dept specific dir, then in global config dir + for image_dir in ( + SCODOC_LOGOS_DIR + "/logos_" + context.DeptId() + "/", + SCODOC_LOGOS_DIR + "/", # global logos + ): + for suffix in LOGOS_IMAGES_ALLOWED_TYPES: + fn = image_dir + "/bul_pdf_background" + "." + suffix + if not self.background_image_filename and os.path.exists(fn): + self.background_image_filename = fn + # Also try to use PV background + fn = image_dir + "/letter_background" + "." + suffix + if not self.background_image_filename and os.path.exists(fn): + self.background_image_filename = fn def beforeDrawPage(self, canvas, doc): - """Draws a logo and an 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] month : Month as a decimal number [01,12]. @@ -203,6 +220,12 @@ class ScolarsPageTemplate(PageTemplate): """ canvas.saveState() + # ---- Background image + if self.background_image_filename and self.with_page_background: + canvas.drawImage( + self.background_image_filename, 0, 0, doc.pagesize[0], doc.pagesize[1] + ) + # ---- Logo: a small image, positionned at top left of the page if self.logo is not None: # draws the logo if it exists @@ -266,7 +289,7 @@ def _makeTimeDict(): def pdf_basic_page( - objects, title="", preferences=None + objects, title="", preferences=None, context=None ): # used by gen_table.make_page() """Simple convenience fonction: build a page from a list of platypus objects, adding a title if specified. @@ -277,6 +300,7 @@ def pdf_basic_page( document.addPageTemplates( ScolarsPageTemplate( document, + context, title=title, author="%s %s (E. Viennet)" % (SCONAME, SCOVERSION), footer_template="Edité par %(scodoc_name)s le %(day)s/%(month)s/%(year)s à %(hour)sh%(minute)s", diff --git a/sco_preferences.py b/sco_preferences.py index 67f06915e..75b5989d7 100644 --- a/sco_preferences.py +++ b/sco_preferences.py @@ -1386,6 +1386,16 @@ Année scolaire: %(anneescolaire)s "category": "bul", }, ), + ( + "bul_pdf_with_background", + { + "initvalue": 0, + "title": "Mettre l'image de fond sur les bulletins", + "input_type": "boolcheckbox", + "labels": ["non", "oui"], + "category": "bul", + }, + ), ( "SCOLAR_FONT_BUL_FIELDS", { diff --git a/sco_trombino.py b/sco_trombino.py index a3f8eb452..230714de3 100644 --- a/sco_trombino.py +++ b/sco_trombino.py @@ -157,14 +157,16 @@ def trombino_html(context, groups_infos, REQUEST=None): def check_local_photos_availability(context, groups_infos, REQUEST, format=""): """Verifie que toutes les photos (des gropupes indiqués) sont copiées localement - dans ScoDoc (seules les photos dont nous disposons localement peuvent être exportées + dans ScoDoc (seules les photos dont nous disposons localement peuvent être exportées en pdf ou en zip). Si toutes ne sont pas dispo, retourne un dialogue d'avertissement pour l'utilisateur. """ nb_missing = 0 for t in groups_infos.members: etudid = t["etudid"] - url = sco_photos.etud_photo_url(context, t, REQUEST=REQUEST) # -> copy distant files if needed + url = sco_photos.etud_photo_url( + context, t, REQUEST=REQUEST + ) # -> copy distant files if needed if not sco_photos.etud_photo_is_local(context, t): nb_missing += 1 if nb_missing > 0: @@ -271,8 +273,7 @@ def trombino_copy_photos(context, group_ids=[], REQUEST=None, dialog_confirmed=F def _get_etud_platypus_image(context, t, image_width=2 * cm): - """Returns aplatypus object for the photo of student t - """ + """Returns aplatypus object for the photo of student t""" try: path = sco_photos.photo_pathname(context, t, size="small") if not path: @@ -364,7 +365,9 @@ def _trombino_pdf(context, groups_infos, REQUEST): document = BaseDocTemplate(report) document.addPageTemplates( ScolarsPageTemplate( - document, preferences=context.get_preferences(sem["formsemestre_id"]) + document, + context, + preferences=context.get_preferences(sem["formsemestre_id"]), ) ) document.build(objects) @@ -445,7 +448,9 @@ def _listeappel_photos_pdf(context, groups_infos, REQUEST): document = BaseDocTemplate(report) document.addPageTemplates( ScolarsPageTemplate( - document, preferences=context.get_preferences(sem["formsemestre_id"]) + document, + context, + preferences=context.get_preferences(sem["formsemestre_id"]), ) ) document.build(objects) @@ -509,7 +514,9 @@ def _listeappel_photos_pdf(context, groups_infos, REQUEST): document = BaseDocTemplate(report) document.addPageTemplates( ScolarsPageTemplate( - document, preferences=context.get_preferences(sem["formsemestre_id"]) + document, + context, + preferences=context.get_preferences(sem["formsemestre_id"]), ) ) document.build(objects) @@ -519,8 +526,7 @@ def _listeappel_photos_pdf(context, groups_infos, REQUEST): # --------------------- Upload des photos de tout un groupe def photos_generate_excel_sample(context, group_ids=[], REQUEST=None): - """Feuille excel pour import fichiers photos - """ + """Feuille excel pour import fichiers photos""" fmt = ImportScolars.sco_import_format() data = ImportScolars.sco_import_generate_excel_sample( fmt, @@ -541,8 +547,7 @@ def photos_generate_excel_sample(context, group_ids=[], REQUEST=None): def photos_import_files_form(context, group_ids=[], REQUEST=None): - """Formulaire pour importation photos - """ + """Formulaire pour importation photos""" groups_infos = sco_groups_view.DisplayedGroupsInfos( context, group_ids, REQUEST=REQUEST ) @@ -596,8 +601,7 @@ def photos_import_files_form(context, group_ids=[], REQUEST=None): def photos_import_files( context, group_ids=[], xlsfile=None, zipfile=None, REQUEST=None ): - """Importation des photos - """ + """Importation des photos""" groups_infos = sco_groups_view.DisplayedGroupsInfos( context, group_ids, REQUEST=REQUEST )