mirror of
https://github.com/pretix/pretix.git
synced 2026-08-27 13:24:41 +00:00
Add email_filter signal
This commit is contained in:
@@ -11,7 +11,7 @@ Core
|
|||||||
----
|
----
|
||||||
|
|
||||||
.. automodule:: pretix.base.signals
|
.. automodule:: pretix.base.signals
|
||||||
:members: periodic_task, event_live_issues, event_copy_data
|
:members: periodic_task, event_live_issues, event_copy_data, email_filter
|
||||||
|
|
||||||
Order events
|
Order events
|
||||||
""""""""""""
|
""""""""""""
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from inlinestyler.utils import inline_css
|
|||||||
from pretix.base.i18n import language
|
from pretix.base.i18n import language
|
||||||
from pretix.base.models import Event, Invoice, InvoiceAddress, Order
|
from pretix.base.models import Event, Invoice, InvoiceAddress, Order
|
||||||
from pretix.base.services.invoices import invoice_pdf_task
|
from pretix.base.services.invoices import invoice_pdf_task
|
||||||
|
from pretix.base.signals import email_filter
|
||||||
from pretix.celery_app import app
|
from pretix.celery_app import app
|
||||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||||
|
|
||||||
@@ -150,7 +151,8 @@ def mail(email: str, subject: str, template: Union[str, LazyI18nString],
|
|||||||
sender=sender,
|
sender=sender,
|
||||||
event=event.id if event else None,
|
event=event.id if event else None,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
invoices=[i.pk for i in invoices] if invoices else []
|
invoices=[i.pk for i in invoices] if invoices else [],
|
||||||
|
order=order.pk if order else None
|
||||||
)
|
)
|
||||||
|
|
||||||
if invoices:
|
if invoices:
|
||||||
@@ -164,7 +166,8 @@ def mail(email: str, subject: str, template: Union[str, LazyI18nString],
|
|||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def mail_send_task(*args, to: List[str], subject: str, body: str, html: str, sender: str,
|
def mail_send_task(*args, to: List[str], subject: str, body: str, html: str, sender: str,
|
||||||
event: int=None, headers: dict=None, bcc: List[str]=None, invoices: List[int]=None) -> bool:
|
event: int=None, headers: dict=None, bcc: List[str]=None, invoices: List[int]=None,
|
||||||
|
order: int=None) -> bool:
|
||||||
email = EmailMultiAlternatives(subject, body, sender, to=to, bcc=bcc, headers=headers)
|
email = EmailMultiAlternatives(subject, body, sender, to=to, bcc=bcc, headers=headers)
|
||||||
if html is not None:
|
if html is not None:
|
||||||
email.attach_alternative(inline_css(html), "text/html")
|
email.attach_alternative(inline_css(html), "text/html")
|
||||||
@@ -183,6 +186,14 @@ def mail_send_task(*args, to: List[str], subject: str, body: str, html: str, sen
|
|||||||
else:
|
else:
|
||||||
backend = get_connection(fail_silently=False)
|
backend = get_connection(fail_silently=False)
|
||||||
|
|
||||||
|
if event:
|
||||||
|
if order:
|
||||||
|
try:
|
||||||
|
order = event.orders.get(pk=order)
|
||||||
|
except Order.DoesNotExist:
|
||||||
|
order = None
|
||||||
|
email = email_filter.send_chained(event, 'message', message=email, order=order)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
backend.send_messages([email])
|
backend.send_messages([email])
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
+58
-16
@@ -25,6 +25,24 @@ class EventPluginSignal(django.dispatch.Signal):
|
|||||||
Event.
|
Event.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def _is_active(self, sender, receiver):
|
||||||
|
# Find the Django application this belongs to
|
||||||
|
searchpath = receiver.__module__
|
||||||
|
core_module = any([searchpath.startswith(cm) for cm in settings.CORE_MODULES])
|
||||||
|
app = None
|
||||||
|
if not core_module:
|
||||||
|
while True:
|
||||||
|
app = app_cache.get(searchpath)
|
||||||
|
if "." not in searchpath or app:
|
||||||
|
break
|
||||||
|
searchpath, _ = searchpath.rsplit(".", 1)
|
||||||
|
|
||||||
|
# Only fire receivers from active plugins and core modules
|
||||||
|
if core_module or (sender and app and app.name in sender.get_plugins()):
|
||||||
|
if not hasattr(app, 'compatibility_errors') or not app.compatibility_errors:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def send(self, sender: Event, **named) -> List[Tuple[Callable, Any]]:
|
def send(self, sender: Event, **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
|
||||||
@@ -43,24 +61,35 @@ class EventPluginSignal(django.dispatch.Signal):
|
|||||||
_populate_app_cache()
|
_populate_app_cache()
|
||||||
|
|
||||||
for receiver in self._live_receivers(sender):
|
for receiver in self._live_receivers(sender):
|
||||||
# Find the Django application this belongs to
|
if self._is_active(sender, receiver):
|
||||||
searchpath = receiver.__module__
|
response = receiver(signal=self, sender=sender, **named)
|
||||||
core_module = any([searchpath.startswith(cm) for cm in settings.CORE_MODULES])
|
responses.append((receiver, response))
|
||||||
app = None
|
|
||||||
if not core_module:
|
|
||||||
while True:
|
|
||||||
app = app_cache.get(searchpath)
|
|
||||||
if "." not in searchpath or app:
|
|
||||||
break
|
|
||||||
searchpath, _ = searchpath.rsplit(".", 1)
|
|
||||||
|
|
||||||
# Only fire receivers from active plugins and core modules
|
|
||||||
if core_module or (sender and app and app.name in sender.get_plugins()):
|
|
||||||
if not hasattr(app, 'compatibility_errors') or not app.compatibility_errors:
|
|
||||||
response = receiver(signal=self, sender=sender, **named)
|
|
||||||
responses.append((receiver, response))
|
|
||||||
return sorted(responses, key=lambda r: (receiver.__module__, receiver.__name__))
|
return sorted(responses, key=lambda r: (receiver.__module__, receiver.__name__))
|
||||||
|
|
||||||
|
def send_chained(self, sender: Event, 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``.
|
||||||
|
"""
|
||||||
|
if sender and not isinstance(sender, Event):
|
||||||
|
raise ValueError("Sender needs to be an event.")
|
||||||
|
|
||||||
|
response = named.get(chain_kwarg_name)
|
||||||
|
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
|
||||||
|
return response
|
||||||
|
|
||||||
|
if not app_cache:
|
||||||
|
_populate_app_cache()
|
||||||
|
|
||||||
|
for receiver in self._live_receivers(sender):
|
||||||
|
if self._is_active(sender, receiver):
|
||||||
|
named[chain_kwarg_name] = response
|
||||||
|
response = receiver(signal=self, sender=sender, **named)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
class DeprecatedSignal(django.dispatch.Signal):
|
class DeprecatedSignal(django.dispatch.Signal):
|
||||||
|
|
||||||
@@ -277,3 +306,16 @@ a download will not be offered.
|
|||||||
|
|
||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
email_filter = EventPluginSignal(
|
||||||
|
providing_args=['message', 'order']
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
This signal allows you to implement a middleware-style filter on all outgoing emails. You are expected to
|
||||||
|
return a (possibly modified) copy of the message object passed to you.
|
||||||
|
|
||||||
|
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
|
The ``message`` argument will contian an ``EmailMultiAlternatives`` object.
|
||||||
|
If the email is associated with a specific order, the ``order`` argument will be passed as well, otherwise
|
||||||
|
it will be ``None``.
|
||||||
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user