Beispiel #1
0
    def get(self, request, *args, **kwargs):
        if not self.output or not self.output.is_enabled:
            messages.error(request, _("You requested an invalid ticket output type."))
            return redirect(self.get_order_url())
        if not self.order:
            raise Http404(_("Unknown order code or not authorized to access this order."))
        if self.order.status != Order.STATUS_PAID:
            messages.error(request, _("Order is not paid."))
            return redirect(self.get_order_url())
        if not self.request.event.settings.ticket_download or (
            self.request.event.settings.ticket_download_date is not None
            and now() < self.request.event.settings.ticket_download_date
        ):
            messages.error(request, _("Ticket download is not (yet) enabled."))
            return redirect(self.get_order_url())

        try:
            ct = CachedTicket.objects.get(order=self.order, provider=self.output.identifier)
        except CachedTicket.DoesNotExist:
            ct = CachedTicket(order=self.order, provider=self.output.identifier)
        try:
            ct.cachedfile
        except CachedFile.DoesNotExist:
            cf = CachedFile()
            cf.date = now()
            cf.expires = self.request.event.date_from + timedelta(days=30)
            cf.save()
            ct.cachedfile = cf
        ct.save()
        generate(self.order.id, self.output.identifier)
        return redirect(reverse("cachedfile.download", kwargs={"id": ct.cachedfile.id}))
Beispiel #2
0
    def get(self, request, *args, **kwargs):
        if not self.output or not self.output.is_enabled:
            messages.error(request, _('You requested an invalid ticket output type.'))
            return redirect(self.get_order_url())
        if not self.order or not self.order_position:
            raise Http404(_('Unknown order code or not authorized to access this order.'))
        if self.order.status != Order.STATUS_PAID:
            messages.error(request, _('Order is not paid.'))
            return redirect(self.get_order_url())
        if (not self.request.event.settings.ticket_download
            or (self.request.event.settings.ticket_download_date is not None
                and now() < self.request.event.settings.ticket_download_date)):
            messages.error(request, _('Ticket download is not (yet) enabled.'))
            return redirect(self.get_order_url())

        ct = CachedTicket.objects.get_or_create(
            order_position=self.order_position, provider=self.output.identifier
        )[0]
        if not ct.cachedfile:
            cf = CachedFile()
            cf.date = now()
            cf.expires = self.request.event.date_from + timedelta(days=30)
            cf.save()
            ct.cachedfile = cf
            ct.save()
        generate.apply_async(args=(self.order_position.id, self.output.identifier))
        return redirect(reverse('cachedfile.download', kwargs={'id': ct.cachedfile.id}))
Beispiel #3
0
    def post(self, request, *args, **kwargs):
        if "background" in request.FILES:
            error, fileobj = self.process_upload()
            if error:
                return JsonResponse({
                    "status": "error",
                    "error": error
                })
            c = CachedFile()
            c.expires = now() + timedelta(days=7)
            c.date = now()
            c.filename = 'background_preview.pdf'
            c.type = 'application/pdf'
            c.file = fileobj
            c.save()
            c.refresh_from_db()
            return JsonResponse({
                "status": "ok",
                "id": c.id,
                "url": reverse('control:pdf.background', kwargs={
                    'event': request.event.slug,
                    'organizer': request.organizer.slug,
                    'filename': str(c.id)
                })
            })

        cf = None
        if request.POST.get("background", "").strip():
            try:
                cf = CachedFile.objects.get(id=request.POST.get("background"))
            except CachedFile.DoesNotExist:
                pass

        if "preview" in request.POST:
            with rolledback_transaction(), language(request.event.settings.locale):
                p = self._get_preview_position()
                fname, mimet, data = self.generate(
                    p,
                    override_layout=(json.loads(self.request.POST.get("data"))
                                     if self.request.POST.get("data") else None),
                    override_background=cf.file if cf else None
                )

            resp = HttpResponse(data, content_type=mimet)
            ftype = fname.split(".")[-1]
            resp['Content-Disposition'] = 'attachment; filename="ticket-preview.{}"'.format(ftype)
            return resp
        elif "data" in request.POST:
            if cf:
                self.save_background(cf)
            self.save_layout()
            return JsonResponse({'status': 'ok'})
        return HttpResponseBadRequest()
