mirror of
https://github.com/pretix/pretix.git
synced 2026-08-23 12:51:59 +00:00
Experimental organizer-level plugin implementation
This commit is contained in:
@@ -742,8 +742,8 @@ class Event(EventMixin, LoggedModel):
|
|||||||
Returns the names of the plugins activated for this event as a list.
|
Returns the names of the plugins activated for this event as a list.
|
||||||
"""
|
"""
|
||||||
if self.plugins is None:
|
if self.plugins is None:
|
||||||
return []
|
return self.organizer.get_plugins()
|
||||||
return self.plugins.split(",")
|
return self.plugins.split(",") + self.organizer.get_plugins()
|
||||||
|
|
||||||
def get_cache(self):
|
def get_cache(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -91,6 +91,10 @@ class Organizer(LoggedModel):
|
|||||||
verbose_name=_("Short form"),
|
verbose_name=_("Short form"),
|
||||||
unique=True
|
unique=True
|
||||||
)
|
)
|
||||||
|
plugins = models.TextField(
|
||||||
|
null=True, blank=True,
|
||||||
|
verbose_name=_("Plugins"),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Organizer")
|
verbose_name = _("Organizer")
|
||||||
@@ -119,6 +123,14 @@ class Organizer(LoggedModel):
|
|||||||
"""
|
"""
|
||||||
self.settings.cookie_consent = True
|
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):
|
def get_cache(self):
|
||||||
"""
|
"""
|
||||||
Returns an :py:class:`ObjectRelatedCache` object. This behaves equivalent to
|
Returns an :py:class:`ObjectRelatedCache` object. This behaves equivalent to
|
||||||
|
|||||||
+29
-14
@@ -96,22 +96,27 @@ def is_receiver_active(sender, receiver):
|
|||||||
return is_app_active(sender, app)
|
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
|
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
|
out it's events only to receivers which belong to plugins that are enabled for the given
|
||||||
Event.
|
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
|
Send signal from sender to all connected receivers that belong to
|
||||||
plugins enabled for the given Event.
|
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):
|
if sender and not is_plugin_host(sender):
|
||||||
raise ValueError("Sender needs to be an event.")
|
raise ValueError("Sender needs to be a plugin host.")
|
||||||
|
|
||||||
responses = []
|
responses = []
|
||||||
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
|
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))
|
responses.append((receiver, response))
|
||||||
return responses
|
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
|
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
|
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.
|
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):
|
if sender and not is_plugin_host(sender):
|
||||||
raise ValueError("Sender needs to be an event.")
|
raise ValueError("Sender needs to be a plugin host.")
|
||||||
|
|
||||||
response = named.get(chain_kwarg_name)
|
response = named.get(chain_kwarg_name)
|
||||||
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
|
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)
|
response = receiver(signal=self, sender=sender, **named)
|
||||||
return response
|
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
|
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
|
instead of returning a value, the exception is included as the result instead of
|
||||||
stopping the response chain at the offending receiver.
|
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):
|
if sender and not is_plugin_host(sender):
|
||||||
raise ValueError("Sender needs to be an event.")
|
raise ValueError("Sender needs to be a plugin host.")
|
||||||
|
|
||||||
responses = []
|
responses = []
|
||||||
if (
|
if (
|
||||||
@@ -194,6 +201,14 @@ class EventPluginSignal(django.dispatch.Signal):
|
|||||||
return sorted_list
|
return sorted_list
|
||||||
|
|
||||||
|
|
||||||
|
class OrganizerPluginSignal(PluginSignal):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class EventPluginSignal(PluginSignal):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GlobalSignal(django.dispatch.Signal):
|
class GlobalSignal(django.dispatch.Signal):
|
||||||
def send_chained(self, sender: Event, chain_kwarg_name, **named) -> List[Tuple[Callable, Any]]:
|
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))
|
return self.by_key.get(key).get(value, (None, None))
|
||||||
|
|
||||||
|
|
||||||
class EventPluginRegistry(Registry):
|
class PluginRegistry(Registry):
|
||||||
def __init__(self, keys):
|
def __init__(self, keys):
|
||||||
super().__init__({"plugin": lambda o: get_defining_app(o), **keys})
|
super().__init__({"plugin": lambda o: get_defining_app(o), **keys})
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
from django.dispatch import Signal
|
from django.dispatch import Signal
|
||||||
|
|
||||||
from pretix.base.signals import DeprecatedSignal, EventPluginSignal
|
from pretix.base.signals import DeprecatedSignal, EventPluginSignal, OrganizerPluginSignal
|
||||||
|
|
||||||
html_page_start = Signal()
|
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.
|
break the installation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
nav_organizer = Signal()
|
nav_organizer = OrganizerPluginSignal()
|
||||||
"""
|
"""
|
||||||
Arguments: 'organizer', 'request'
|
Arguments: 'organizer', 'request'
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,9 @@ from django.dispatch import receiver
|
|||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
from django.utils.translation import gettext_lazy as _
|
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 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
|
from pretix.base.signals import ( # NOQA: legacy import
|
||||||
EventPluginSignal, event_copy_data, item_copy_data, layout_text_variables,
|
EventPluginSignal, event_copy_data, item_copy_data, layout_text_variables,
|
||||||
logentry_display, logentry_object_link, register_data_exporters,
|
logentry_display, logentry_object_link, register_data_exporters,
|
||||||
|
|||||||
Reference in New Issue
Block a user