Skip to content

Commit

Permalink
Make sending email more robust
Browse files Browse the repository at this point in the history
Fail earlier when creating message with invalid email address, catch ValidationErrors when sending mails in batch in order to handle gracefully by showing message
  • Loading branch information
Compizfox committed Oct 9, 2017
1 parent c09ddbc commit 0fc69f3
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 21 deletions.
7 changes: 6 additions & 1 deletion app/forms/RegistrationsForm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from bootstrap3_datetime.widgets import DateTimePicker
from django_auth_ldap.backend import LDAPBackend
from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError
from django.contrib import messages

from app.models import User, Registration
from app.mails import RegistrationNotificationMail
Expand Down Expand Up @@ -52,4 +54,7 @@ def save(self, mailer, request):
registration.save()

# Send mail to participant
mailer.send(RegistrationNotificationMail(self.event, self.cleaned_data['username'], request))
try:
mailer.send(RegistrationNotificationMail(self.event, self.cleaned_data['username'], request))
except ValidationError:
messages.error(request, _("Kon email niet verzenden aan {} {} (ongeldig emailadres)").format(self.cleaned_data['username'].first_name, self.cleaned_data['username'].last_name))
Binary file modified app/locale/en/LC_MESSAGES/django.mo
Binary file not shown.
40 changes: 23 additions & 17 deletions app/locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ msgid ""
msgstr ""
"Project-Id-Version: Inschrijflijst v3.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-16 18:09+0200\n"
"PO-Revision-Date: 2017-09-16 18:19+0200\n"
"POT-Creation-Date: 2017-10-09 20:47+0200\n"
"PO-Revision-Date: 2017-10-09 20:48+0200\n"
"Last-Translator: Lars Veldscholte <[email protected]>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language-Team: \n"
"X-Generator: Poedit 2.0.3\n"

#: .\app\forms\EventForm.py:39 .\app\templates\event_detail.html:45
#: .\app\templates\event_edit.html:23
Expand Down Expand Up @@ -97,7 +99,7 @@ msgid "<p>Beste {{ name }},</p>"
msgstr "<p>Dear {{ name }},</p>"

#: .\app\forms\RegistrationForm.py:14 .\app\forms\RegistrationForm.py:29
#: .\app\templates\event_list.html:38
#: .\app\templates\event_list.html:39
msgid "Ingeschreven"
msgstr "Enrolled"

Expand Down Expand Up @@ -183,7 +185,7 @@ msgstr "Step 1: Link Google account"
msgid "Stap 2: Selecteer juiste agenda (Jaarcirkel)"
msgstr "Step 2: Select appropriate calendar"

#: .\app\templates\admin.html:46 .\app\templates\event_detail.html:86
#: .\app\templates\admin.html:46 .\app\templates\event_detail.html:87
msgid "Opslaan"
msgstr "Save"

Expand Down Expand Up @@ -250,11 +252,11 @@ msgstr "Enrolled:"
msgid "Inschrijfdatum"
msgstr "Enrolment date"

#: .\app\templates\event_detail.html:91
#: .\app\templates\event_detail.html:92
msgid "Schrijf je commissie in:"
msgstr "Enrol your committee:"

#: .\app\templates\event_detail.html:103
#: .\app\templates\event_detail.html:105
msgid ""
"Deze inschrijflijst zit vol. Je kunt je nog wel inschrijven als reserve; je "
"komt dan op de lijst te staan als iemand zich uitschrijft. Selectie is op "
Expand All @@ -263,7 +265,7 @@ msgstr ""
"This event is full. You can still enrol as backup; you will enter as a "
"participant when someone disenrolls. Selection is on basis of enrolment date."

#: .\app\templates\event_detail.html:108
#: .\app\templates\event_detail.html:110
#, python-format
msgid ""
"De deadline voor deze inschrijflijst is verstreken. Je kunt je niet meer in- "
Expand All @@ -281,21 +283,21 @@ msgstr "Edit"
msgid "Uitschrijfdatum"
msgstr "Disenrolment date"

#: .\app\templates\event_edit.html:48
#: .\app\templates\event_edit.html:49
msgid "Inschrijvingen toevoegen"
msgstr "Add enrolments"

#: .\app\templates\event_edit.html:49
#: .\app\templates\event_edit.html:50
msgid ""
"Alleen ingeschreven deelnemers die niet op de reservelijst staan worden "
"geëxporteerd"
msgstr "Only enrolled participants who are not backup will be exported"

