mirror of
https://github.com/pretix/pretix.git
synced 2026-05-04 15:04:03 +00:00
Sendmail plugin: Allow to attach a file to emails (#1814)
* sendmail: allow to attach files to emails * Fix mixup of model objects and model IDs * Attach to order-level emails, not only position-level emails * Give attachments a proper file type * Add a warning note about higher spam chances Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
This commit is contained in:
@@ -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'}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block content %}
|
||||
<h1>{% trans "Send out emails" %}</h1>
|
||||
{% block inner %}
|
||||
<form class="form-horizontal" method="post" action="">
|
||||
<form class="form-horizontal" method="post" action="" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_field form.recipients layout='horizontal' %}
|
||||
{% bootstrap_field form.sendto layout='horizontal' %}
|
||||
@@ -32,6 +32,7 @@
|
||||
</div>
|
||||
{% bootstrap_field form.subject layout='horizontal' %}
|
||||
{% bootstrap_field form.message layout='horizontal' %}
|
||||
{% bootstrap_field form.attachment layout='horizontal' %}
|
||||
{% if request.method == "POST" %}
|
||||
<fieldset>
|
||||
<legend>{% trans "E-mail preview" %}</legend>
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user