mirror of
https://github.com/pretix/pretix.git
synced 2026-10-13 21:14:42 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c00cebb724 |
@@ -1,11 +1,27 @@
|
||||
{% extends "pretixcontrol/organizers/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load eventurl %}
|
||||
{% load bootstrap3 %}
|
||||
{% load static %}
|
||||
{% block inner %}
|
||||
<h1>
|
||||
{% blocktrans with name=request.organizer.name %}Organizer: {{ name }}{% endblocktrans %}
|
||||
</h1>
|
||||
<div class="helper-space-below">
|
||||
{% trans "Public profile" %}:
|
||||
<span id="organizer_url" class="text-muted">{% abseventurl request.organizer "presale:organizer.index" %}</span>
|
||||
<button type="button" class="btn btn-default btn-xs btn-clipboard js-only" data-clipboard-target="#organizer_url">
|
||||
<i class="fa fa-clipboard" aria-hidden="true"></i>
|
||||
<span class="sr-only">{% trans "Copy to clipboard" %}</span>
|
||||
</button>
|
||||
<div class="btn-group helper-display-inline-block">
|
||||
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" title="{% trans "Create QR code" %}" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fa fa-qrcode" aria-hidden="true"></i>
|
||||
</button>
|
||||
{% include "pretixcontrol/organizers/fragment_qr_dropdown.html" with url=0 %}
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% if events|length == 0 and not filter_form.filtered %}
|
||||
{% if "organizer.events:create" in request.orgapermset %}
|
||||
<p>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
{% load i18n %}
|
||||
<ul class="dropdown-menu dropdown-menu-right">
|
||||
<li>
|
||||
<a href="{% url "control:organizer.qrcode" organizer=request.organizer.slug filetype="png" %}{% if url %}?url={{ url|urlencode }}{% endif %}"
|
||||
target="_blank" download>
|
||||
{% blocktrans with filetype="PNG" %}Download QR code as {{ filetype }} image{% endblocktrans %}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url "control:organizer.qrcode" organizer=request.organizer.slug filetype="svg" %}{% if url %}?url={{ url|urlencode }}{% endif %}"
|
||||
target="_blank" download>
|
||||
{% blocktrans with filetype="SVG" %}Download QR code as {{ filetype }} image{% endblocktrans %}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url "control:organizer.qrcode" organizer=request.organizer.slug filetype="jpeg" %}{% if url %}?url={{ url|urlencode }}{% endif %}"
|
||||
target="_blank" download>
|
||||
{% blocktrans with filetype="JPG" %}Download QR code as {{ filetype }} image{% endblocktrans %}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url "control:organizer.qrcode" organizer=request.organizer.slug filetype="gif" %}{% if url %}?url={{ url|urlencode }}{% endif %}"
|
||||
target="_blank" download>
|
||||
{% blocktrans with filetype="GIF" %}Download QR code as {{ filetype }} image{% endblocktrans %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -263,6 +263,7 @@ urlpatterns = [
|
||||
name='organizer.export.scheduled.delete'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/ticket_select2$', typeahead.ticket_select2, name='organizer.ticket_select2'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/datasync/failedjobs/$', datasync.OrganizerFailedSyncJobsView.as_view(), name='organizer.datasync.failedjobs'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/qrcode.(?P<filetype>(png|jpeg|gif|svg))$', organizer.OrganizerQRCode.as_view(), name='organizer.qrcode'),
|
||||
re_path(r'^nav/typeahead/$', typeahead.nav_context_list, name='nav.typeahead'),
|
||||
re_path(r'^events/$', main.EventList.as_view(), name='events'),
|
||||
re_path(r'^events/add$', main.EventWizard.as_view(), name='events.add'),
|
||||
|
||||
@@ -40,11 +40,14 @@ from collections import Counter
|
||||
from datetime import time, timedelta
|
||||
from decimal import Decimal
|
||||
from hashlib import sha1
|
||||
from io import BytesIO
|
||||
from itertools import groupby
|
||||
from json import JSONDecodeError
|
||||
|
||||
import bleach
|
||||
import dateutil
|
||||
import qrcode
|
||||
import qrcode.image.svg
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
@@ -3758,3 +3761,41 @@ def reorder_channels(request, organizer):
|
||||
)
|
||||
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
class OrganizerQRCode(OrganizerPermissionRequiredMixin, View):
|
||||
permission = None
|
||||
|
||||
def get(self, request, *args, filetype, **kwargs):
|
||||
url = eventreverse_absolute(request.organizer, 'presale:organizer.index')
|
||||
|
||||
if "url" in request.GET:
|
||||
if request.GET["url"].startswith(url):
|
||||
url = request.GET["url"]
|
||||
else:
|
||||
raise PermissionDenied("Untrusted URL")
|
||||
|
||||
qr = qrcode.QRCode(
|
||||
version=1,
|
||||
error_correction=qrcode.constants.ERROR_CORRECT_M,
|
||||
box_size=10,
|
||||
border=4,
|
||||
)
|
||||
qr.add_data(url)
|
||||
qr.make(fit=True)
|
||||
|
||||
if filetype == 'svg':
|
||||
factory = qrcode.image.svg.SvgPathImage
|
||||
img = qr.make_image(image_factory=factory)
|
||||
r = HttpResponse(img.to_string(), content_type='image/svg+xml')
|
||||
r['Content-Disposition'] = f'inline; filename="qrcode-{request.organizer.slug}.{filetype}"'
|
||||
return r
|
||||
elif filetype in ('jpeg', 'png', 'gif'):
|
||||
img = qr.make_image(fill_color="black", back_color="white")
|
||||
|
||||
byte_io = BytesIO()
|
||||
img.save(byte_io, filetype.upper())
|
||||
byte_io.seek(0)
|
||||
r = HttpResponse(byte_io.read(), content_type='image/' + filetype)
|
||||
r['Content-Disposition'] = f'inline; filename="qrcode-{request.organizer.slug}.{filetype}"'
|
||||
return r
|
||||
|
||||
Reference in New Issue
Block a user