diff --git a/djrill/mail/backends/djrill.py b/djrill/mail/backends/djrill.py index bb9d459..a2aac59 100644 --- a/djrill/mail/backends/djrill.py +++ b/djrill/mail/backends/djrill.py @@ -62,6 +62,7 @@ class DjrillBackend(BaseEmailBackend): super(DjrillBackend, self).__init__(**kwargs) self.api_key = getattr(settings, "MANDRILL_API_KEY", None) self.api_url = MANDRILL_API_URL + self.session = None self.subaccount = getattr(settings, "MANDRILL_SUBACCOUNT", None) @@ -72,10 +73,33 @@ class DjrillBackend(BaseEmailBackend): self.api_send = self.api_url + "/messages/send.json" self.api_send_template = self.api_url + "/messages/send-template.json" + def open(self): + if not self.session: + try: + self.session = requests.Session() + except: + if not self.fail_silently: + raise + return False + return True + + + def close(self, error=False): + if self.session: + try: + self.session.close() + except: + if not self.fail_silently and not error: + raise + self.session = None + def send_messages(self, email_messages): if not email_messages: return 0 + if not self.open(): + return + num_sent = 0 for message in email_messages: sent = self._send(message) @@ -83,6 +107,8 @@ class DjrillBackend(BaseEmailBackend): if sent: num_sent += 1 + self.close() + return num_sent def _send(self, message): @@ -114,6 +140,7 @@ class DjrillBackend(BaseEmailBackend): except NotSupportedByMandrillError: if not self.fail_silently: + self.close(True) raise return False @@ -127,9 +154,10 @@ class DjrillBackend(BaseEmailBackend): err.args[0] + " in a Djrill message (perhaps it's a merge var?)." " Try converting it to a string or number first.", ) + err.args[1:] + self.close(True) raise err - response = requests.post(api_url, data=api_data) + response = self.session.post(api_url, data=api_data) if response.status_code != 200: @@ -143,6 +171,7 @@ class DjrillBackend(BaseEmailBackend): to['email'] for to in msg_dict.get('to', []) if 'email' in to) if 'from_email' in msg_dict: log_message += " from %s" % msg_dict['from_email'] + self.close(True) raise MandrillAPIError( status_code=response.status_code, response=response, diff --git a/djrill/tests/mock_backend.py b/djrill/tests/mock_backend.py index a675cd9..9fcf7b4 100644 --- a/djrill/tests/mock_backend.py +++ b/djrill/tests/mock_backend.py @@ -21,7 +21,7 @@ class DjrillBackendMockAPITestCase(TestCase): self.raw = six.BytesIO(raw) def setUp(self): - self.patch = patch('requests.post', autospec=True) + self.patch = patch('requests.Session.post', autospec=True) self.mock_post = self.patch.start() self.mock_post.return_value = self.MockResponse() @@ -39,7 +39,7 @@ class DjrillBackendMockAPITestCase(TestCase): raise AssertionError("Mandrill API was not called") (args, kwargs) = self.mock_post.call_args try: - post_url = kwargs.get('url', None) or args[0] + post_url = kwargs.get('url', None) or args[1] except IndexError: raise AssertionError("requests.post was called without an url (?!)") if not post_url.endswith(endpoint): @@ -56,7 +56,7 @@ class DjrillBackendMockAPITestCase(TestCase): raise AssertionError("Mandrill API was not called") (args, kwargs) = self.mock_post.call_args try: - post_data = kwargs.get('data', None) or args[1] + post_data = kwargs.get('data', None) or args[2] except IndexError: raise AssertionError("requests.post was called without data") return json.loads(post_data)