Beispiel #4
0
def export(event: Event, shredders: List[str], session_key=None) -> None:
    known_shredders = event.get_data_shredders()

    with NamedTemporaryFile() as rawfile:
        with ZipFile(rawfile, 'w') as zipfile:
            ccode = get_random_string(6)
            zipfile.writestr(
                'CONFIRM_CODE.txt',
                ccode,
            )
            zipfile.writestr(
                'index.json',
                json.dumps(
                    {
                        'instance': settings.SITE_URL,
                        'organizer': event.organizer.slug,
                        'event': event.slug,
                        'time': now().isoformat(),
                        'shredders': shredders,
                        'confirm_code': ccode
                    },
                    indent=4))
            for s in shredders:
                shredder = known_shredders.get(s)
                if not shredder:
                    continue

                it = shredder.generate_files()
                if not it:
                    continue
                for fname, ftype, content in it:
                    zipfile.writestr(fname, content)

        rawfile.seek(0)

        cf = CachedFile()
        cf.date = now()
        cf.filename = event.slug + '.zip'
        cf.type = 'application/zip'
        cf.session_key = session_key
        cf.web_download = True
        cf.expires = now() + timedelta(hours=1)
        cf.save()
        cf.file.save(cachedfile_name(cf, cf.filename), rawfile)

    return cf.pk
Beispiel #5
0
    def post(self, *args, **kwargs):
        if not self.exporter:
            messages.error(self.request, _('The selected exporter was not found.'))
            return redirect('control:event.orders.export', kwargs={
                'event': self.request.event.slug,
                'organizer': self.request.event.organizer.slug
            })
        if not self.exporter.form.is_valid():
            messages.error(self.request, _('There was a problem processing your input. See below for error details.'))
            return self.get(*args, **kwargs)

        cf = CachedFile()
        cf.date = now()
        cf.expires = now() + timedelta(days=3)
        cf.save()
        export(self.request.event.id, str(cf.id), self.exporter.identifier, self.exporter.form.cleaned_data)
        return redirect(reverse('cachedfile.download', kwargs={'id': str(cf.id)}))
Beispiel #6
0
def generate(order, provider):
    order = Order.objects.current.select_related('event').get(identity=order)
    ct = CachedTicket.objects.get_or_create(order=order, provider=provider)[0]
    if not ct.cachedfile:
        cf = CachedFile()
        cf.date = now()
        cf.expires = order.event.date_from + timedelta(days=30)
        cf.save()
        ct.cachedfile = cf
        ct.save()

    responses = register_ticket_outputs.send(order.event)
    for receiver, response in responses:
        prov = response(order.event)
        if prov.identifier == provider:
            ct.cachedfile.filename, ct.cachedfile.type, data = prov.generate(order)
            ct.cachedfile.file.save(cachedfile_name(ct.cachedfile, ct.cachedfile.filename), ContentFile(data))
            ct.cachedfile.save()
Beispiel #7
0
 def test_file_handling(self):
     cf = CachedFile()
     val = SimpleUploadedFile("testfile.txt", b"file_content")
     cf.file.save("testfile.txt", val)
     cf.type = "text/plain"
     cf.filename = "testfile.txt"
     cf.save()
     assert default_storage.exists(cf.file.name)
     with default_storage.open(cf.file.name, 'r') as f:
         assert f.read().strip() == "file_content"
     cf.delete()
     assert not default_storage.exists(cf.file.name)
Beispiel #8
0
    def post(self, *args, **kwargs):
        if not self.exporter:
            messages.error(self.request,
                           _('The selected exporter was not found.'))
            return redirect('control:event.orders.export',
                            kwargs={
                                'event': self.request.event.slug,
                                'organizer': self.request.event.organizer.slug
                            })
        if not self.exporter.form.is_valid():
            messages.error(
                self.request,
                _('There was a problem processing your input. See below for error details.'
                  ))
            return self.get(*args, **kwargs)

        cf = CachedFile()
        cf.date = now()
        cf.expires = now() + timedelta(days=3)
        cf.save()
        export.apply_async(args=(self.request.event.id, str(cf.id),
                                 self.exporter.identifier,
                                 self.exporter.form.cleaned_data))
        return redirect(
            reverse('cachedfile.download', kwargs={'id': str(cf.id)}))
