Fix PDF (combining accents) and StringIO imports

This commit is contained in:
Emmanuel Viennet 2021-07-25 23:31:59 +03:00
parent 294bc8f205
commit a07571494c
9 changed files with 50 additions and 42 deletions

View File

@ -78,6 +78,7 @@ class DEFAULT_TABLE_PREFERENCES(object):
"SCOLAR_FONT": "Helvetica", # used for PDF, overriden by preferences argument "SCOLAR_FONT": "Helvetica", # used for PDF, overriden by preferences argument
"SCOLAR_FONT_SIZE": 10, "SCOLAR_FONT_SIZE": 10,
"SCOLAR_FONT_SIZE_FOOT": 6, "SCOLAR_FONT_SIZE_FOOT": 6,
"bul_pdf_with_background": False,
} }
def __getitem__(self, k): def __getitem__(self, k):
@ -699,8 +700,8 @@ class SeqGenTable(object):
# ----- Exemple d'utilisation minimal. # ----- Exemple d'utilisation minimal.
if __name__ == "__main__": if __name__ == "__main__":
T = GenTable( T = gen_tables.GenTable(
rows=[{"nom": "Toto", "age": 26}, {"nom": "Titi", "age": 21}], rows=[{"nom": "Hélène", "age": 26}, {"nom": "Titi&çà§", "age": 21}],
columns_ids=("nom", "age"), columns_ids=("nom", "age"),
) )
print("--- HTML:") print("--- HTML:")
@ -709,3 +710,24 @@ if __name__ == "__main__":
print(T.gen(format="xml")) print(T.gen(format="xml"))
print("\n--- JSON:") print("\n--- JSON:")
print(T.gen(format="json")) print(T.gen(format="json"))
# Test pdf:
import io
from reportlab.platypus import KeepInFrame
from app.scodoc import sco_preferences, sco_pdf
preferences = sco_preferences.SemPreferences(None)
T.preferences = preferences
objects = T.gen(format="pdf")
objects = [KeepInFrame(0, 0, objects, mode="shrink")]
doc = io.BytesIO()
document = sco_pdf.BaseDocTemplate(doc)
document.addPageTemplates(
sco_pdf.ScolarsPageTemplate(
document,
)
)
document.build(objects)
data = doc.getvalue()
open("/tmp/gen_table.pdf", "wb").write(data)
p = T.make_page(None, format="pdf", REQUEST=None)
open("toto.pdf", "wb").write(p)

View File

@ -28,10 +28,7 @@
"""ScoDoc : formulaires gestion maquettes Apogee / export resultats """ScoDoc : formulaires gestion maquettes Apogee / export resultats
""" """
try: from io import StringIO
from io import StringIO # for Python 3
except ImportError:
from cStringIO import StringIO # for Python 2
from zipfile import ZipFile from zipfile import ZipFile
from flask import url_for, g from flask import url_for, g

View File

@ -31,10 +31,7 @@ import datetime
import re import re
import time import time
try: from io import StringIO
from io import StringIO # for Python 3
except ImportError:
from cStringIO import StringIO # for Python 2
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.header import Header from email.header import Header

View File

