forked from CGM_Public/pretix_original
Compare commits
4 Commits
logentryty
...
organizer-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ecf81bdfe | ||
|
|
e395834811 | ||
|
|
86a32d7856 | ||
|
|
47e8549f19 |
@@ -4,11 +4,34 @@ from django.urls import reverse
|
||||
from django.utils.html import escape
|
||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||
|
||||
from pretix.base.models.log import make_link
|
||||
from pretix.base.signals import EventPluginRegistry
|
||||
from pretix.base.signals import PluginRegistry
|
||||
|
||||
|
||||
class LogEntryTypeRegistry(EventPluginRegistry):
|
||||
def make_link(a_map, wrapper, is_active=True, event=None, plugin_name=None):
|
||||
if a_map:
|
||||
if is_active:
|
||||
a_map['val'] = '<a href="{href}">{val}</a>'.format_map(a_map)
|
||||
elif event and plugin_name:
|
||||
a_map['val'] = (
|
||||
'<i>{val}</i> <a href="{plugin_href}">'
|
||||
'<span data-toggle="tooltip" title="{errmes}" class="fa fa-warning fa-fw"></span></a>'
|
||||
).format_map({
|
||||
**a_map,
|
||||
"errmes": _("The relevant plugin is currently not active. To activate it, click here to go to the plugin settings."),
|
||||
"plugin_href": reverse('control:event.settings.plugins', kwargs={
|
||||
'organizer': event.organizer.slug,
|
||||
'event': event.slug,
|
||||
}) + '#plugin_' + plugin_name,
|
||||
})
|
||||
else:
|
||||
a_map['val'] = '<i>{val}</i> <span data-toggle="tooltip" title="{errmes}" class="fa fa-warning fa-fw"></span>'.format_map({
|
||||
**a_map,
|
||||
"errmes": _("The relevant plugin is currently not active."),
|
||||
})
|
||||
return wrapper.format_map(a_map)
|
||||
|
||||
|
||||
class LogEntryTypeRegistry(PluginRegistry):
|
||||
def new_from_dict(self, data):
|
||||
def reg(clz):
|
||||
for action_type, plain in data.items():
|
||||
|
||||
@@ -742,8 +742,8 @@ class Event(EventMixin, LoggedModel):
|
||||
Returns the names of the plugins activated for this event as a list.
|
||||
"""
|
||||
if self.plugins is None:
|
||||
return []
|
||||
return self.plugins.split(",")
|
||||
return self.organizer.get_plugins()
|
||||
return self.plugins.split(",") + self.organizer.get_plugins()
|
||||
|
||||
def get_cache(self):
|
||||
"""
|
||||
|
||||
@@ -42,7 +42,7 @@ from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from pretix.base.logentrytypes import log_entry_types
|
||||
from pretix.base.logentrytypes import log_entry_types, make_link
|
||||
from pretix.base.signals import is_app_active, logentry_object_link
|
||||
|
||||
|
||||
@@ -51,30 +51,6 @@ class VisibleOnlyManager(models.Manager):
|
||||
return super().get_queryset().filter(visible=True)
|
||||
|
||||
|
||||
def make_link(a_map, wrapper, is_active=True, event=None, plugin_name=None):
|
||||
if a_map:
|
||||
if is_active:
|
||||
a_map['val'] = '<a href="{href}">{val}</a>'.format_map(a_map)
|
||||
elif event and plugin_name:
|
||||
a_map['val'] = (
|
||||
'<i>{val}</i> <a href="{plugin_href}">'
|
||||
'<span data-toggle="tooltip" title="{errmes}" class="fa fa-warning fa-fw"></span></a>'
|
||||
).format_map({
|
||||
**a_map,
|
||||
"errmes": _("The relevant plugin is currently not active. To activate it, click here to go to the plugin settings."),
|
||||
"plugin_href": reverse('control:event.settings.plugins', kwargs={
|
||||
'organizer': event.organizer.slug,
|
||||
'event': event.slug,
|
||||
}) + '#plugin_' + plugin_name,
|
||||
})
|
||||
else:
|
||||
a_map['val'] = '<i>{val}</i> <span data-toggle="tooltip" title="{errmes}" class="fa fa-warning fa-fw"></span>'.format_map({
|
||||
**a_map,
|
||||
"errmes": _("The relevant plugin is currently not active."),
|
||||
})
|
||||
return wrapper.format_map(a_map)
|
||||
|
||||
|
||||
class LogEntry(models.Model):
|
||||
"""
|
||||
Represents a change or action that has been performed on another object
|
||||
|
||||
@@ -2835,6 +2835,14 @@ class OrderPosition(AbstractPosition):
|
||||
(self.order.event.settings.change_allow_user_addons and ItemAddOn.objects.filter(base_item_id__in=[op.item_id for op in positions]).exists())
|
||||
)
|
||||
|
||||
@property
|
||||
def full_code(self):
|
||||
"""
|
||||
A ticket code which is unique among all events of a single organizer,
|
||||
built by concatenating the event slug and the order code.
|
||||
"""
|
||||
return '{order}-{position}'.format(order=self.order.full_code, position=self.positionid)
|
||||
|
||||
|
||||
class Transaction(models.Model):
|
||||
"""
|
||||
|
||||
@@ -91,6 +91,10 @@ class Organizer(LoggedModel):
|
||||
verbose_name=_("Short form"),
|
||||
unique=True
|
||||
)
|
||||
plugins = models.TextField(
|
||||
null=True, blank=True,
|
||||
verbose_name=_("Plugins"),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Organizer")
|
||||
@@ -119,6 +123,14 @@ class Organizer(LoggedModel):
|
||||
"""
|
||||
self.settings.cookie_consent = True
|
||||
|
||||
def get_plugins(self):
|
||||
"""
|
||||
Returns the names of the plugins activated for this organizer as a list.
|
||||
"""
|
||||
if self.plugins is None:
|
||||
return []
|
||||
return self.plugins.split(",")
|
||||
|
||||
def get_cache(self):
|
||||
"""
|
||||
Returns an :py:class:`ObjectRelatedCache` object. This behaves equivalent to
|
||||
|
||||
@@ -96,22 +96,27 @@ def is_receiver_active(sender, receiver):
|
||||
return is_app_active(sender, app)
|
||||
|
||||
|
||||
class EventPluginSignal(django.dispatch.Signal):
|
||||
def is_plugin_host(sender):
|
||||
return hasattr(sender, 'get_plugins')
|
||||
|
||||
|
||||
class PluginSignal(django.dispatch.Signal):
|
||||
"""
|
||||
This is an extension to Django's built-in signals which differs in a way that it sends
|
||||
out it's events only to receivers which belong to plugins that are enabled for the given
|
||||
Event.
|
||||
"""
|
||||
|
||||
def send(self, sender: Event, **named) -> List[Tuple[Callable, Any]]:
|
||||
def send(self, sender, **named) -> List[Tuple[Callable, Any]]:
|
||||
"""
|
||||
Send signal from sender to all connected receivers that belong to
|
||||
plugins enabled for the given Event.
|
||||
|
||||
sender is required to be an instance of ``pretix.base.models.Event``.
|
||||
sender is required to be a plugin host (an object with a `get_plugins` method),
|
||||
for example a ``pretix.base.models.Event``.
|
||||
"""
|
||||
if sender and not isinstance(sender, Event):
|
||||
raise ValueError("Sender needs to be an event.")
|
||||
if sender and not is_plugin_host(sender):
|
||||
raise ValueError("Sender needs to be a plugin host.")
|
||||
|
||||
responses = []
|
||||
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
|
||||
@@ -126,16 +131,17 @@ class EventPluginSignal(django.dispatch.Signal):
|
||||
responses.append((receiver, response))
|
||||
return responses
|
||||
|
||||
def send_chained(self, sender: Event, chain_kwarg_name, **named) -> List[Tuple[Callable, Any]]:
|
||||
def send_chained(self, sender, chain_kwarg_name, **named) -> List[Tuple[Callable, Any]]:
|
||||
"""
|
||||
Send signal from sender to all connected receivers. The return value of the first receiver
|
||||
will be used as the keyword argument specified by ``chain_kwarg_name`` in the input to the
|
||||
second receiver and so on. The return value of the last receiver is returned by this method.
|
||||
|
||||
sender is required to be an instance of ``pretix.base.models.Event``.
|
||||
sender is required to be a plugin host (an object with a `get_plugins` method),
|
||||
for example a ``pretix.base.models.Event``.
|
||||
"""
|
||||
if sender and not isinstance(sender, Event):
|
||||
raise ValueError("Sender needs to be an event.")
|
||||
if sender and not is_plugin_host(sender):
|
||||
raise ValueError("Sender needs to be a plugin host.")
|
||||
|
||||
response = named.get(chain_kwarg_name)
|
||||
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
|
||||
@@ -150,16 +156,17 @@ class EventPluginSignal(django.dispatch.Signal):
|
||||
response = receiver(signal=self, sender=sender, **named)
|
||||
return response
|
||||
|
||||
def send_robust(self, sender: Event, **named) -> List[Tuple[Callable, Any]]:
|
||||
def send_robust(self, sender, **named) -> List[Tuple[Callable, Any]]:
|
||||
"""
|
||||
Send signal from sender to all connected receivers. If a receiver raises an exception
|
||||
instead of returning a value, the exception is included as the result instead of
|
||||
stopping the response chain at the offending receiver.
|
||||
|
||||
sender is required to be an instance of ``pretix.base.models.Event``.
|
||||
sender is required to be a plugin host (an object with a `get_plugins` method),
|
||||
for example a ``pretix.base.models.Event``.
|
||||
"""
|
||||
if sender and not isinstance(sender, Event):
|
||||
raise ValueError("Sender needs to be an event.")
|
||||
if sender and not is_plugin_host(sender):
|
||||
raise ValueError("Sender needs to be a plugin host.")
|
||||
|
||||
responses = []
|
||||
if (
|
||||
@@ -194,6 +201,14 @@ class EventPluginSignal(django.dispatch.Signal):
|
||||
return sorted_list
|
||||
|
||||
|
||||
class OrganizerPluginSignal(PluginSignal):
|
||||
pass
|
||||
|
||||
|
||||
class EventPluginSignal(PluginSignal):
|
||||
pass
|
||||
|
||||
|
||||
class GlobalSignal(django.dispatch.Signal):
|
||||
def send_chained(self, sender: Event, chain_kwarg_name, **named) -> List[Tuple[Callable, Any]]:
|
||||
"""
|
||||
@@ -245,7 +260,7 @@ class Registry:
|
||||
return self.by_key.get(key).get(value, (None, None))
|
||||
|
||||
|
||||
class EventPluginRegistry(Registry):
|
||||
class PluginRegistry(Registry):
|
||||
def __init__(self, keys):
|
||||
super().__init__({"plugin": lambda o: get_defining_app(o), **keys})
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
from django.dispatch import Signal
|
||||
|
||||
from pretix.base.signals import DeprecatedSignal, EventPluginSignal
|
||||
from pretix.base.signals import DeprecatedSignal, EventPluginSignal, OrganizerPluginSignal
|
||||
|
||||
html_page_start = Signal()
|
||||
"""
|
||||
@@ -221,7 +221,7 @@ Deprecated signal, no longer works. We just keep the definition so old plugins d
|
||||
break the installation.
|
||||
"""
|
||||
|
||||
nav_organizer = Signal()
|
||||
nav_organizer = OrganizerPluginSignal()
|
||||
"""
|
||||
Arguments: 'organizer', 'request'
|
||||
|
||||
|
||||
@@ -26,8 +26,9 @@ from django.dispatch import receiver
|
||||
from django.template.loader import get_template
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from pretix.base.logentrytypes import EventLogEntryType
|
||||
from pretix.base.models import Event, SalesChannel
|
||||
from pretix.base.models.log import EventLogEntryType, log_entry_types
|
||||
from pretix.base.models.log import log_entry_types
|
||||
from pretix.base.signals import ( # NOQA: legacy import
|
||||
EventPluginSignal, event_copy_data, item_copy_data, layout_text_variables,
|
||||
logentry_display, logentry_object_link, register_data_exporters,
|
||||
|
||||
@@ -552,6 +552,16 @@ var form_handlers = function (el) {
|
||||
language: $("body").attr("data-select2-locale"),
|
||||
});
|
||||
|
||||
el.find('[data-model-select2=json_script]').each(function() {
|
||||
const selectedValue = this.value;
|
||||
this.replaceChildren();
|
||||
$(this).select2({
|
||||
theme: "bootstrap",
|
||||
language: $("body").attr("data-select2-locale"),
|
||||
data: JSON.parse($(this.getAttribute('data-select2-src')).text()),
|
||||
}).val(selectedValue).trigger('change');
|
||||
});
|
||||
|
||||
el.find('input[data-typeahead-url]').each(function () {
|
||||
var $inp = $(this);
|
||||
if ($inp.data("ttTypeahead") || $inp.hasClass("tt-hint")) {
|
||||
|
||||
Reference in New Issue
Block a user