Skip to content

Commit

Permalink
Merge pull request #58 from jproffitt/master
Browse files Browse the repository at this point in the history
Fixes several bugs, and runs CI with django 2.2
  • Loading branch information
Jared Proffitt committed Jun 22, 2019
2 parents 7b67a73 + c25ad1d commit d3e41bd
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 39 deletions.
21 changes: 7 additions & 14 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ python:
- "3.4"
- "3.5"
- "3.6"
- "3.7"

env:
- DJANGO='https://github.com/django/django/archive/master.tar.gz'
- DJANGO='django>=2.2,<3.0'
- DJANGO='django>=2.1,<2.2'
- DJANGO='django>=2.0,<2.1'
- DJANGO='django>=1.11,<1.12'
Expand All @@ -28,36 +30,27 @@ notifications:
email: false

matrix:
include:
- python: 3.7
dist: xenial
sudo: true
env: DJANGO='django>=2.1,<2.2'
- python: 3.7
dist: xenial
sudo: true
env: DJANGO='django>=2.0,<2.1'
- python: 3.7
dist: xenial
sudo: true
env: DJANGO='https://github.com/django/django/archive/master.tar.gz'

exclude:
- python: "2.7"
env: DJANGO='https://github.com/django/django/archive/master.tar.gz'
- python: "2.7"
env: DJANGO='django>=2.0,<2.1'
- python: "2.7"
env: DJANGO='django>=2.1,<2.2'
- python: "2.7"
env: DJANGO='django>=2.2,<3.0'
- python: "3.4"
env: DJANGO='https://github.com/django/django/archive/master.tar.gz'
- python: "3.4"
env: DJANGO='django>=2.1,<2.2'
- python: "3.4"
env: DJANGO='django>=2.2,<3.0'
- python: "3.7"
env: DJANGO='django>=1.11,<1.12'

allow_failures:
- env: DJANGO='https://github.com/django/django/archive/master.tar.gz'

fast_finish: true

after_success:
Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
=== 0.2.1 (unreleased) ===
=== 0.2.1 (06-22-2019) ===
- Fix bug that could occur sometimes in herald.contrib.auth when reversing the password reset url
- Add feature to automatically delete old notifications after configured period of time
- Don't set base_url to empty string when DEBUG==True
- Fix for attaching files to a notification that may be closed before the notification is sent
- Text view for viewing notification now uses the text/plain content type, and the default charset setting


=== 0.2 (08-16-2018) ===
Expand Down
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ We try to make herald support all versions of django that django supports + all

For python, herald supports all versions of python that the above versions of django support.

So as of herald v0.2 we support django 1.11, 2.0, and 2.1, and python 2.7, 3.4, 3.5, 3.6, and 3.7.
So as of herald v0.2 we support django 1.11, 2.0, 2.1, and 2.2, and python 2.7, 3.4, 3.5, 3.6, and 3.7.

## What version of herald do I need if I have django x and python x?

Expand All @@ -33,6 +33,7 @@ If the django/python version combination has a `---` in the table, it is not gua
| **dj 1.11** | \>=0.1.5 | --- | \>=0.1.5 | \>=0.1.5 | \>=0.1.5 | --- |
| **dj 2.0** | --- | --- | \>=0.1.5 | \>=0.1.5 | \>=0.1.5 | \>=0.2 |
| **dj 2.1** | --- | --- | --- | \>=0.2 | \>=0.2 | \>=0.2 |
| **dj 2.2** | --- | --- | --- | \>=0.2 | \>=0.2 | \>=0.2 |


# Installation
Expand Down Expand Up @@ -97,6 +98,25 @@ class WelcomeEmail(EmailNotification):

5. View the sent emails in django admin and even be able to resend it.

## Email options

The following options can be set on the email notification class. For Example:

```
class WelcomeEmail(EmailNotification):
cc = ['test@example.com']
```

- `from_email`: (`str`, default: `settings.DEFAULT_FROM_EMAIL`) email address of sender
- `subject`: (`str`, default: ) email subject
- `to_emails`: (`List[str]`, default: `None`) list of email strings to send to
- `bcc`: (`List[str]`, default: `None`) list of email strings to send as bcc
- `cc`: (`List[str]`, default: `None`) list of email strings to send as cc
- `headers`: (`dict`, default: `None`) extra headers to be passed along to the `EmailMultiAlternatives` object
- `reply_to`: (`List[str]`, default: `None`) list of email strings to send as the Reply-To emails
- `attachments`: (`list`) list of attachments. See "Email Attachments" below for more info


## Automatically Deleting Old Notifications

Herald can automatically delete old notifications whenever a new notification is sent.
Expand Down
13 changes: 6 additions & 7 deletions 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.2.1b2'
__version__ = '0.2.1'

default_app_config = 'herald.apps.HeraldConfig'

Expand All @@ -22,10 +22,12 @@ def register(self, kls):
from .base import NotificationBase

if not issubclass(kls, NotificationBase):
raise ValueError('Notification must subclass NotificationBase.')
raise ValueError('Notification must subclass NotificationBase.')

self._registry.append(kls)

return kls

