Files
pretix_original/src/pretix/plugins/ticketoutputpdf/ticketoutput.py
2017-05-02 17:07:09 +02:00

208 lines
9.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import copy
import logging
from collections import OrderedDict
from io import BytesIO
from django import forms
from django.contrib.staticfiles import finders
from django.core.files import File
from django.core.files.storage import default_storage
from django.utils.translation import ugettext_lazy as _
from pretix.base.models import Order
from pretix.base.ticketoutput import BaseTicketOutput
from pretix.control.forms import ExtFileField
logger = logging.getLogger('pretix.plugins.ticketoutputpdf')
class PdfTicketOutput(BaseTicketOutput):
identifier = 'pdf'
verbose_name = _('PDF output')
download_button_text = _('PDF')
def _draw_page(self, p, op, order):
from reportlab.graphics.shapes import Drawing
from reportlab.lib import units
from reportlab.graphics.barcode.qr import QrCodeWidget
from reportlab.graphics import renderPDF
event_s = self.settings.get('event_s', default=22, as_type=float)
if event_s:
p.setFont("Helvetica", event_s)
event_x = self.settings.get('event_x', default=15, as_type=float)
event_y = self.settings.get('event_y', default=235, as_type=float)
p.drawString(event_x * units.mm, event_y * units.mm, str(self.event.name))
order_s = self.settings.get('order_s', default=17, as_type=float)
if order_s:
p.setFont("Helvetica", order_s)
order_x = self.settings.get('order_x', default=15, as_type=float)
order_y = self.settings.get('order_y', default=220, as_type=float)
p.drawString(order_x * units.mm, order_y * units.mm, _('Order code: {code}').format(code=order.code))
name_s = self.settings.get('name_s', default=17, as_type=float)
if name_s:
p.setFont("Helvetica", name_s)
name_x = self.settings.get('name_x', default=15, as_type=float)
name_y = self.settings.get('name_y', default=210, as_type=float)
item = str(op.item.name)
if op.variation:
item += " " + str(op.variation)
p.drawString(name_x * units.mm, name_y * units.mm, item)
price_s = self.settings.get('price_s', default=17, as_type=float)
if price_s:
p.setFont("Helvetica", price_s)
price_x = self.settings.get('price_x', default=15, as_type=float)
price_y = self.settings.get('price_y', default=200, as_type=float)
p.drawString(price_x * units.mm, price_y * units.mm, "%s %s" % (str(op.price), self.event.currency))
qr_s = self.settings.get('qr_s', default=80, as_type=float)
if qr_s:
reqs = qr_s * units.mm
qrw = QrCodeWidget(op.secret, barLevel='H')
b = qrw.getBounds()
w = b[2] - b[0]
h = b[3] - b[1]
d = Drawing(reqs, reqs, transform=[reqs / w, 0, 0, reqs / h, 0, 0])
d.add(qrw)
qr_x = self.settings.get('qr_x', default=10, as_type=float)
qr_y = self.settings.get('qr_y', default=120, as_type=float)
renderPDF.draw(d, p, qr_x * units.mm, qr_y * units.mm)
code_s = self.settings.get('code_s', default=11, as_type=float)
if code_s:
p.setFont("Helvetica", code_s)
code_x = self.settings.get('code_x', default=15, as_type=float)
code_y = self.settings.get('code_y', default=120, as_type=float)
p.drawString(code_x * units.mm, code_y * units.mm, op.secret)
attendee_s = self.settings.get('attendee_s', default=0, as_type=float)
if attendee_s and op.attendee_name:
p.setFont("Helvetica", attendee_s)
attendee_x = self.settings.get('attendee_x', default=15, as_type=float)
attendee_y = self.settings.get('attendee_y', default=90, as_type=float)
p.drawString(attendee_x * units.mm, attendee_y * units.mm, op.attendee_name)
p.showPage()
def generate_order(self, order: Order):
buffer = BytesIO()
p = self._create_canvas(buffer)
for op in order.positions.all():
if op.addon_to_id and not self.event.settings.ticket_download_addons:
continue
self._draw_page(p, op, order)
p.save()
outbuffer = self._render_with_background(buffer)
return 'order%s%s.pdf' % (self.event.slug, order.code), 'application/pdf', outbuffer.read()
def generate(self, op):
buffer = BytesIO()
p = self._create_canvas(buffer)
order = op.order
self._draw_page(p, op, order)
p.save()
outbuffer = self._render_with_background(buffer)
return 'order%s%s.pdf' % (self.event.slug, order.code), 'application/pdf', outbuffer.read()
def _create_canvas(self, buffer):
from reportlab.pdfgen import canvas
from reportlab.lib import pagesizes
pagesize = self.settings.get('pagesize', default='A4')
if hasattr(pagesizes, pagesize):
pagesize = getattr(pagesizes, pagesize)
else:
pagesize = pagesizes.A4
orientation = self.settings.get('orientation', default='portrait')
if hasattr(pagesizes, orientation):
pagesize = getattr(pagesizes, orientation)(pagesize)
return canvas.Canvas(buffer, pagesize=pagesize)
def _render_with_background(self, buffer):
from PyPDF2 import PdfFileWriter, PdfFileReader
buffer.seek(0)
new_pdf = PdfFileReader(buffer)
output = PdfFileWriter()
bg_file = self.settings.get('background', as_type=File)
if isinstance(bg_file, File):
bgf = default_storage.open(bg_file.name, "rb")
else:
bgf = open(finders.find('pretixpresale/pdf/ticket_default_a4.pdf'), "rb")
bg_pdf = PdfFileReader(bgf)
for page in new_pdf.pages:
bg_page = copy.copy(bg_pdf.getPage(0))
bg_page.mergePage(page)
output.addPage(bg_page)
outbuffer = BytesIO()
output.write(outbuffer)
outbuffer.seek(0)
return outbuffer
@property
def settings_form_fields(self) -> dict:
return OrderedDict(
list(super().settings_form_fields.items()) + [
('paper_size',
forms.ChoiceField(
label=_('Paper size'),
choices=(
('A4', 'A4'),
('A5', 'A5'),
('B4', 'B4'),
('B5', 'B5'),
('letter', 'Letter'),
('legal', 'Legal'),
),
required=False
)),
('orientation',
forms.ChoiceField(
label=_('Paper orientation'),
choices=(
('portrait', _('Portrait')),
('landscape', _('Landscape')),
),
required=False
)),
('background',
ExtFileField(
label=_('Background PDF'),
ext_whitelist=(".pdf", ),
required=False
)),
('qr_x', forms.FloatField(label=_('QR-Code x position (mm)'), required=False)),
('qr_y', forms.FloatField(label=_('QR-Code y position (mm)'), required=False)),
('qr_s', forms.FloatField(label=_('QR-Code size (mm)'), required=False)),
('code_x', forms.FloatField(label=_('Ticket code x position (mm)'), required=False)),
('code_y', forms.FloatField(label=_('Ticket code y position (mm)'), required=False)),
('code_s', forms.FloatField(label=_('Ticket code size (mm)'), required=False,
help_text=_('Visible by default, set this to 0 to hide the element.'))),
('order_x', forms.FloatField(label=_('Order x position (mm)'), required=False)),
('order_y', forms.FloatField(label=_('Order y position (mm)'), required=False)),
('order_s', forms.FloatField(label=_('Order size (mm)'), required=False,
help_text=_('Visible by default, set this to 0 to hide the element.'))),
('name_x', forms.FloatField(label=_('Product name x position (mm)'), required=False)),
('name_y', forms.FloatField(label=_('Product name y position (mm)'), required=False)),
('name_s', forms.FloatField(label=_('Product name size (mm)'), required=False,
help_text=_('Visible by default, set this to 0 to hide the element.'))),
('price_x', forms.FloatField(label=_('Price x position (mm)'), required=False)),
('price_y', forms.FloatField(label=_('Price y position (mm)'), required=False)),
('price_s', forms.FloatField(label=_('Price size (mm)'), required=False,
help_text=_('Visible by default, set this to 0 to hide the element.'))),
('event_x', forms.FloatField(label=_('Event name x position (mm)'), required=False)),
('event_y', forms.FloatField(label=_('Event name y position (mm)'), required=False)),
('event_s', forms.FloatField(label=_('Event name size (mm)'), required=False,
help_text=_('Visible by default, set this to 0 to hide the element.'))),
('attendee_x', forms.FloatField(label=_('Attendee name x position (mm)'), required=False)),
('attendee_y', forms.FloatField(label=_('Attendee name y position (mm)'), required=False)),
('attendee_s', forms.FloatField(label=_('Attendee name size (mm)'), required=False,
help_text=_('Invisible by default, set this to a number greater than 0 '
'to show.')))
]
)