Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get feat/user_preferences up to date #36

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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