Beispiel #9
0
    def run(self, *args, **kwargs):
        instance = self.get_object()
        serializer = JobRunSerializer(exporter=instance,
                                      data=self.request.data,
                                      **self.get_serializer_kwargs())
        serializer.is_valid(raise_exception=True)

        cf = CachedFile(web_download=False)
        cf.date = now()
        cf.expires = now() + timedelta(hours=24)
        cf.save()
        d = serializer.data
        for k, v in d.items():
            if isinstance(v, set):
                d[k] = list(v)
        async_result = self.do_export(cf, instance, d)

        url_kwargs = {
            'asyncid': str(async_result.id),
            'cfid': str(cf.id),
        }
        url_kwargs.update(self.kwargs)
        return Response(
            {
                'download':
                reverse('api-v1:exporters-download',
                        kwargs=url_kwargs,
                        request=self.request)
            },
            status=status.HTTP_202_ACCEPTED)
Beispiel #10
0
    def get(self, request, *args, **kwargs):
        if not self.output or not self.output.is_enabled:
            messages.error(request, _('You requested an invalid ticket output type.'))
            return redirect(self.get_order_url())
        if not self.order:
            raise Http404(_('Unknown order code or not authorized to access this order.'))
        if self.order.status != Order.STATUS_PAID:
            messages.error(request, _('Order is not paid.'))
            return redirect(self.get_order_url())
        if (not self.request.event.settings.ticket_download
            or (self.request.event.settings.ticket_download_date is not None
                and now() < self.request.event.settings.ticket_download_date)):
            messages.error(request, _('Ticket download is not (yet) enabled.'))
            return redirect(self.get_order_url())

        try:
            ct = CachedTicket.objects.get(order=self.order, provider=self.output.identifier)
        except CachedTicket.DoesNotExist:
            ct = CachedTicket(order=self.order, provider=self.output.identifier)
        try:
            ct.cachedfile
        except CachedFile.DoesNotExist:
            cf = CachedFile()
            cf.date = now()
            cf.expires = self.request.event.date_from + timedelta(days=30)
            cf.save()
            ct.cachedfile = cf
        ct.save()
        generate(self.order.id, self.output.identifier)
        return redirect(reverse('cachedfile.download', kwargs={'id': ct.cachedfile.id}))
Beispiel #11
0
    def get(self, request, *args, **kwargs):
        if not self.output or not self.output.is_enabled:
            messages.error(request,
                           _('You requested an invalid ticket output type.'))
            return redirect(self.get_order_url())
        if self.order.status != Order.STATUS_PAID:
            messages.error(request, _('Order is not paid.'))
            return redirect(self.get_order_url())

        try:
            ct = CachedTicket.objects.get(order=self.order,
                                          provider=self.output.identifier)
        except CachedTicket.DoesNotExist:
            ct = CachedTicket(order=self.order,
                              provider=self.output.identifier)
        try:
            ct.cachedfile
        except CachedFile.DoesNotExist:
            cf = CachedFile()
            cf.date = now()
            cf.expires = self.request.event.date_from + timedelta(days=30)
            cf.save()
            ct.cachedfile = cf
        ct.save()
        if not ct.cachedfile.file.name:
            tickets.generate(self.order.id, self.output.identifier)
        return redirect(
            reverse('cachedfile.download', kwargs={'id': ct.cachedfile.id}))
Beispiel #12
0
 def test_file_handling(self):
     cf = CachedFile()
     val = SimpleUploadedFile("testfile.txt", b"file_content")
     cf.file.save("testfile.txt", val)
     cf.type = "text/plain"
     cf.filename = "testfile.txt"
     cf.save()
     assert default_storage.exists(cf.file.name)
     with default_storage.open(cf.file.name, 'r') as f:
         assert f.read().strip() == "file_content"
     cf.delete()
     assert not default_storage.exists(cf.file.name)
Beispiel #13
0
    def get(self, request, *args, **kwargs):
        if not self.output or not self.output.is_enabled:
            messages.error(request, _('You requested an invalid ticket output type.'))
            return redirect(self.get_order_url())
        if self.order.status != Order.STATUS_PAID:
            messages.error(request, _('Order is not paid.'))
            return redirect(self.get_order_url())

        try:
            ct = CachedTicket.objects.get(order=self.order, provider=self.output.identifier)
        except CachedTicket.DoesNotExist:
            ct = CachedTicket(order=self.order, provider=self.output.identifier)
        try:
            ct.cachedfile
        except CachedFile.DoesNotExist:
            cf = CachedFile()
            cf.date = now()
            cf.expires = self.request.event.date_from + timedelta(days=30)
            cf.save()
            ct.cachedfile = cf
        ct.save()
        generate(self.order.identity, self.output.identifier)
        return redirect(reverse('cachedfile.download', kwargs={'id': ct.cachedfile.id}))
