Add option to attach calendar files to emails (#1457)

This commit is contained in:
Raphael Michel
2019-10-21 10:41:22 +02:00
committed by GitHub
parent 2b18621c76
commit 19b10e3ca4
6 changed files with 43 additions and 9 deletions

View File

@@ -723,7 +723,8 @@ class Order(LockModel, LoggedModel):
def send_mail(self, subject: str, template: Union[str, LazyI18nString],
context: Dict[str, Any]=None, log_entry_type: str='pretix.event.order.email.sent',
user: User=None, headers: dict=None, sender: str=None, invoices: list=None,
auth=None, attach_tickets=False, position: 'OrderPosition'=None, auto_email=True):
auth=None, attach_tickets=False, position: 'OrderPosition'=None, auto_email=True,
attach_ical=False):
"""
Sends an email to the user that placed this order. Basically, this method does two things:
@@ -740,6 +741,7 @@ class Order(LockModel, LoggedModel):
:param headers: Dictionary with additional mail headers
:param sender: Custom email sender.
:param attach_tickets: Attach tickets of this order, if they are existing and ready to download
:param attach_ical: Attach relevant ICS files
:param position: An order position this refers to. If given, no invoices will be attached, the tickets will
only be attached for this position and child positions, the link will only point to the
position and the attendee email will be used if available.
@@ -763,7 +765,7 @@ class Order(LockModel, LoggedModel):
recipient, subject, template, context,
self.event, self.locale, self, headers=headers, sender=sender,
invoices=invoices, attach_tickets=attach_tickets,
position=position, auto_email=auto_email
position=position, auto_email=auto_email, attach_ical=attach_ical
)
except SendMailException:
raise
@@ -779,6 +781,7 @@ class Order(LockModel, LoggedModel):
'recipient': recipient,
'invoices': [i.pk for i in invoices] if invoices else [],
'attach_tickets': attach_tickets,
'attach_ical': attach_ical,
}
)
@@ -790,7 +793,7 @@ class Order(LockModel, LoggedModel):
self.send_mail(
email_subject, email_template, email_context,
'pretix.event.order.email.resend', user=user, auth=auth,
attach_tickets=True
attach_tickets=True,
)
@property
@@ -1334,7 +1337,7 @@ class OrderPayment(models.Model):
email_subject, email_template, email_context,
'pretix.event.order.email.order_paid', user,
invoices=[], position=position,
attach_tickets=True
attach_tickets=True, attach_ical=True
)
except SendMailException:
logger.exception('Order paid email could not be sent')
@@ -1351,7 +1354,7 @@ class OrderPayment(models.Model):
email_subject, email_template, email_context,
'pretix.event.order.email.order_paid', user,
invoices=[invoice] if invoice and self.order.event.settings.invoice_email_attachment else [],
attach_tickets=True
attach_tickets=True, attach_ical=True
)
except SendMailException:
logger.exception('Order paid email could not be sent')

View File

@@ -31,6 +31,7 @@ from pretix.base.services.tickets import get_tickets_for_order
from pretix.base.signals import email_filter, global_email_filter
from pretix.celery_app import app
from pretix.multidomain.urlreverse import build_absolute_uri
from pretix.presale.ical import get_ical
logger = logging.getLogger('pretix.base.mail')
INVALID_ADDRESS = 'invalid-pretix-mail-address'
@@ -50,7 +51,7 @@ class SendMailException(Exception):
def mail(email: str, subject: str, template: Union[str, LazyI18nString],
context: Dict[str, Any]=None, event: Event=None, locale: str=None,
order: Order=None, position: OrderPosition=None, headers: dict=None, sender: str=None,
invoices: list=None, attach_tickets=False, auto_email=True, user=None):
invoices: list=None, attach_tickets=False, auto_email=True, user=None, attach_ical=False):
"""
Sends out an email to a user. The mail will be sent synchronously or asynchronously depending on the installation.
@@ -85,6 +86,8 @@ def mail(email: str, subject: str, template: Union[str, LazyI18nString],
:param attach_tickets: Whether to attach tickets to this email, if they are available to download.
:param attach_ical: Whether to attach relevant ``.ics`` files to this email
:param auto_email: Whether this email is auto-generated
:param user: The user this email is sent to
@@ -216,6 +219,7 @@ def mail(email: str, subject: str, template: Union[str, LazyI18nString],
order=order.pk if order else None,
position=position.pk if position else None,
attach_tickets=attach_tickets,
attach_ical=attach_ical,
user=user.pk if user else None
)
@@ -231,7 +235,8 @@ def mail(email: str, subject: str, template: Union[str, LazyI18nString],
@app.task(base=TransactionAwareTask, bind=True)
def mail_send_task(self, *args, to: List[str], subject: str, body: str, html: str, sender: str,
event: int=None, position: int=None, headers: dict=None, bcc: List[str]=None,
invoices: List[int]=None, order: int=None, attach_tickets=False, user=None) -> bool:
invoices: List[int]=None, order: int=None, attach_tickets=False, user=None,
attach_ical=False) -> bool:
email = EmailMultiAlternatives(subject, body, sender, to=to, bcc=bcc, headers=headers)
if html is not None:
html_with_cid, cid_images = replace_images_with_cid_paths(html)
@@ -301,6 +306,20 @@ def mail_send_task(self, *args, to: List[str], subject: str, body: str, html: st
'invoices': [],
}
)
if attach_ical:
ical_events = set()
if event.has_subevents:
if position:
ical_events.add(position.subevent)
else:
for p in order.positions.all():
ical_events.add(p.subevent)
else:
ical_events.add(order.event)
for i, e in enumerate(ical_events):
cal = get_ical([e])
email.attach('event-{}.ics'.format(i), cal.serialize(), 'text/calendar')
email = email_filter.send_chained(event, 'message', message=email, order=order, user=user)

View File

@@ -707,7 +707,8 @@ def _order_placed_email(event: Event, order: Order, pprov: BasePaymentProvider,
email_subject, email_template, email_context,
log_entry,
invoices=[invoice] if invoice and event.settings.invoice_email_attachment else [],
attach_tickets=True
attach_tickets=True,
attach_ical=event.settings.mail_attach_ical
)
except SendMailException:
logger.exception('Order received email could not be sent')
@@ -723,7 +724,8 @@ def _order_placed_email_attendee(event: Event, order: Order, position: OrderPosi
log_entry,
invoices=[],
attach_tickets=True,
position=position
position=position,
attach_ical=event.settings.mail_attach_ical
)
except SendMailException:
logger.exception('Order received email could not be sent to attendee')

View File

@@ -297,6 +297,10 @@ DEFAULTS = {
'default': 'classic',
'type': str
},
'mail_attach_ical': {
'default': 'False',
'type': bool
},
'mail_prefix': {
'default': None,
'type': str

View File

@@ -976,6 +976,11 @@ class MailSettingsForm(SettingsForm):
required=False,
max_length=255
)
mail_attach_ical = forms.BooleanField(
label=_("Attach calendar files"),
help_text=_("If enabled, we will attach an .ics calendar file to order confirmation emails."),
required=False
)
mail_text_signature = I18nFormField(
label=_("Signature"),

View File

@@ -16,6 +16,7 @@
{% bootstrap_field form.mail_from_name layout="control" %}
{% bootstrap_field form.mail_text_signature layout="control" %}
{% bootstrap_field form.mail_bcc layout="control" %}
{% bootstrap_field form.mail_attach_ical layout="control" %}
</fieldset>
<fieldset>
<legend>{% trans "E-mail design" %}</legend>