From a8eb0ffe97aa1a2ef3182ea7a728c4bf5a6fd157 Mon Sep 17 00:00:00 2001 From: Stephan Telling Date: Sun, 30 Apr 2017 11:32:49 +0200 Subject: [PATCH] use filefield for email attachments, add logging for emailworker --- src/shop/email.py | 18 +++++++++--------- src/utils/email.py | 26 +++++++++++++++++--------- src/utils/models.py | 6 ++++-- src/utils/outgoingemailworker.py | 21 ++++++++++++++++----- 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/shop/email.py b/src/shop/email.py index 5181050c..de18e082 100644 --- a/src/shop/email.py +++ b/src/shop/email.py @@ -1,4 +1,4 @@ -from utils.email import _send_email +from utils.email import add_outgoing_email import logging logger = logging.getLogger("bornhack.%s" % __name__) @@ -11,11 +11,11 @@ def send_creditnote_email(creditnote): subject = 'BornHack creditnote %s' % creditnote.pk - # send mail - return _send_email( + # add email to outgoing email queue + return add_outgoing_email( text_template='emails/creditnote_email.txt', html_template='emails/creditnote_email.html', - recipient=creditnote.user.email, + recipients=creditnote.user.email, formatdict=formatdict, subject=subject, attachment=creditnote.pdf.read(), @@ -33,11 +33,11 @@ def send_invoice_email(invoice): subject = 'BornHack invoice %s' % invoice.pk - # send mail - return _send_email( + # add email to outgoing email queue + return add_outgoing_email( text_template='emails/invoice_email.txt', html_template='emails/invoice_email.html', - recipient=invoice.order.user.email, + recipients=invoice.order.user.email, formatdict=formatdict, subject=subject, attachment=invoice.pdf.read(), @@ -46,8 +46,8 @@ def send_invoice_email(invoice): def send_test_email(recipient): - return _send_email( + return add_outgoing_email( text_template='emails/testmail.txt', - recipient=recipient, + recipients=recipient, subject='testmail from bornhack website' ) diff --git a/src/utils/email.py b/src/utils/email.py index 6fbd10cb..82f702e3 100644 --- a/src/utils/email.py +++ b/src/utils/email.py @@ -1,7 +1,8 @@ from django.core.mail import EmailMultiAlternatives +from django.core.validators import validate_email +from django.core.files.base import ContentFile from django.conf import settings from django.template.loader import render_to_string -from django.core.validators import validate_email from .models import OutgoingEmail import logging logger = logging.getLogger("bornhack.%s" % __name__) @@ -13,7 +14,7 @@ def _send_email( subject, html_template='', sender='BornHack ', - attachment='', + attachment=None, attachment_filename='' ): if not isinstance(recipient, list): @@ -39,13 +40,16 @@ def _send_email( # is there a pdf attachment to this mail? if attachment: msg.attach(attachment_filename, attachment, 'application/pdf') - except Exception as e: logger.exception('exception while rendering email: {}'.format(e)) return False # send the email - msg.send() + try: + msg.send(fail_silently=False) + except Exception as e: + logger.exception('exception while sending email: {}'.format(e)) + return False return True @@ -57,7 +61,7 @@ def add_outgoing_email( subject, html_template='', sender='BornHack ', - attachment='', + attachment=None, attachment_filename='' ): """ adds an email to the outgoing queue @@ -74,13 +78,17 @@ def add_outgoing_email( else: validate_email(recipients) - OutgoingEmail.objects.create( + email = OutgoingEmail.objects.create( text_template=text_template, html_template=html_template, subject=subject, sender=sender, - recipient=recipients, - attachment=attachment, - attachment_filename=attachment_filename + recipient=recipients ) + + if attachment: + django_file = ContentFile(attachment) + django_file.name = attachment_filename + email.attachment.save(attachment_filename, django_file, save=True) + return True diff --git a/src/utils/models.py b/src/utils/models.py index 51c10bbb..5095c1f6 100644 --- a/src/utils/models.py +++ b/src/utils/models.py @@ -76,6 +76,8 @@ class OutgoingEmail(CreatedUpdatedModel): html_template = models.TextField(blank=True) recipient = models.CharField(max_length=500) sender = models.CharField(max_length=500) - attachment = models.CharField(max_length=500, blank=True) - attachment_filename = models.CharField(max_length=500, blank=True) + attachment = models.FileField(blank=True) processed = models.BooleanField(default=False) + + def __str__(self): + return 'Email {} for {}'.format(self.subject, self.recipient) diff --git a/src/utils/outgoingemailworker.py b/src/utils/outgoingemailworker.py index 1146b874..cceaf7d0 100644 --- a/src/utils/outgoingemailworker.py +++ b/src/utils/outgoingemailworker.py @@ -12,19 +12,30 @@ def do_work(): """ not_processed_email = OutgoingEmail.objects.filter(processed=False) + logger.info('about to process {} emails'.format(len(not_processed_email))) for email in not_processed_email: if ',' in email.recipient: recipient = email.recipient.split(',') else: recipient = [email.recipient] - _send_email( + attachment = None + attachment_filename = '' + if email.attachment: + attachment = email.attachment.read() + attachment_filename = email.attachment.name + + mail_send_success = _send_email( text_template=email.text_template, recipient=recipient, subject=email.subject, html_template=email.html_template, - attachment=email.attachment, - attachment_filename=email.attachment_filename + attachment=attachment, + attachment_filename=attachment_filename ) - email.processed = True - email.save() + if mail_send_success: + email.processed = True + email.save() + logger.info('successfully sent {}'.format(email)) + else: + logger.error('unable to sent {}'.format(email))