Beispiel #14
0
 def post(self, request, *args, **kwargs):
     order = get_object_or_404(self.request.event.orders, code=request.GET.get("code"))
     cf = CachedFile(web_download=True, session_key=self.request.session.session_key)
     cf.date = now()
     cf.type = 'application/pdf'
     cf.expires = now() + timedelta(days=3)
     if 'position' in request.GET:
         qs = order.positions.filter(pk=request.GET.get('position'))
         positions = [p.pk for p in qs]
         if len(positions) < 5:
             cf.filename = f'badges_{self.request.event.slug}_{order.code}_{"_".join(str(p.positionid) for p in qs)}.pdf'
     else:
         positions = [p.pk for p in order.positions.all()]
         cf.filename = f'badges_{self.request.event.slug}_{order.code}.pdf'
     cf.save()
     return self.do(
         self.request.event.pk,
         str(cf.id),
         positions,
     )
Beispiel #15
0
 def post(self, request, *args, **kwargs):
     order = get_object_or_404(self.request.event.orders,
                               code=request.GET.get("code"))
     cf = CachedFile()
     cf.date = now()
     cf.type = 'application/pdf'
     cf.expires = now() + timedelta(days=3)
     cf.save()
     return self.do(
         str(cf.id),
         self.request.event.pk,
         [order.pk],
     )
Beispiel #16
0
 def post(self, request, *args, **kwargs):
     order = get_object_or_404(self.request.event.orders, code=request.GET.get("code"))
     cf = CachedFile()
     cf.date = now()
     cf.type = 'application/pdf'
     cf.expires = now() + timedelta(days=3)
     cf.save()
     return self.do(
         str(cf.id),
         self.request.event.pk,
         [order.pk],
     )
Beispiel #17
0
 def post(self, request, *args, **kwargs):
     order = get_object_or_404(self.request.event.orders, code=request.GET.get("code"))
     cf = CachedFile(web_download=True, session_key=self.request.session.session_key)
     cf.date = now()
     cf.type = 'application/pdf'
     cf.expires = now() + timedelta(days=3)
     cf.save()
     if 'position' in request.GET:
         positions = [p.pk for p in order.positions.filter(pk=request.GET.get('position'))]
     else:
         positions = [p.pk for p in order.positions.all()]
     return self.do(
         self.request.event.pk,
         str(cf.id),
         positions,
     )
Beispiel #18
0
def export(event: str, shredders: List[str]) -> None:
    event = Event.objects.get(id=event)
    known_shredders = event.get_data_shredders()

    with NamedTemporaryFile() as rawfile:
        with ZipFile(rawfile, 'w') as zipfile:
            ccode = get_random_string(6)
            zipfile.writestr(
                'CONFIRM_CODE.txt',
                ccode,
            )
            zipfile.writestr(
                'index.json',
                json.dumps({
                    'instance': settings.SITE_URL,
                    'organizer': event.organizer.slug,
                    'event': event.slug,
                    'time': now().isoformat(),
                    'shredders': shredders,
                    'confirm_code': ccode
                }, indent=4)
            )
            for s in shredders:
                shredder = known_shredders.get(s)
                if not shredder:
                    continue

                it = shredder.generate_files()
                if not it:
                    continue
                for fname, ftype, content in it:
                    zipfile.writestr(fname, content)

        rawfile.seek(0)

        cf = CachedFile()
        cf.date = now()
        cf.filename = event.slug + '.zip'
        cf.type = 'application/pdf'
        cf.expires = now() + timedelta(hours=1)
        cf.save()
        cf.file.save(cachedfile_name(cf, cf.filename), rawfile)

    return cf.pk
Beispiel #19
0
 def post(self, request, *args, **kwargs):
     order = get_object_or_404(self.request.event.orders, code=request.GET.get("code"))
     cf = CachedFile()
     cf.date = now()
     cf.type = 'application/pdf'
     cf.expires = now() + timedelta(days=3)
     cf.save()
     if 'position' in request.GET:
         positions = [p.pk for p in order.positions.filter(pk=request.GET.get('position'))]
     else:
         positions = [p.pk for p in order.positions.all()]
     return self.do(
         str(cf.id),
         self.request.event.pk,
         positions,
     )