def unregister(self, kls):
"""
Unregister a notification class
Expand All @@ -35,15 +37,12 @@ def unregister(self, kls):

def register_decorator(self):
"""
Registers the given notification with Django Herold
Registers the given notification with Django Herald
"""

def _notification_wrapper(kls):
return self.register(kls)

self.register(kls)

return kls
return _notification_wrapper


Expand Down
4 changes: 3 additions & 1 deletion herald/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ def _get_encoded_attachments(self):

for attachment in attachments or []:
if isinstance(attachment, File):
attachment.seek(0)
# cannot do with attachment.open() since django 1.11 doesn't support that
attachment.open()
new_attachments.append((attachment.name, attachment.read(), guess_type(attachment.name)[0]))
attachment.close()
else:
new_attachments.append(attachment)

Expand Down
7 changes: 5 additions & 2 deletions herald/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Views for testing notifications. Should not be present in production
"""

from django.conf import settings
from django.http import HttpResponse
from django.views.generic import TemplateView, View

Expand Down Expand Up @@ -44,4 +44,7 @@ def get(self, request, *args, **kwargs): # pylint: disable=W0613

content = obj.render(render_type, context)

return HttpResponse(content, content_type='text/{}'.format(render_type))
render_type = "plain" if render_type == "text" else render_type
charset = settings.DEFAULT_CHARSET

return HttpResponse(content, content_type='text/{}; charset={}'.format(render_type, charset))
23 changes: 18 additions & 5 deletions tests/notifications.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from email.mime.image import MIMEImage

from django.core.files import File

from herald import registry
from herald.base import EmailNotification
from herald.base import TwilioTextNotification


@registry.register
class MyNotification(EmailNotification):
context = {'hello': 'world'}
template_name = 'hello_world'
Expand All @@ -24,21 +27,31 @@ def get_attachments(self):
img,
]

registry.register(MyNotification)


@registry.register
class MyOtherNotification(EmailNotification):
context = {'hello': 'world'}
template_name = 'hello_world'
to_emails = ['test@test.com']

registry.register(MyOtherNotification)


@registry.register
class MyTwilioNotification(TwilioTextNotification):
context = {'hello': 'world'}
template_name = 'hello_world'
to_emails = ['test@test.com']


registry.register(MyTwilioNotification)
@registry.register
class MyNotificationAttachmentOpen(EmailNotification):
context = {'hello': 'world'}
template_name = 'hello_world'
to_emails = ['test@test.com']

def get_attachments(self):
with open('tests/python.jpeg', 'rb') as f:
img = File(f)

img2 = File(open('tests/python.jpeg', 'rb'))

return [img, img2]
10 changes: 5 additions & 5 deletions tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ class TestNotification(EmailNotification):

registry.register(TestNotification)

self.assertEqual(len(registry._registry), 5)
self.assertEqual(len(registry._registry), 6)

registry.unregister(TestNotification)

self.assertEqual(len(registry._registry), 4)
self.assertEqual(len(registry._registry), 5)

def test_register_decorator(self):
@registry.register_decorator()
class TestNotification(EmailNotification):
pass

self.assertEqual(len(registry._registry), 5)
self.assertEqual(len(registry._registry), 6)

registry.unregister(TestNotification)

self.assertEqual(len(registry._registry), 4)
self.assertEqual(len(registry._registry), 5)

def test_register_invalid(self):
class TestNotification(object):
Expand All @@ -35,4 +35,4 @@ class TestNotification(object):
with self.assertRaises(ValueError):
registry.register(TestNotification)

self.assertEqual(len(registry._registry), 4)
self.assertEqual(len(registry._registry), 5)
10 changes: 8 additions & 2 deletions tests/test_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from herald.base import NotificationBase, EmailNotification, TwilioTextNotification
from herald.models import SentNotification
from .notifications import MyNotification
from .notifications import MyNotification, MyNotificationAttachmentOpen


class BaseNotificationTests(TestCase):
Expand Down Expand Up @@ -76,7 +76,13 @@ def test_real_send(self):
def test_real_send_attachments(self):
MyNotification().send()
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].attachments[0][1],'Some Report Data')
self.assertEqual(mail.outbox[0].attachments[0][1], 'Some Report Data')

def test_real_send_attachments_open(self):
MyNotificationAttachmentOpen().send()
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].attachments[0][0], 'tests/python.jpeg')
self.assertEqual(mail.outbox[0].attachments[1][0], 'tests/python.jpeg')

def test_render_no_type(self):
class DummyNotification(NotificationBase):
Expand Down
2 changes: 2 additions & 0 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ def test_preview_text(self):
client = Client()
response = client.get('/herald/0/text/')
self.assertContains(response, 'Hello World')
self.assertEqual(response['content-type'], 'text/plain; charset=utf-8')

def test_preview_html(self):
client = Client()
response = client.get('/herald/0/html/')
self.assertContains(response, '<html><body>Hello World</body></html>')
self.assertEqual(response['content-type'], 'text/html; charset=utf-8')
5 changes: 4 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ envlist =
{py27,py34,py35,py36}-django111,
{py34,py35,py36,py37}-django20,
{py35,py36,py37}-django21,
{py35,py36,py37}-django-latest
{py35,py36,py37}-django22,
{py36,py37,py38}-django-latest


[testenv]
Expand All @@ -13,11 +14,13 @@ basepython =
py35: python3.5
py36: python3.6
py37: python3.7
py38: python3.8


commands = ./runtests.py
deps =
django111: django>=1.11.0,<2.0.0
django20: django>=2.0,<2.1.0
django21: django>=2.1,<2.2.0
django22: django>=2.2,<3.0
django-latest: https://github.com/django/django/archive/master.tar.gz

0 comments on commit d3e41bd

Please sign in to comment.