commit d4c40a927ad7069e4a9ad9cd3dc11050b1c8ddf2 Author: _Bastler Date: Thu Nov 19 09:40:03 2020 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cc7fbd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,62 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg +.ropeproject/ + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +#Ipython Notebook +.ipynb_checkpoints diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..65d5d6c --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ + +Copyright 2020 _Bastler + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..17ba0c0 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +recursive-include pretix_digital_items/static * +recursive-include pretix_digital_items/templates * +recursive-include pretix_digital_items/locale * diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fd8eec0 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +all: localecompile +LNGS:=`find pretix_digital_items/locale/ -mindepth 1 -maxdepth 1 -type d -printf "-l %f "` + +localecompile: + django-admin compilemessages + +localegen: + django-admin makemessages --keep-pot -i build -i dist -i "*egg*" $(LNGS) + +.PHONY: all localecompile localegen diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..c6fb469 --- /dev/null +++ b/README.rst @@ -0,0 +1,36 @@ +Digital Items +========================== + +This is a plugin for `pretix`_. + +Sell digital Items by using secrets as tokens. Adds secrets to email placeholders, output secret as simple TXT file. + +Development setup +----------------- + +1. Make sure that you have a working `pretix development setup`_. + +2. Clone this repository, eg to ``local/pretix-digital-items``. + +3. Activate the virtual environment you use for pretix development. + +4. Execute ``python setup.py develop`` within this directory to register this application with pretix's plugin registry. + +5. Execute ``make`` within this directory to compile translations. + +6. Restart your local pretix server. You can now use the plugin from this repository for your events by enabling it in + the 'plugins' tab in the settings. + + +License +------- + + +Copyright 2020 _Bastler + +Released under the terms of the Apache License 2.0 + + + +.. _pretix: https://github.com/pretix/pretix +.. _pretix development setup: https://docs.pretix.eu/en/latest/development/setup.html diff --git a/pretix_digital_items/__init__.py b/pretix_digital_items/__init__.py new file mode 100644 index 0000000..d29d1f0 --- /dev/null +++ b/pretix_digital_items/__init__.py @@ -0,0 +1,28 @@ +from django.utils.translation import gettext_lazy + +try: + from pretix.base.plugins import PluginConfig +except ImportError: + raise RuntimeError("Please use pretix 2.7 or above to run this plugin!") + +__version__ = '1.0.0' + + +class PluginApp(PluginConfig): + name = 'pretix_digital_items' + verbose_name = 'Digital Items' + + class PretixPluginMeta: + name = gettext_lazy('Digital Items') + author = '_Bastler' + description = gettext_lazy('Sell digital Items by using secrets as tokens. Adds secrets to email placeholders, output secret as simple TXT file.') + visible = True + version = __version__ + category = 'FEATURE' + compatibility = "pretix>=2.7.0" + + def ready(self): + from . import signals # NOQA + + +default_app_config = 'pretix_digital_items.PluginApp' diff --git a/pretix_digital_items/forms.py b/pretix_digital_items/forms.py new file mode 100644 index 0000000..3c3486c --- /dev/null +++ b/pretix_digital_items/forms.py @@ -0,0 +1,16 @@ +from django import forms +from django.utils.translation import ugettext_lazy as _ +from pretix.base.forms import SettingsForm + + +class PretixDigitalItemsSettingsForm(SettingsForm): + digitalitems_token_mail_format = forms.CharField( + label=_("Token mail format"), + help_text=_("This text will be included for every token in an email. Available placeholder are {name} for the item name and {secret} for the token code."), + widget=forms.TextInput(attrs={'placeholder': '{name}: {secret}'}), + required=False) + digitalitems_token_export_format = forms.CharField( + label=_("Token export format"), + help_text=_("This text will be included for every token in a TXT export. Available placeholder are {name} for the item name and {secret} for the token code."), + widget=forms.TextInput(attrs={'placeholder': '{name}: {secret}'}), + required=False) diff --git a/pretix_digital_items/locale/de/LC_MESSAGES/django.po b/pretix_digital_items/locale/de/LC_MESSAGES/django.po new file mode 100644 index 0000000..b6643aa --- /dev/null +++ b/pretix_digital_items/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,40 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-07 19:01+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: _Bastler\n" +"Language-Team: \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# title +msgid "Digital Items" +msgstr "Digitale Items" + +# description +msgid "" +"Sell digital Items by using secrets as tokens. Adds secrets to email placeholders, output secret as simple TXT file." +msgstr "Verkauf digitaler Items indem die Token-Codes der Tickets als einzulösendes Token verwendet werden. Token-Codes sind als E-Mail Platzhalter verfügbar, Exportfunktion als einfache TXT-Datei." + +#: pretix_digital_items/forms.py:8 +msgid "Token mail format" +msgstr "Token E-Mail Format" + +#: pretix_digital_items/forms.py:9 +msgid "" +"This text will be included for every token in an email. Available placeholder are {name} for the item name and {secret} for the token code." +msgstr "Dieser Text wird für jedes Token in einer E-Mail eingefügt. Verfügbare Platzhalter sind {name} für den Item-Namen und {secret} für den Token-Code." + +#: pretix_digital_items/forms.py: +msgid "Token export format" +msgstr "Token Export Format" + +#: pretix_digital_items/forms.py: +msgid "" +"This text will be included for every token in a TXT export. Available placeholder are {name} for the item name and {secret} for the token code." +msgstr "Dieser Text wird für jedes Token in einem TXT Export eingefügt. Verfügbare Platzhalter sind {name} für den Item-Namen und {secret} für den Token-Code." + diff --git a/pretix_digital_items/locale/de_Informal/.gitkeep b/pretix_digital_items/locale/de_Informal/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/pretix_digital_items/locale/de_Informal/LC_MESSAGES/django.po b/pretix_digital_items/locale/de_Informal/LC_MESSAGES/django.po new file mode 100644 index 0000000..b6643aa --- /dev/null +++ b/pretix_digital_items/locale/de_Informal/LC_MESSAGES/django.po @@ -0,0 +1,40 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-07 19:01+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: _Bastler\n" +"Language-Team: \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# title +msgid "Digital Items" +msgstr "Digitale Items" + +# description +msgid "" +"Sell digital Items by using secrets as tokens. Adds secrets to email placeholders, output secret as simple TXT file." +msgstr "Verkauf digitaler Items indem die Token-Codes der Tickets als einzulösendes Token verwendet werden. Token-Codes sind als E-Mail Platzhalter verfügbar, Exportfunktion als einfache TXT-Datei." + +#: pretix_digital_items/forms.py:8 +msgid "Token mail format" +msgstr "Token E-Mail Format" + +#: pretix_digital_items/forms.py:9 +msgid "" +"This text will be included for every token in an email. Available placeholder are {name} for the item name and {secret} for the token code." +msgstr "Dieser Text wird für jedes Token in einer E-Mail eingefügt. Verfügbare Platzhalter sind {name} für den Item-Namen und {secret} für den Token-Code." + +#: pretix_digital_items/forms.py: +msgid "Token export format" +msgstr "Token Export Format" + +#: pretix_digital_items/forms.py: +msgid "" +"This text will be included for every token in a TXT export. Available placeholder are {name} for the item name and {secret} for the token code." +msgstr "Dieser Text wird für jedes Token in einem TXT Export eingefügt. Verfügbare Platzhalter sind {name} für den Item-Namen und {secret} für den Token-Code." + diff --git a/pretix_digital_items/signals.py b/pretix_digital_items/signals.py new file mode 100644 index 0000000..0b333e1 --- /dev/null +++ b/pretix_digital_items/signals.py @@ -0,0 +1,32 @@ +from django.dispatch import receiver +from django.urls import resolve, reverse + +from django.utils.translation import ugettext_lazy as _ + +from pretix.base.signals import (register_mail_placeholders, register_ticket_outputs) +from pretix.base.email import SimpleFunctionalMailTextPlaceholder +from pretix.control.signals import nav_event_settings + +@receiver(register_mail_placeholders, dispatch_uid="pretix_digital_items_mail_placeholder") +def register_mail_secrets(sender, **kwargs): + token_mail_format = "{name}: {secret}" + if sender.settings.digitalitems_token_mail_format: + token_mail_format = sender.settings.digitalitems_token_mail_format + return SimpleFunctionalMailTextPlaceholder('secrets', ['order'], lambda order: '\n' + '\n\n'.join(token_mail_format.format(secret = position.secret, name = str(position.item.name)) for position in order.positions.all()), '\nej7f73xs8vfmwvkk2p73yeve4fueq849\n\np8yct9752a897rpsmqzf7beby34a2w25\n\nwwqxtw6guy5s8c5tdarfhyez2ft2juap') + +@receiver(register_ticket_outputs, dispatch_uid="pretix_digital_items_ticket_output") +def register_ticket_outputs(sender, **kwargs): + from .textticketoutput import TextTicketOutput + return TextTicketOutput + +@receiver(nav_event_settings, dispatch_uid='pretix_digital_items_nav_settings') +def navbar_settings(sender, request, **kwargs): + url = resolve(request.path_info) + return [{ + 'label': _('Digital Items'), + 'url': reverse('plugins:pretix_digital_items:settings', kwargs={ + 'event': request.event.slug, + 'organizer': request.organizer.slug, + }), + 'active': url.namespace == 'plugins:pretix_digital_items' and url.url_name == 'settings', + }] diff --git a/pretix_digital_items/static/pretix_digital_items/.gitkeep b/pretix_digital_items/static/pretix_digital_items/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/pretix_digital_items/templates/pretix_digital_items/.gitkeep b/pretix_digital_items/templates/pretix_digital_items/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/pretix_digital_items/templates/pretix_digital_items/settings.html b/pretix_digital_items/templates/pretix_digital_items/settings.html new file mode 100644 index 0000000..8b18284 --- /dev/null +++ b/pretix_digital_items/templates/pretix_digital_items/settings.html @@ -0,0 +1,16 @@ +{% extends "pretixcontrol/event/settings_base.html" %} +{% load i18n %} +{% load bootstrap3 %} +{% block inside %} +