Beispiel #20
0
def generate(order: str, provider: str):
    order = Order.objects.select_related('event').get(id=order)
    ct = CachedTicket.objects.get_or_create(order=order, provider=provider)[0]
    if not ct.cachedfile:
        cf = CachedFile()
        cf.date = now()
        cf.expires = order.event.date_from + timedelta(days=30)
        cf.save()
        ct.cachedfile = cf
        ct.save()

    responses = register_ticket_outputs.send(order.event)
    for receiver, response in responses:
        prov = response(order.event)
        if prov.identifier == provider:
            ct.cachedfile.filename, ct.cachedfile.type, data = prov.generate(order)
            ct.cachedfile.file.save(cachedfile_name(ct.cachedfile, ct.cachedfile.filename), ContentFile(data))
            ct.cachedfile.save()
Beispiel #21
0
    def post(self, request, *args, **kwargs):
        if "emptybackground" in request.POST:
            p = PdfFileWriter()
            try:
                p.addBlankPage(
                    width=float(request.POST.get('width')) * mm,
                    height=float(request.POST.get('height')) * mm,
                )
            except ValueError:
                return JsonResponse({
                    "status": "error",
                    "error": "Invalid height/width given."
                })
            buffer = BytesIO()
            p.write(buffer)
            buffer.seek(0)
            c = CachedFile()
            c.expires = now() + timedelta(days=7)
            c.date = now()
            c.filename = 'background_preview.pdf'
            c.type = 'application/pdf'
            c.save()
            c.file.save('empty.pdf', ContentFile(buffer.read()))
            c.refresh_from_db()
            return JsonResponse({
                "status":
                "ok",
                "id":
                c.id,
                "url":
                reverse('control:pdf.background',
                        kwargs={
                            'event': request.event.slug,
                            'organizer': request.organizer.slug,
                            'filename': str(c.id)
                        })
            })

        if "background" in request.FILES:
            error, fileobj = self.process_upload()
            if error:
                return JsonResponse({"status": "error", "error": error})
            c = CachedFile()
            c.expires = now() + timedelta(days=7)
            c.date = now()
            c.filename = 'background_preview.pdf'
            c.type = 'application/pdf'
            c.file = fileobj
            c.save()
            c.refresh_from_db()
            return JsonResponse({
                "status":
                "ok",
                "id":
                c.id,
                "url":
                reverse('control:pdf.background',
                        kwargs={
                            'event': request.event.slug,
                            'organizer': request.organizer.slug,
                            'filename': str(c.id)
                        })
            })

        cf = None
        if request.POST.get("background", "").strip():
            try:
                cf = CachedFile.objects.get(id=request.POST.get("background"))
            except CachedFile.DoesNotExist:
                pass

        if "preview" in request.POST:
            with rolledback_transaction(), language(
                    request.event.settings.locale):
                p = self._get_preview_position()
                fname, mimet, data = self.generate(
                    p,
                    override_layout=(json.loads(self.request.POST.get("data"))
                                     if self.request.POST.get("data") else
                                     None),
                    override_background=cf.file if cf else None)

            resp = HttpResponse(data, content_type=mimet)
            ftype = fname.split(".")[-1]
            resp[
                'Content-Disposition'] = 'attachment; filename="ticket-preview.{}"'.format(
                    ftype)
            return resp
        elif "data" in request.POST:
            if cf:
                self.save_background(cf)
            self.save_layout()
            return JsonResponse({'status': 'ok'})
        return HttpResponseBadRequest()