@ -31,17 +31,13 @@
Tout accès à ReportLab doit donc être précédé d'un PDFLOCK.acquire() Tout accès à ReportLab doit donc être précédé d'un PDFLOCK.acquire()
et terminé par un PDFLOCK.release() et terminé par un PDFLOCK.release()
""" """
import io
import time import time
import re import re
import os import os
import unicodedata import unicodedata
import traceback import traceback
try:
from io import StringIO # for Python 3
except ImportError:
from cStringIO import StringIO # for Python 2
import reportlab import reportlab
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak
from reportlab.platypus import Table, TableStyle, Image, KeepInFrame from reportlab.platypus import Table, TableStyle, Image, KeepInFrame
@ -59,7 +55,6 @@ from reportlab.lib.pagesizes import letter, A4, landscape
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc.sco_utils import ( from app.scodoc.sco_utils import (
CONFIG, CONFIG,
SCO_ENCODING,
SCODOC_LOGOS_DIR, SCODOC_LOGOS_DIR,
LOGOS_IMAGES_ALLOWED_TYPES, LOGOS_IMAGES_ALLOWED_TYPES,
) )
@ -78,13 +73,15 @@ DEFAULT_PDF_FOOTER_TEMPLATE = CONFIG.DEFAULT_PDF_FOOTER_TEMPLATE
def SU(s): def SU(s):
"convert s from string to string suitable for ReportLab" "convert s from string to string suitable for ReportLab"
# A priori inutile en Python 3, mais tester les "combining accents" if not s:
return s or "" return ""
else:
# Remplace caractères composés # Remplace caractères composés
# eg 'e\xcc\x81' COMBINING ACUTE ACCENT par '\xc3\xa9' LATIN SMALL LETTER E WITH ACUTE # eg 'e\xcc\x81' COMBINING ACUTE ACCENT par '\xc3\xa9' LATIN SMALL LETTER E WITH ACUTE
# car les "combining accents" ne sont pas traités par ReportLab mais peuvent # car les "combining accents" ne sont pas traités par ReportLab mais peuvent
# nous être envoyés par certains navigateurs ou imports # nous être envoyés par certains navigateurs ou imports
# return unicodedata.normalize("NFC", s) # (on en a dans les bases de données)
return unicodedata.normalize("NFC", s)
def _splitPara(txt): def _splitPara(txt):
@ -189,7 +186,10 @@ class ScolarsPageTemplate(PageTemplate):
self.server_name = server_name self.server_name = server_name
self.filigranne = filigranne self.filigranne = filigranne
self.footer_template = footer_template self.footer_template = footer_template
if self.preferences:
self.with_page_background = self.preferences["bul_pdf_with_background"] self.with_page_background = self.preferences["bul_pdf_with_background"]
else:
self.with_page_background = False
self.background_image_filename = None self.background_image_filename = None
# Our doc is made of a single frame # Our doc is made of a single frame
left, top, right, bottom = [float(x) for x in margins] left, top, right, bottom = [float(x) for x in margins]
@ -229,6 +229,8 @@ class ScolarsPageTemplate(PageTemplate):
server_url: URL du serveur ScoDoc server_url: URL du serveur ScoDoc
""" """
if not self.preferences:
return
canvas.saveState() canvas.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:
@ -308,7 +310,7 @@ def pdf_basic_page(
adding a title if specified. adding a title if specified.
""" """
StyleSheet = styles.getSampleStyleSheet() StyleSheet = styles.getSampleStyleSheet()
report = StringIO.StringIO() # in-memory document, no disk file report = io.BytesIO() # in-memory document, no disk file
document = BaseDocTemplate(report) document = BaseDocTemplate(report)
document.addPageTemplates( document.addPageTemplates(
ScolarsPageTemplate( ScolarsPageTemplate(

View File

@ -51,10 +51,7 @@ import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
import traceback import traceback
from PIL import Image as PILImage from PIL import Image as PILImage
try: from io import StringIO
from io import StringIO # for Python 3
except ImportError:
from cStringIO import StringIO # for Python 2
import glob import glob
from flask import request from flask import request

View File

@ -28,10 +28,7 @@
"""Photos: trombinoscopes """Photos: trombinoscopes
""" """
try: from io import StringIO
from io import StringIO # for Python 3
except ImportError:
from cStringIO import StringIO # for Python 2
from zipfile import ZipFile, BadZipfile from zipfile import ZipFile, BadZipfile
import reportlab import reportlab
from reportlab.lib.units import cm, mm from reportlab.lib.units import cm, mm

View File

@ -30,10 +30,7 @@
Modification Jérome Billoue,Vincent Grimaud, IUT de Tours, 2017 Modification Jérome Billoue,Vincent Grimaud, IUT de Tours, 2017
""" """
try: from io import StringIO
from io import StringIO # for Python 3
except ImportError:
from cStringIO import StringIO # for Python 2
from reportlab.lib import colors from reportlab.lib import colors
from reportlab.lib import pagesizes from reportlab.lib import pagesizes

View File

@ -35,10 +35,7 @@ import sys
import time import time
# StringIO => io.StringIO or io.BytesIO for text and data respectively. #py3 # StringIO => io.StringIO or io.BytesIO for text and data respectively. #py3
try: from io import StringIO
from io import StringIO # for Python 3
except ImportError:
from cStringIO import StringIO # for Python 2
from zipfile import ZipFile from zipfile import ZipFile
import psycopg2 import psycopg2

View File

@ -24,13 +24,14 @@ import app.utils as utils
from config import Config from config import Config
app = create_app() app = create_app()
cli.register(app) cli.register(app)
@app.shell_context_processor @app.shell_context_processor
def make_shell_context(): def make_shell_context():
from app.scodoc import notesdb as ndb
return { return {
"db": db, "db": db,
"User": User, "User": User,
@ -38,6 +39,7 @@ def make_shell_context():
"UserRole": UserRole, "UserRole": UserRole,
"notes": notes, "notes": notes,
"scolar": scolar, "scolar": scolar,
"ndb": ndb,
"pp": pp, "pp": pp,
"flask": flask, "flask": flask,
"current_app": flask.current_app, "current_app": flask.current_app,