Skip to content

Commit

Permalink
Merge f0553e4 into 5a2ec73
Browse files Browse the repository at this point in the history
  • Loading branch information
jproffitt committed Aug 30, 2017
2 parents 5a2ec73 + f0553e4 commit fe00d3d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 31 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
=== 0.1.6 (06-30-2017) ===
- Email attachments support


=== 0.1.5 (02-10-2017) ===
- Added decorator to register notifications
- Fixed issue where an extra migration would get created in django 1.10
Expand All @@ -24,4 +28,4 @@


=== 0.1 (07-19-2016) ===
- Initial release
- Initial release
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,23 @@ inherited Notification class. Like this:

## Email Attachments

To send attachments, assign a list of tuples to the attachments attribute of your EmailNotification instance, or override the get_attachments() method. The tuples should consist of the filename, the raw attachment data, and the mimetype. It is up to you to get the attachment data. Like this:
To send attachments, assign a list of attachments to the attachments attribute of your EmailNotification instance, or override the get_attachments() method.

raw_data = get_pdf_data()
Each attachment in the list can be one of the following:

email.attachments = [
('Report.pdf', raw_data, 'application/pdf'),
('report.txt', 'text version of report', 'text/plain')
]
email.send()
1. A tuple which consists of the filename, the raw attachment data, and the mimetype. It is up to you to get the attachment data. Like this:

You can also provide a MIMEBase object instead of a tuple. See the documentation for attachments under EmailMessage Objects/attachments in the Django documentation.
raw_data = get_pdf_data()

email.attachments = [
('Report.pdf', raw_data, 'application/pdf'),
('report.txt', 'text version of report', 'text/plain')
]
email.send()

2. A MIMEBase object. See the documentation for attachments under EmailMessage Objects/attachments in the Django documentation.

3. A django `File` object.

### Inline Attachments

Expand Down
2 changes: 1 addition & 1 deletion herald/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Notification classes. Used for sending texts and emails
"""
__version__ = '0.1.5'
__version__ = '0.1.6'

default_app_config = 'herald.apps.HeraldConfig'

Expand Down
53 changes: 36 additions & 17 deletions herald/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@

import json
from email.mime.base import MIMEBase
from mimetypes import guess_type

import jsonpickle
import six

from django.conf import settings
from django.contrib.sites.models import Site
from django.core.mail import EmailMultiAlternatives
from django.template import TemplateDoesNotExist
from django.template.loader import render_to_string
from django.utils import timezone
from django.core.files import File

from .models import SentNotification

Expand Down Expand Up @@ -76,12 +79,29 @@ def send(self, raise_exception=False, user=None):
subject=subject,
extra_data=json.dumps(extra_data) if extra_data else None,
notification_class='{}.{}'.format(self.__class__.__module__, self.__class__.__name__),
attachments=self._get_encoded_attachments(),
user=user,
attachments=jsonpickle.dumps(self.get_attachments()),
)

return self.resend(sent_notification, raise_exception=raise_exception)

def _get_encoded_attachments(self):
attachments = self.get_attachments()

if attachments:
new_attachments = []

for attachment in attachments:
if isinstance(attachment, File):
attachment.seek(0)
new_attachments.append((attachment.name, attachment.read(), guess_type(attachment.name)[0]))
else:
new_attachments.append(attachment)

attachments = new_attachments

return jsonpickle.dumps(attachments)

def get_recipients(self):
"""
Returns a list of recipients. However the subclass defines that. (emails, phone numbers, etc)
Expand Down Expand Up @@ -113,8 +133,8 @@ def get_subject(self):

def get_attachments(self):
"""
Return a list of attachments or None.
Return a list of attachments or None.
This only works with email.
"""
return None
Expand Down Expand Up @@ -253,7 +273,7 @@ def get_extra_data(self):

def get_attachments(self):
"""
Return a list of attachments or None.
Return a list of attachments or None.
This only works with email.
"""
Expand All @@ -279,19 +299,18 @@ def _send(recipients, text_content=None, html_content=None, sent_from=None, subj
if html_content:
mail.attach_alternative(html_content, 'text/html')

if attachments:
for attachment in attachments:
# All mimebase attachments must have a Content-ID or Content-Disposition header
# or they will show up as unnamed attachments"
if isinstance(attachment, MIMEBase):
if attachment.get('Content-ID',False):
# if you are sending attachment with content id,
# subtype must be 'related'.
mail.mixed_subtype = 'related'

mail.attach(attachment)
else:
mail.attach(*attachment)
for attachment in (attachments or []):
# All mimebase attachments must have a Content-ID or Content-Disposition header
# or they will show up as unnamed attachments"
if isinstance(attachment, MIMEBase):
if attachment.get('Content-ID', False):
# if you are sending attachment with content id,
# subtype must be 'related'.
mail.mixed_subtype = 'related'

mail.attach(attachment)
else:
mail.attach(*attachment)

mail.send()

Expand Down
10 changes: 6 additions & 4 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[tox]
envlist =
{py27,py32,py33,py34}-django{17,18},
{py27,py34,py35}-django19,
{py27,py34,py35}-django110,
{py27,py34,py35}-django-latest
{py27,py32,py33,py34,py35}-django18,
{py27,py34,py35}-django{19,110},
{py27,py34,py35,py36}-django111,
{py34,py35,py36}-django-latest


[testenv]
Expand All @@ -13,11 +13,13 @@ basepython =
py33: python3.3
py34: python3.4
py35: python3.5
py36: python3.6


commands = ./runtests.py
deps =
django18: django>=1.8.0,<1.9.0
django19: django>=1.9.0,<1.10.0
django110: django>=1.10.0,<1.11.0
django111: django>=1.11.0,<1.12.0
django-latest: https://github.com/django/django/archive/master.tar.gz

0 comments on commit fe00d3d

Please sign in to comment.