Skip to content

Commit c5e69f1

Browse files
authored
Merge pull request #65 from ambitioninc/develop
1.1.1
2 parents c5e38e6 + 2c37879 commit c5e69f1

File tree

9 files changed

+87
-19
lines changed

9 files changed

+87
-19
lines changed

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
include README.md
22
include LICENSE
3+
recursive-include requirements *

entity_emailer/interface.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import sys
2+
13
from datetime import datetime
24

35
from django.core import mail
46
from entity_event import context_loader
57

68
from entity_emailer.models import Email
9+
from entity_emailer.signals import pre_send
710

811
from entity_emailer.utils import get_medium, get_from_email_address, get_subscribed_email_addresses, \
912
create_email_message, extract_email_subject_from_html_content
@@ -26,7 +29,7 @@ def send_unsent_scheduled_emails():
2629
scheduled__lte=current_time,
2730
sent__isnull=True
2831
).select_related(
29-
'event'
32+
'event__source'
3033
).prefetch_related(
3134
'recipients'
3235
)
@@ -38,14 +41,28 @@ def send_unsent_scheduled_emails():
3841
for email in to_send:
3942
to_email_addresses = get_subscribed_email_addresses(email)
4043
if to_email_addresses:
44+
# Render the email
4145
text_message, html_message = email.render(email_medium)
46+
47+
# Create the email
4248
message = create_email_message(
4349
to_emails=to_email_addresses,
4450
from_email=email.from_address or get_from_email_address(),
4551
subject=email.subject or extract_email_subject_from_html_content(html_message),
4652
text=text_message,
4753
html=html_message,
4854
)
55+
56+
# Fire the pre send signal
57+
pre_send.send(
58+
sender=sys.intern(email.event.source.name),
59+
email=email,
60+
event=email.event,
61+
context=email.event.context,
62+
message=message,
63+
)
64+
65+
# Add the email to the list of emails that need to be sent
4966
emails.append(message)
5067

5168
connection = mail.get_connection()

entity_emailer/signals.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.dispatch import Signal
2+
3+
4+
# An event that will be fired prior to an email being sent
5+
pre_send = Signal(providing_args=['email', 'event', 'context', 'message'])

entity_emailer/tests/interface_tests.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from datetime import datetime
22

33
from django.core import mail
4+
from django.core.mail import EmailMultiAlternatives
45
from django.core.management import call_command
56
from django.test import TestCase, SimpleTestCase
67
from django.test.utils import override_settings
@@ -343,6 +344,36 @@ def test_sends_all_scheduled_emails(self, render_mock, address_mock):
343344
EntityEmailerInterface.send_unsent_scheduled_emails()
344345
self.assertEqual(len(mail.outbox), 2)
345346

347+
@patch('entity_emailer.interface.pre_send')
348+
@patch('entity_emailer.interface.get_subscribed_email_addresses')
349+
@patch.object(Event, 'render', spec_set=True)
350+
def test_send_signals(self, render_mock, address_mock, mock_pre_send):
351+
"""
352+
Test that we properly fire signals during the send process
353+
"""
354+
355+
# Setup the email
356+
render_mock.return_value = ['<p>This is a test html email.</p>', 'This is a test text email.']
357+
address_mock.return_value = ['[email protected]', '[email protected]']
358+
email = g_email(context={
359+
'test': 'test'
360+
}, scheduled=datetime.min)
361+
EntityEmailerInterface.send_unsent_scheduled_emails()
362+
363+
# Assert that we sent the email
364+
self.assertEqual(len(mail.outbox), 1)
365+
366+
# Assert that we called the pre send signal with the proper values
367+
name, args, kwargs = mock_pre_send.send.mock_calls[0]
368+
self.assertEqual(kwargs['sender'], email.event.source.name)
369+
self.assertEqual(kwargs['email'], email)
370+
self.assertEqual(kwargs['event'], email.event)
371+
self.assertEqual(kwargs['context'], {
372+
'test': 'test',
373+
'entity_emailer_id': str(email.view_uid)
374+
})
375+
self.assertIsInstance(kwargs['message'], EmailMultiAlternatives)
376+
346377
@patch('entity_emailer.interface.get_subscribed_email_addresses')
347378
@patch.object(Event, 'render', spec_set=True)
348379
def test_sends_email_with_specified_from_address(self, render_mock, address_mock):

entity_emailer/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.1.0'
1+
__version__ = '1.1.1'

release_notes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
Release Notes
22
=============
33

4+
v1.1.1
5+
------
6+
* Add `pre_send` signal
7+
48
v1.1.0
59
------
610
* Python 3.7

requirements/requirements.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
beautifulsoup4>=4.3.2
2+
Django>=2.0
3+
django-db-mutex>=1.2.0
4+
django-entity>=4.2.0
5+
django-entity-event>=1.2.0
6+
ambition-django-uuidfield>=0.5.0

run_tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from django_nose import NoseTestSuiteRunner
1414

1515

16-
def run_tests(*test_args, **kwargs):
16+
def run(*test_args, **kwargs):
1717
if not test_args:
1818
test_args = ['entity_emailer']
1919

@@ -30,4 +30,4 @@ def run_tests(*test_args, **kwargs):
3030
parser.add_option('--verbosity', dest='verbosity', action='store', default=1, type=int)
3131
(options, args) = parser.parse_args()
3232

33-
run_tests(*args, **options.__dict__)
33+
run(*args, **options.__dict__)

setup.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from os import path
2+
13
import re
24
from setuptools import setup, find_packages
35

@@ -18,6 +20,20 @@ def get_version():
1820
raise RuntimeError('Unable to find version string in {0}.'.format(VERSION_FILE))
1921

2022

23+
def get_requirements(requirements_file):
24+
"""
25+
Gets a list of requirements from requirements.txt.
26+
"""
27+
with open(path.join(path.dirname(__file__), 'requirements', requirements_file)) as requirements_file:
28+
requirements = requirements_file.readlines()
29+
30+
requirements = [r.strip() for r in requirements if r.strip()]
31+
32+
return [
33+
r for r in requirements
34+
if not r.startswith('#') and not r.startswith('-')
35+
]
36+
2137
setup(
2238
name='django-entity-emailer',
2339
version=get_version(),
@@ -41,20 +57,8 @@ def get_version():
4157
'Framework :: Django :: 2.2',
4258
],
4359
license='MIT',
44-
install_requires=[
45-
'beautifulsoup4>=4.3.2',
46-
'Django>=2.0',
47-
'django-db-mutex>=1.2.0',
48-
'django-entity>=4.2.0',
49-
'django-entity-event>=1.2.0',
50-
'ambition-django-uuidfield>=0.5.0',
51-
],
52-
tests_require=[
53-
'django-dynamic-fixture',
54-
'django-nose>=1.4',
55-
'freezegun',
56-
'mock',
57-
],
58-
test_suite='run_tests.run_tests',
60+
install_requires=get_requirements('requirements.txt'),
61+
tests_require=get_requirements('requirements-testing.txt'),
62+
test_suite='run_tests.run',
5963
include_package_data=True,
6064
)

0 commit comments

Comments
 (0)