diff options
author | Magnus Hagander | 2023-06-02 15:37:42 +0000 |
---|---|---|
committer | Magnus Hagander | 2023-06-02 15:37:42 +0000 |
commit | 01214a785959878f6d7dd835347819dbaa888ac1 (patch) | |
tree | 38337993b0bb5f4ad1ecab8587bec1d2af0697b0 /postgresqleu/digisign/pdfutil.py | |
parent | 5a8a7681352a19fa81a97ff01f0ad87b1c36231d (diff) |
Add support for digital signature providers
This adds a new type of provider to the system for handling digital
signatures.
Initially the only consumer is conference sponsorships, but it could be
added for other parts of the system as well in the future. Regular
"old-style" sponsorship contracts are still supported, but will gain the
feature to auto-fill sponsor name and VAT number if wanted. The sponsor
signup workflow is adjusted to support either one or both of the two
methods.
Initially the only implementation is Signwell, but the system is made
pluggable just like e.g. the payment providers, so other suppliers can
be added in the future.
This should be considered fairly beta at this point, as several parts of
it cannot be fully tested until a production account is in place. But
the basics are there...
Diffstat (limited to 'postgresqleu/digisign/pdfutil.py')
-rw-r--r-- | postgresqleu/digisign/pdfutil.py | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/postgresqleu/digisign/pdfutil.py b/postgresqleu/digisign/pdfutil.py new file mode 100644 index 00000000..421838cc --- /dev/null +++ b/postgresqleu/digisign/pdfutil.py @@ -0,0 +1,71 @@ +import io +import itertools + +from reportlab.pdfgen.canvas import Canvas + +from postgresqleu.util.reporttools import cm + + +def fill_pdf_fields(pdf, available_fields, fielddata): + import fitz + + pagefields = {int(k): list(v) for k, v in itertools.groupby(fielddata['fields'], lambda x: x['page'])} + + pdf = fitz.open('pdf', bytes(pdf)) + for pagenum, page in enumerate(pdf.pages()): + if pagenum in pagefields: + for f in pagefields[pagenum]: + # Location in the json is top-left corner, but we want bottom-left for the + # PDF. So we add the size of the font in points, which is turned into pixels + # by multiplying by 96/72. + p = fitz.Point( + f['x'], + f['y'] + fielddata['fontsize'] * 96 / 72, + ) + + # Preview with the field title + txt = None + for fieldname, fieldtext in available_fields: + if not fieldname.startswith('static:'): + break + if fieldname == f['field']: + txt = fieldtext + break + else: + txt = "" + + if txt: + page.insertText(p, txt, fontname='Courier-Bold', fontsize=fielddata['fontsize']) + + return pdf.write() + + +def pdf_watermark_preview(pdfdata): + try: + import fitz + except ImportError: + # Just return without watermark + return pdfdata + + wmio = io.BytesIO() + wmcanvas = Canvas(wmio) + wmcanvas.rotate(45) + for y in -5, 0, 5, 10, 15: + t = wmcanvas.beginText() + t.setTextOrigin(cm(6), cm(y)) + t.setFont("Times-Roman", 100) + t.setFillColorRGB(0.9, 0.9, 0.9) + t.textLine("PREVIEW PREVIEW") + wmcanvas.drawText(t) + wmcanvas.rotate(-45) + wmcanvas.save() + + wmio.seek(0) + wmpdf = fitz.open('pdf', wmio) + wmpixmap = next(wmpdf.pages()).getPixmap() + + pdf = fitz.open('pdf', pdfdata) + for pagenum, page in enumerate(pdf.pages()): + page.insertImage(page.bound(), pixmap=wmpixmap, overlay=False) + + return pdf.write() |