diff --git a/src/pretix/base/services/mail.py b/src/pretix/base/services/mail.py index 51dd5dc958..8d9c90fb23 100644 --- a/src/pretix/base/services/mail.py +++ b/src/pretix/base/services/mail.py @@ -231,7 +231,7 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La attach_tickets=attach_tickets, attach_ical=attach_ical, user=user.pk if user else None, - attach_cached_files=[cf.id for cf in attach_cached_files] if attach_cached_files else [], + attach_cached_files=[(cf.id if isinstance(cf, CachedFile) else cf) for cf in attach_cached_files] if attach_cached_files else [], ) if invoices: diff --git a/src/pretix/plugins/sendmail/forms.py b/src/pretix/plugins/sendmail/forms.py index adef3662b4..1e48f337fb 100644 --- a/src/pretix/plugins/sendmail/forms.py +++ b/src/pretix/plugins/sendmail/forms.py @@ -7,6 +7,7 @@ from i18nfield.forms import I18nFormField, I18nTextarea, I18nTextInput from pretix.base.email import get_available_placeholders from pretix.base.forms import PlaceholderValidator from pretix.base.models import CheckinList, Item, Order, SubEvent +from pretix.control.forms import ExtFileField from pretix.control.forms.widgets import Select2, Select2Multiple @@ -20,6 +21,18 @@ class MailForm(forms.Form): sendto = forms.MultipleChoiceField() # overridden later subject = forms.CharField(label=_("Subject")) message = forms.CharField(label=_("Message")) + attachment = ExtFileField( + label=_("Attachment"), + required=False, + ext_whitelist=( + ".png", ".jpg", ".gif", ".jpeg", ".pdf", ".txt", ".docx", ".gif", ".svg", + ".pptx", ".ppt", ".doc", ".xlsx", ".xls", ".jfif", ".heic", ".heif", ".pages", + ".bmp", ".tif", ".tiff" + ), + help_text=_('Sending an attachment increases the chance of your email not arriving or being sorted into spam folders. We recommend only using PDFs ' + 'of no more than 2 MB in size.'), + max_size=10 * 1024 * 1024 + ) # TODO i18n items = forms.ModelMultipleChoiceField( widget=forms.CheckboxSelectMultiple( attrs={'class': 'scrolling-multiple-choice'} diff --git a/src/pretix/plugins/sendmail/tasks.py b/src/pretix/plugins/sendmail/tasks.py index 5a045930b9..6d3cbb4364 100644 --- a/src/pretix/plugins/sendmail/tasks.py +++ b/src/pretix/plugins/sendmail/tasks.py @@ -10,7 +10,8 @@ from pretix.celery_app import app @app.task(base=ProfiledEventTask, acks_late=True) def send_mails(event: Event, user: int, subject: dict, message: dict, orders: list, items: list, - recipients: str, filter_checkins: bool, not_checked_in: bool, checkin_lists: list) -> None: + recipients: str, filter_checkins: bool, not_checked_in: bool, checkin_lists: list, + attachments: list = None) -> None: failures = [] user = User.objects.get(pk=user) if user else None orders = Order.objects.filter(pk__in=orders, event=event) @@ -61,7 +62,8 @@ def send_mails(event: Event, user: int, subject: dict, message: dict, orders: li event, locale=o.locale, order=o, - position=p + position=p, + attach_cached_files=attachments ) o.log_action( 'pretix.plugins.sendmail.order.email.sent.attendee', @@ -87,7 +89,8 @@ def send_mails(event: Event, user: int, subject: dict, message: dict, orders: li email_context, event, locale=o.locale, - order=o + order=o, + attach_cached_files=attachments ) o.log_action( 'pretix.plugins.sendmail.order.email.sent', diff --git a/src/pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html b/src/pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html index 76aa4093d4..27a61b5b64 100644 --- a/src/pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html +++ b/src/pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html @@ -5,7 +5,7 @@ {% block content %}

{% trans "Send out emails" %}

{% block inner %} -
+ {% csrf_token %} {% bootstrap_field form.recipients layout='horizontal' %} {% bootstrap_field form.sendto layout='horizontal' %} @@ -32,6 +32,7 @@ {% bootstrap_field form.subject layout='horizontal' %} {% bootstrap_field form.message layout='horizontal' %} + {% bootstrap_field form.attachment layout='horizontal' %} {% if request.method == "POST" %}
{% trans "E-mail preview" %} diff --git a/src/pretix/plugins/sendmail/views.py b/src/pretix/plugins/sendmail/views.py index db71dae427..f174fcbf81 100644 --- a/src/pretix/plugins/sendmail/views.py +++ b/src/pretix/plugins/sendmail/views.py @@ -1,4 +1,5 @@ import logging +from datetime import timedelta import bleach from django.contrib import messages @@ -11,7 +12,7 @@ from django.views.generic import FormView, ListView from pretix.base.email import get_available_placeholders from pretix.base.i18n import LazyI18nString, language -from pretix.base.models import LogEntry, Order, OrderPosition +from pretix.base.models import CachedFile, LogEntry, Order, OrderPosition from pretix.base.models.event import SubEvent from pretix.base.services.mail import TolerantDict from pretix.base.templatetags.rich_text import markdown_compile_email @@ -136,19 +137,34 @@ class SenderView(EventPermissionRequiredMixin, FormView): return self.get(self.request, *self.args, **self.kwargs) + attachment = None + if 'attachment' in self.request.FILES: + attachment = self.request.FILES['attachment'] + cf = CachedFile.objects.create( + expires=now() + timedelta(days=1), + date=now(), + filename=attachment.name, + type=attachment.content_type, + ) + cf.file.save(attachment.name, attachment.file) + cf.save() + kwargs = { + 'recipients': form.cleaned_data['recipients'], + 'event': self.request.event.pk, + 'user': self.request.user.pk, + 'subject': form.cleaned_data['subject'].data, + 'message': form.cleaned_data['message'].data, + 'orders': [o.pk for o in orders], + 'items': [i.pk for i in form.cleaned_data.get('items')], + 'not_checked_in': form.cleaned_data.get('not_checked_in'), + 'checkin_lists': [i.pk for i in form.cleaned_data.get('checkin_lists')], + 'filter_checkins': form.cleaned_data.get('filter_checkins'), + } + if attachment is not None: + kwargs['attachments'] = [cf.id] + send_mails.apply_async( - kwargs={ - 'recipients': form.cleaned_data['recipients'], - 'event': self.request.event.pk, - 'user': self.request.user.pk, - 'subject': form.cleaned_data['subject'].data, - 'message': form.cleaned_data['message'].data, - 'orders': [o.pk for o in orders], - 'items': [i.pk for i in form.cleaned_data.get('items')], - 'not_checked_in': form.cleaned_data.get('not_checked_in'), - 'checkin_lists': [i.pk for i in form.cleaned_data.get('checkin_lists')], - 'filter_checkins': form.cleaned_data.get('filter_checkins'), - } + kwargs=kwargs ) self.request.event.log_action('pretix.plugins.sendmail.sent', user=self.request.user,