{% trans "Digital Items" %}

+
+ {% csrf_token %} + {% bootstrap_form_errors form %} + {% bootstrap_form form layout="horizontal" %} +
+ +
+
+{% endblock %} diff --git a/pretix_digital_items/textticketoutput.py b/pretix_digital_items/textticketoutput.py new file mode 100644 index 0000000..62f4ace --- /dev/null +++ b/pretix_digital_items/textticketoutput.py @@ -0,0 +1,18 @@ +from pretix.base.ticketoutput import BaseTicketOutput + +class TextTicketOutput(BaseTicketOutput): + identifier = 'tokens' + verbose_name = 'Download token as in simple textfile' + download_button_text = 'Download Token' + + def generate(self, position): + token_export_format = "{name}: {secret}" + if position.event.settings.digitalitems_token_export_format: + token_export_format = position.event.settings.digitalitems_token_export_format + return 'token.txt', 'text/plain', token_export_format.format(secret = position.secret, name = str(position.item.name)) + + def generate_order(self, order): + token_export_format = "{name}: {secret}" + if order.event.settings.digitalitems_token_export_format: + token_export_format = order.event.settings.digitalitems_token_export_format + return 'tokens.txt', 'text/plain', '\n'.join(token_export_format.format(secret = position.secret, name = str(position.item.name)) for position in order.positions.all()) diff --git a/pretix_digital_items/urls.py b/pretix_digital_items/urls.py new file mode 100644 index 0000000..6ab342b --- /dev/null +++ b/pretix_digital_items/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls import url + +from .views import SettingsView + +urlpatterns = [ + url( + r"^control/event/(?P[^/]+)/(?P[^/]+)/pretix_digital_items/settings", + SettingsView.as_view(), + name="settings", + ), +] diff --git a/pretix_digital_items/views.py b/pretix_digital_items/views.py new file mode 100644 index 0000000..5d89a73 --- /dev/null +++ b/pretix_digital_items/views.py @@ -0,0 +1,23 @@ +from django.urls import reverse +from pretix.control.views.event import EventSettingsFormView, EventSettingsViewMixin +from pretix.base.models.event import Event +from .forms import PretixDigitalItemsSettingsForm + +from pretix.presale.style import regenerate_css +from django.contrib import messages + + +class SettingsView(EventSettingsViewMixin, EventSettingsFormView): + model = Event + permission = "can_change_settings" + form_class = PretixDigitalItemsSettingsForm + template_name = "pretix_digital_items/settings.html" + + def get_success_url(self, **kwargs): + return reverse( + "plugins:pretix_digital_items:settings", + kwargs={ + "organizer": self.request.event.organizer.slug, + "event": self.request.event.slug, + }, + ) diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..ccf8194 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +DJANGO_SETTINGS_MODULE=pretix.testutils.settings diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..5cd9371 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,14 @@ +[flake8] +ignore = N802,W503,E402 +max-line-length = 160 +exclude = migrations,.ropeproject,static,_static,build + +[isort] +combine_as_imports = true +default_section = THIRDPARTY +include_trailing_comma = true +known_third_party = pretix +known_standard_library = typing +multi_line_output = 5 +not_skip = __init__.py +skip = setup.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..618f059 --- /dev/null +++ b/setup.py @@ -0,0 +1,46 @@ +import os +from distutils.command.build import build + +from django.core import management +from setuptools import find_packages, setup + +from pretix_digital_items import __version__ + + +try: + with open(os.path.join(os.path.dirname(__file__), 'README.rst'), encoding='utf-8') as f: + long_description = f.read() +except: + long_description = '' + + +class CustomBuild(build): + def run(self): + management.call_command('compilemessages', verbosity=1) + build.run(self) + + +cmdclass = { + 'build': CustomBuild +} + + +setup( + name='pretix-digital-items', + version=__version__, + description='Sell digital Items by using secrets as tokens. Adds secrets to email placeholders, output secret as simple TXT file.', + long_description=long_description, + url='https://git.lh8.de/_Bastler/pretix-digital-items', + author='_Bastler', + author_email='pretix-digital-items@bstly.de', + license='Apache', + + install_requires=[], + packages=find_packages(exclude=['tests', 'tests.*']), + include_package_data=True, + cmdclass=cmdclass, + entry_points=""" +[pretix.plugin] +pretix_digital_items=pretix_digital_items:PretixPluginMeta +""", +)