summaryrefslogtreecommitdiff
path: root/postgresqleu/digisign/pdfutil.py
diff options
context:
space:
mode:
authorMagnus Hagander2023-06-02 15:37:42 +0000
committerMagnus Hagander2023-06-02 15:37:42 +0000
commit01214a785959878f6d7dd835347819dbaa888ac1 (patch)
tree38337993b0bb5f4ad1ecab8587bec1d2af0697b0 /postgresqleu/digisign/pdfutil.py
parent5a8a7681352a19fa81a97ff01f0ad87b1c36231d (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.py71
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()