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

#47 Support inline images #64

Merged
merged 4 commits into from Sep 26, 2016
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,6 +1,10 @@
CHANGELOG for python-postmark
===============================

Version 0.4.10
--------------
- Added inline images support (#47)

Version 0.4.9
-------------
- Tornado mixin (tigrus)
Expand Down
8 changes: 3 additions & 5 deletions README.md
Expand Up @@ -21,6 +21,9 @@ See [CONTRIBUTORS.md](https://github.com/themartorana/python-postmark/blob/maste
Changelog
----------

Version 0.4.10
- Added inline images support (issue #47, PR #64)

Version 0.4.9
- Tornado mixin (tigrus)
- PMJSONEncoder unicode changes (mattrobenolt)
Expand All @@ -37,11 +40,6 @@ Version 0.4.6
Version 0.4.5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be removed now?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're limiting the number of versions shown in the README

- Fix for Python 3 support (issue #42, PR #43) (mflaxman)

Version 0.4.4
- Minor code cleanup (Stranger6667)
- Fix for Django 1.5+ ugettext_lazy strings being improperly converted (#11, #41) (justinabrahms, rduffield)
- Demo brought up to Django 1.6 (catskul)

*[See full changelog](https://github.com/themartorana/python-postmark/blob/master/CHANGELOG.md)*


Expand Down
2 changes: 1 addition & 1 deletion postmark/__init__.py
@@ -1,4 +1,4 @@
__version__ = '0.4.8'
__version__ = '0.4.10'
__author__ = "Dave Martorana (http://davemartorana.com), Richard Cooper (http://frozenskys.com), Bill Jones (oraclebill), Dmitry Golomidov (deeGraYve)"
__date__ = '2010-April-14'
__url__ = 'http://postmarkapp.com'
Expand Down
35 changes: 25 additions & 10 deletions postmark/core.py
Expand Up @@ -387,17 +387,32 @@ def to_json_message(self):
attachments = []
for attachment in self.__attachments:
if isinstance(attachment, tuple):
attachments.append({
"Name": attachment[0],
"Content": attachment[1],
"ContentType": attachment[2],
})
file_item = {
"Name": attachment[0],
"Content": attachment[1],
"ContentType": attachment[2],
}
# If need add Content-ID header:
if len(attachment) >= 4 and attachment[3]:
file_item["ContentID"] = attachment[3]
elif isinstance(attachment, MIMEBase):
attachments.append({
"Name": attachment.get_filename(),
"Content": attachment.get_payload(),
"ContentType": attachment.get_content_type(),
})
file_item = {
"Name": attachment.get_filename(),
"Content": attachment.get_payload(),
"ContentType": attachment.get_content_type(),
}
content_id = attachment.get("Content-ID")
if content_id:
# Because postmarkapp api required clear value. Not enclosed in angle brackets:
if content_id.startswith("<") and content_id.endswith(">"):
content_id = content_id[1:-1]
# Postmarkapp will mark attachment as "inline" only if "ContentID" field starts with "cid":
if (attachment.get("Content-Disposition") or "").startswith("inline"):
content_id = "cid:%s" % content_id
file_item["ContentID"] = content_id
else:
continue
attachments.append(file_item)
json_message['Attachments'] = attachments

return json_message
Expand Down
5 changes: 4 additions & 1 deletion setup.py
@@ -1,8 +1,11 @@
from distutils.core import setup

import postmark


setup(
name="python-postmark",
version="0.4.9",
version=postmark.__version__,
packages=['postmark'],
author="Dave Martorana (http://davemartorana.com), Richard Cooper (http://frozenskys.com), Bill Jones (oraclebill), Dmitry Golomidov (deeGraYve)",
license='BSD',
Expand Down
28 changes: 27 additions & 1 deletion tests.py
@@ -1,6 +1,6 @@
import sys
import unittest

from email.mime.image import MIMEImage

from io import BytesIO

Expand Down Expand Up @@ -52,6 +52,32 @@ def test_500_error_server_error(self):
500, '', {}, None)):
self.assertRaises(PMMailServerErrorException, message.send)

def test_inline_attachments(self):
image = MIMEImage('image_file', 'png', name='image.png')
image_with_id = MIMEImage('inline_image_file', 'png', name='image_with_id.png')
image_with_id.add_header('Content-ID', '<image2@postmarkapp.com>')
inline_image = MIMEImage('inline_image_file', 'png', name='inline_image.png')
inline_image.add_header('Content-ID', '<image3@postmarkapp.com>')
inline_image.add_header('Content-Disposition', 'inline', filename='inline_image.png')

json_message = PMMail(
sender='from@example.com', to='to@example.com', subject='Subject', text_body='Body', api_key='test',
attachments=[
('TextFile', 'content', 'text/plain'),
('InlineImage', 'image_content', 'image/png', 'cid:image@postmarkapp.com'),
image,
image_with_id,
inline_image,
]
).to_json_message()
assert json_message['Attachments'] == [
{'Name': 'TextFile', 'Content': 'content', 'ContentType': 'text/plain'},
{'Name': 'InlineImage', 'Content': 'image_content', 'ContentType': 'image/png', 'ContentID': 'cid:image@postmarkapp.com'},
{'Name': 'image.png', 'Content': 'aW1hZ2VfZmlsZQ==\n', 'ContentType': 'image/png'},
{'Name': 'image_with_id.png', 'Content': 'aW5saW5lX2ltYWdlX2ZpbGU=\n', 'ContentType': 'image/png', 'ContentID': 'image2@postmarkapp.com'},
{'Name': 'inline_image.png', 'Content': 'aW5saW5lX2ltYWdlX2ZpbGU=\n', 'ContentType': 'image/png', 'ContentID': 'cid:image3@postmarkapp.com'},
]


class PMBatchMailTests(unittest.TestCase):
def test_406_error_inactive_recipient(self):
Expand Down