Sendmail plugin: Move to background process

This commit is contained in:
Raphael Michel
2018-03-07 14:48:17 +01:00
parent 9fdef5eb5d
commit d058721243
3 changed files with 76 additions and 47 deletions

View File

@@ -17,6 +17,7 @@ class SendMailApp(AppConfig):
def ready(self): def ready(self):
from . import signals # NOQA from . import signals # NOQA
from . import tasks # NOQA
default_app_config = 'pretix.plugins.sendmail.SendMailApp' default_app_config = 'pretix.plugins.sendmail.SendMailApp'

View File

@@ -0,0 +1,63 @@
import pytz
from django.utils.formats import date_format
from i18nfield.strings import LazyI18nString
from pretix.base.i18n import language
from pretix.base.models import Event, InvoiceAddress, Order, User
from pretix.base.services.async import ProfiledTask
from pretix.base.services.mail import SendMailException, mail
from pretix.celery_app import app
from pretix.multidomain.urlreverse import build_absolute_uri
@app.task(base=ProfiledTask)
def send_mails(event: int, user: int, subject: dict, message: dict, orders: list) -> None:
failures = []
event = Event.objects.get(pk=event)
user = User.objects.get(pk=user) if user else None
orders = Order.objects.filter(pk__in=orders)
subject = LazyI18nString(subject)
message = LazyI18nString(message)
tz = pytz.timezone(event.settings.timezone)
for o in orders:
try:
invoice_name = o.invoice_address.name
invoice_company = o.invoice_address.company
except InvoiceAddress.DoesNotExist:
invoice_name = ""
invoice_company = ""
try:
with language(o.locale):
email_context = {
'event': o.event,
'code': o.code,
'date': date_format(o.datetime.astimezone(tz), 'SHORT_DATETIME_FORMAT'),
'expire_date': date_format(o.expires, 'SHORT_DATE_FORMAT'),
'url': build_absolute_uri(event, 'presale:event.order', kwargs={
'order': o.code,
'secret': o.secret
}),
'invoice_name': invoice_name,
'invoice_company': invoice_company,
}
mail(
o.email,
subject,
message,
email_context,
event,
locale=o.locale,
order=o
)
o.log_action(
'pretix.plugins.sendmail.order.email.sent',
user=user,
data={
'subject': subject.localize(o.locale),
'message': message.localize(o.locale).format_map(email_context),
'recipient': o.email
}
)
except SendMailException:
failures.append(o.email)

View File

@@ -1,7 +1,6 @@
import logging import logging
from datetime import timedelta from datetime import timedelta
import pytz
from django.contrib import messages from django.contrib import messages
from django.db.models import Q from django.db.models import Q
from django.http import Http404 from django.http import Http404
@@ -12,11 +11,11 @@ from django.utils.translation import ugettext_lazy as _
from django.views.generic import FormView, ListView from django.views.generic import FormView, ListView
from pretix.base.i18n import LazyI18nString, language from pretix.base.i18n import LazyI18nString, language
from pretix.base.models import InvoiceAddress, LogEntry, Order from pretix.base.models import LogEntry, Order
from pretix.base.models.event import SubEvent from pretix.base.models.event import SubEvent
from pretix.base.services.mail import SendMailException, mail
from pretix.control.permissions import EventPermissionRequiredMixin from pretix.control.permissions import EventPermissionRequiredMixin
from pretix.multidomain.urlreverse import build_absolute_uri from pretix.multidomain.urlreverse import build_absolute_uri
from pretix.plugins.sendmail.tasks import send_mails
from . import forms from . import forms
@@ -71,9 +70,6 @@ class SenderView(EventPermissionRequiredMixin, FormView):
orders = orders.filter(positions__subevent__in=(form.cleaned_data.get('subevent'),)) orders = orders.filter(positions__subevent__in=(form.cleaned_data.get('subevent'),))
orders = orders.distinct() orders = orders.distinct()
tz = pytz.timezone(self.request.event.settings.timezone)
failures = []
self.output = {} self.output = {}
if not orders: if not orders:
messages.error(self.request, _('There are no orders matching this selection.')) messages.error(self.request, _('There are no orders matching this selection.'))
@@ -110,50 +106,19 @@ class SenderView(EventPermissionRequiredMixin, FormView):
return self.get(self.request, *self.args, **self.kwargs) return self.get(self.request, *self.args, **self.kwargs)
for o in orders: send_mails.apply_async(
try: kwargs={
invoice_name = o.invoice_address.name 'event': self.request.event.pk,
invoice_company = o.invoice_address.company 'user': self.request.user.pk,
except InvoiceAddress.DoesNotExist: 'subject': form.cleaned_data['subject'].data,
invoice_name = "" 'message': form.cleaned_data['message'].data,
invoice_company = "" 'orders': [o.pk for o in orders],
try: }
with language(o.locale): )
email_context = {
'event': o.event,
'code': o.code,
'date': date_format(o.datetime.astimezone(tz), 'SHORT_DATETIME_FORMAT'),
'expire_date': date_format(o.expires, 'SHORT_DATE_FORMAT'),
'url': build_absolute_uri(o.event, 'presale:event.order', kwargs={
'order': o.code,
'secret': o.secret
}),
'invoice_name': invoice_name,
'invoice_company': invoice_company,
}
mail(
o.email, form.cleaned_data['subject'], form.cleaned_data['message'],
email_context,
self.request.event, locale=o.locale, order=o)
o.log_action(
'pretix.plugins.sendmail.order.email.sent',
user=self.request.user,
data={
'subject': form.cleaned_data['subject'].localize(o.locale),
'message': form.cleaned_data['message'].localize(o.locale).format_map(email_context),
'recipient': o.email
}
)
except SendMailException:
failures.append(o.email)
self.request.event.log_action('pretix.plugins.sendmail.sent', self.request.event.log_action('pretix.plugins.sendmail.sent',
user=self.request.user, user=self.request.user,
data=dict(form.cleaned_data)) data=dict(form.cleaned_data))
if failures: messages.success(self.request, _('Your message has been queued and will be sent to %d users in the next minutes.') % len(orders))
messages.error(self.request,
_('Failed to send mails to the following users: {}'.format(' '.join(failures))))
else:
messages.success(self.request, _('Your message has been queued and will be sent to the selected users.'))
return redirect( return redirect(
'plugins:sendmail:send', 'plugins:sendmail:send',