mirror of
https://github.com/pretix/pretix.git
synced 2026-05-11 16:13:59 +00:00
Add support for PDFTK
This commit is contained in:
@@ -295,5 +295,13 @@ various places like order codes, secrets in the ticket QR codes, etc. Example::
|
|||||||
; Voucher code needs to be < 255 characters, default is 16
|
; Voucher code needs to be < 255 characters, default is 16
|
||||||
voucher_code=16
|
voucher_code=16
|
||||||
|
|
||||||
|
External tools
|
||||||
|
--------------
|
||||||
|
|
||||||
|
pretix can make use of some external tools if they are installed. Currently, they are all optional. Example::
|
||||||
|
|
||||||
|
[tools]
|
||||||
|
pdftk=/usr/bin/pdftk
|
||||||
|
|
||||||
.. _Python documentation: https://docs.python.org/3/library/configparser.html?highlight=configparser#supported-ini-file-structure
|
.. _Python documentation: https://docs.python.org/3/library/configparser.html?highlight=configparser#supported-ini-file-structure
|
||||||
.. _Celery documentation: http://docs.celeryproject.org/en/latest/userguide/configuration.html
|
.. _Celery documentation: http://docs.celeryproject.org/en/latest/userguide/configuration.html
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
import copy
|
import copy
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
import uuid
|
import uuid
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import bleach
|
import bleach
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.staticfiles import finders
|
from django.contrib.staticfiles import finders
|
||||||
from django.utils.formats import date_format
|
from django.utils.formats import date_format
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
@@ -222,10 +226,11 @@ class Renderer:
|
|||||||
self.layout = layout
|
self.layout = layout
|
||||||
self.background_file = background_file
|
self.background_file = background_file
|
||||||
self.variables = get_variables(event)
|
self.variables = get_variables(event)
|
||||||
if self.background_file:
|
if not settings.PDFTK:
|
||||||
self.bg_pdf = PdfFileReader(BytesIO(self.background_file.read()), strict=False)
|
if self.background_file:
|
||||||
else:
|
self.bg_pdf = PdfFileReader(BytesIO(self.background_file.read()), strict=False)
|
||||||
self.bg_pdf = None
|
else:
|
||||||
|
self.bg_pdf = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _register_fonts(cls):
|
def _register_fonts(cls):
|
||||||
@@ -340,21 +345,40 @@ class Renderer:
|
|||||||
canvas.showPage()
|
canvas.showPage()
|
||||||
|
|
||||||
def render_background(self, buffer, title=_('Ticket')):
|
def render_background(self, buffer, title=_('Ticket')):
|
||||||
from PyPDF2 import PdfFileWriter, PdfFileReader
|
if settings.PDFTK:
|
||||||
buffer.seek(0)
|
buffer.seek(0)
|
||||||
new_pdf = PdfFileReader(buffer)
|
with tempfile.TemporaryDirectory() as d:
|
||||||
output = PdfFileWriter()
|
with open(os.path.join(d, 'back.pdf'), 'wb') as f:
|
||||||
|
f.write(self.background_file.read())
|
||||||
|
with open(os.path.join(d, 'front.pdf'), 'wb') as f:
|
||||||
|
f.write(buffer.read())
|
||||||
|
subprocess.run([
|
||||||
|
settings.PDFTK,
|
||||||
|
os.path.join(d, 'front.pdf'),
|
||||||
|
'multistamp',
|
||||||
|
os.path.join(d, 'back.pdf'),
|
||||||
|
'output',
|
||||||
|
os.path.join(d, 'out.pdf'),
|
||||||
|
'compress'
|
||||||
|
], check=True)
|
||||||
|
with open(os.path.join(d, 'out.pdf'), 'rb') as f:
|
||||||
|
return BytesIO(f.read())
|
||||||
|
else:
|
||||||
|
from PyPDF2 import PdfFileWriter, PdfFileReader
|
||||||
|
buffer.seek(0)
|
||||||
|
new_pdf = PdfFileReader(buffer)
|
||||||
|
output = PdfFileWriter()
|
||||||
|
|
||||||
for page in new_pdf.pages:
|
for page in new_pdf.pages:
|
||||||
bg_page = copy.copy(self.bg_pdf.getPage(0))
|
bg_page = copy.copy(self.bg_pdf.getPage(0))
|
||||||
bg_page.mergePage(page)
|
bg_page.mergePage(page)
|
||||||
output.addPage(bg_page)
|
output.addPage(bg_page)
|
||||||
|
|
||||||
output.addMetadata({
|
output.addMetadata({
|
||||||
'/Title': str(title),
|
'/Title': str(title),
|
||||||
'/Creator': 'pretix',
|
'/Creator': 'pretix',
|
||||||
})
|
})
|
||||||
outbuffer = BytesIO()
|
outbuffer = BytesIO()
|
||||||
output.write(outbuffer)
|
output.write(outbuffer)
|
||||||
outbuffer.seek(0)
|
outbuffer.seek(0)
|
||||||
return outbuffer
|
return outbuffer
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ else:
|
|||||||
debug_fallback = "runserver" in sys.argv
|
debug_fallback = "runserver" in sys.argv
|
||||||
DEBUG = config.getboolean('django', 'debug', fallback=debug_fallback)
|
DEBUG = config.getboolean('django', 'debug', fallback=debug_fallback)
|
||||||
|
|
||||||
|
PDFTK = config.get('tools', 'pdftk', fallback=None)
|
||||||
|
|
||||||
db_backend = config.get('database', 'backend', fallback='sqlite3')
|
db_backend = config.get('database', 'backend', fallback='sqlite3')
|
||||||
if db_backend == 'postgresql_psycopg2':
|
if db_backend == 'postgresql_psycopg2':
|
||||||
db_backend = 'postgresql'
|
db_backend = 'postgresql'
|
||||||
|
|||||||
Reference in New Issue
Block a user