Beispiel #22
0
    def post(self, request, *args, **kwargs):
        if "background" in request.FILES:
            error, fileobj = self.process_upload()
            if error:
                return JsonResponse({"status": "error", "error": error})
            c = CachedFile()
            c.expires = now() + timedelta(days=7)
            c.date = now()
            c.filename = 'background_preview.pdf'
            c.type = 'application/pdf'
            c.file = fileobj
            c.save()
            c.refresh_from_db()
            return JsonResponse({
                "status":
                "ok",
                "id":
                c.id,
                "url":
                reverse('plugins:ticketoutputpdf:pdf',
                        kwargs={
                            'event': request.event.slug,
                            'organizer': request.organizer.slug,
                            'filename': str(c.id)
                        })
            })

        cf = None
        if request.POST.get("background", "").strip():
            try:
                cf = CachedFile.objects.get(id=request.POST.get("background"))
            except CachedFile.DoesNotExist:
                pass

        if "preview" in request.POST:
            with rolledback_transaction(), language(
                    request.event.settings.locale):
                p = self._get_preview_position()

                prov = self.get_output(
                    override_layout=(json.loads(request.POST.get("data"))
                                     if request.POST.get("data") else None),
                    override_background=cf.file if cf else None)
                fname, mimet, data = prov.generate(p)

            resp = HttpResponse(data, content_type=mimet)
            ftype = fname.split(".")[-1]
            resp[
                'Content-Disposition'] = 'attachment; filename="ticket-preview.{}"'.format(
                    ftype)
            return resp
        elif "data" in request.POST:
            if cf:
                fexisting = request.event.settings.get(
                    'ticketoutput_{}_layout'.format(self.identifier),
                    as_type=File)
                if fexisting:
                    try:
                        default_storage.delete(fexisting.name)
                    except OSError:  # pragma: no cover
                        logger.error('Deleting file %s failed.' %
                                     fexisting.name)

                # Create new file
                nonce = get_random_string(length=8)
                fname = '%s-%s/%s/%s.%s.%s' % (
                    'event', 'settings', self.request.event.pk,
                    'ticketoutput_{}_layout'.format(
                        self.identifier), nonce, 'pdf')
                newname = default_storage.save(fname, cf.file)
                request.event.settings.set(
                    'ticketoutput_{}_background'.format(self.identifier),
                    'file://' + newname)

            request.event.settings.set(
                'ticketoutput_{}_layout'.format(self.identifier),
                request.POST.get("data"))

            CachedTicket.objects.filter(
                order_position__order__event=self.request.event,
                provider=self.identifier).delete()
            CachedCombinedTicket.objects.filter(
                order__event=self.request.event,
                provider=self.identifier).delete()

            return JsonResponse({'status': 'ok'})
        return HttpResponseBadRequest()
Beispiel #23
0
    def post(self, request, *args, **kwargs):
        if "background" in request.FILES:
            error, fileobj = self.process_upload()
            if error:
                return JsonResponse({
                    "status": "error",
                    "error": error
                })
            c = CachedFile()
            c.expires = now() + timedelta(days=7)
            c.date = now()
            c.filename = 'background_preview.pdf'
            c.type = 'application/pdf'
            c.file = fileobj
            c.save()
            c.refresh_from_db()
            return JsonResponse({
                "status": "ok",
                "id": c.id,
                "url": reverse('plugins:ticketoutputpdf:pdf', kwargs={
                    'event': request.event.slug,
                    'organizer': request.organizer.slug,
                    'filename': str(c.id)
                })
            })

        cf = None
        if request.POST.get("background", "").strip():
            try:
                cf = CachedFile.objects.get(id=request.POST.get("background"))
            except CachedFile.DoesNotExist:
                pass

        if "preview" in request.POST:
            with rolledback_transaction(), language(request.event.settings.locale):
                item = request.event.items.create(name=_("Sample product"), default_price=42.23)
                item2 = request.event.items.create(name=_("Sample workshop"), default_price=23.40)

                from pretix.base.models import Order
                order = request.event.orders.create(status=Order.STATUS_PENDING, datetime=now(),
                                                    email='*****@*****.**',
                                                    expires=now(), code="PREVIEW1234", total=119)

                p = order.positions.create(item=item, attendee_name=_("John Doe"), price=item.default_price)
                order.positions.create(item=item2, attendee_name=_("John Doe"), price=item.default_price, addon_to=p)
                order.positions.create(item=item2, attendee_name=_("John Doe"), price=item.default_price, addon_to=p)

                prov = PdfTicketOutput(request.event,
                                       override_layout=(json.loads(request.POST.get("data"))
                                                        if request.POST.get("data") else None),
                                       override_background=cf.file if cf else None)
                fname, mimet, data = prov.generate(p)

            resp = HttpResponse(data, content_type=mimet)
            ftype = fname.split(".")[-1]
            resp['Content-Disposition'] = 'attachment; filename="ticket-preview.{}"'.format(ftype)
            return resp
        elif "data" in request.POST:
            if cf:
                fexisting = request.event.settings.get('ticketoutput_pdf_layout', as_type=File)
                if fexisting:
                    try:
                        default_storage.delete(fexisting.name)
                    except OSError:  # pragma: no cover
                        logger.error('Deleting file %s failed.' % fexisting.name)

                # Create new file
                nonce = get_random_string(length=8)
                fname = '%s-%s/%s/%s.%s.%s' % (
                    'event', 'settings', self.request.event.pk, 'ticketoutput_pdf_layout', nonce, 'pdf'
                )
                newname = default_storage.save(fname, cf.file)
                request.event.settings.set('ticketoutput_pdf_background', 'file://' + newname)

            request.event.settings.set('ticketoutput_pdf_layout', request.POST.get("data"))
            return JsonResponse({'status': 'ok'})
        return HttpResponseBadRequest()