#: .\app\templates\event_edit.html:49
#: .\app\templates\event_edit.html:50
msgid "Exporteren"
msgstr "Export"

#: .\app\templates\event_edit.html:50 .\app\templates\mail_create.html:6
#: .\app\templates\event_edit.html:51 .\app\templates\mail_create.html:6
#: .\app\templates\mail_create.html:11
msgid "Mass mail"
msgstr "Mass mail"
Expand All @@ -305,19 +307,19 @@ msgstr "Mass mail"
msgid "Inschrijflijsten"
msgstr "Events"

#: .\app\templates\event_list.html:36
#: .\app\templates\event_list.html:37
msgid "Details"
msgstr "Details"

#: .\app\templates\event_list.html:40
#: .\app\templates\event_list.html:41
msgid "Inschrijving sluit binnenkort!"
msgstr "Enrolment closes soon!"

#: .\app\templates\event_list.html:42
#: .\app\templates\event_list.html:43
msgid "Inschrijving gesloten!"
msgstr "Enrolment closed!"

#: .\app\templates\event_list.html:45
#: .\app\templates\event_list.html:46
msgid "Nieuw!"
msgstr "New!"

Expand Down Expand Up @@ -563,15 +565,19 @@ msgstr "Google account linked!"
msgid "Commissies geupdatet!"
msgstr "Committees updated!"

#: .\app\views\EventView.py:79
#: .\app\views\EventView.py:72
msgid "Inschrijflijst bijgewerkt!"
msgstr "Event edited!"

#: .\app\views\EventView.py:96
#: .\app\views\EventView.py:89
msgid "Inschrijflijst aangemaakt!"
msgstr "Event created!"

#: .\app\views\MailView.py:45
msgid "Kon email niet verzenden aan {} {} (ongeldig emailadres)"
msgstr "Could not send email message to {} {} (invalid email address)"

#: .\app\views\MailView.py:49
msgid "{} emails verstuurd!"
msgstr "{} messages sent!"

Expand Down
2 changes: 2 additions & 0 deletions app/mails.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ def __init__(self, event, recipient_user, request):
}
self.recipients = [recipient_user.email]
self.reply_to = request.user.email

self.validate()
10 changes: 7 additions & 3 deletions app/views/MailView.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.shortcuts import render, redirect
from django.conf import settings
from django.utils.translation import ugettext as _
from django.core.exceptions import ValidationError

from lib.ResourceView import ResourceView, bind_model
from lib.Mail import CustomMail, Mailer
Expand Down Expand Up @@ -36,9 +37,12 @@ def store(self, request, event):
for reg in event.registration_set.filter(withdrawn_at=None):
# Only send mail if not withdrawn, and send mail to backup depending on form setting
if not reg.is_backup() or form.cleaned_data['recipients'] == 'all':
msg = CustomMail(event.committee.email, reg.participant, form.cleaned_data['subject'], form.cleaned_data['body'])
mailer.send(msg)
i += 1
try:
msg = CustomMail(event.committee.email, reg.participant, form.cleaned_data['subject'], form.cleaned_data['body'])
mailer.send(msg)
i += 1
except ValidationError:
messages.error(request, _("Kon email niet verzenden aan {} {} (ongeldig emailadres)").format(reg.participant.first_name, reg.participant.last_name))
else:
return self.create(request, event.pk, form=form)

Expand Down
9 changes: 9 additions & 0 deletions lib/Mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django.template.loader import render_to_string
from django.template import Context, Template
from django.core.validators import validate_email
from html2text import html2text
from post_office import mail

Expand All @@ -20,6 +21,8 @@ def __init__(self):
self.reply_to = ''
self.request = None

self.validate()

def get_html_body(self):
return render_to_string(self.template, self.context, self.request)

Expand All @@ -35,6 +38,10 @@ def get_recipients(self):
def get_reply_to(self):
return self.reply_to

def validate(self):
for email in self.recipients:
validate_email(email)


class CustomMail(Mail):
"""
Expand All @@ -50,6 +57,8 @@ def __init__(self, reply_to, user, subject, template_string):
self.reply_to = reply_to
self.template_string = template_string

self.validate()

def get_html_body(self):
"""
Renders the template from the given string and context and returns the message body
Expand Down

0 comments on commit 0fc69f3

Please sign in to comment.