Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
amcgregor committed Sep 16, 2019
2 parents 0193aab + 4208b07 commit 04bfd36
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 9 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Expand Up @@ -9,9 +9,11 @@ branches:
python:
- "2.7"
- "pypy"
- "3.3"
- "pypy3"
- "3.4"
- "3.5"
- "3.6"
- "3.7"

install:
- travis_retry pip install --upgrade setuptools pip codecov 'setuptools_scm>=1.9'
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
@@ -1,4 +1,4 @@
Copyright © 2006-2016 Alice Bevan-McGregor and contributors.
Copyright © 2006-2019 Alice Bevan-McGregor and contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
6 changes: 4 additions & 2 deletions README.textile
Expand Up @@ -2,7 +2,7 @@ h1(#title). Marrow Mailer

bq(subtitle). A highly efficient and modular mail delivery framework for Python 2.6+ and 3.2+, formerly called TurboMail.

bq(byline). (C) 2006-2016, Alice Bevan-McGregor and contributors.
bq(byline). (C) 2006-2019, Alice Bevan-McGregor and contributors.

bq(byline). "https://github.com/marrow/mailer":github-project

Expand Down Expand Up @@ -43,6 +43,8 @@ Installing @marrow.mailer@ is easy, just execute the following in a terminal: [2

If you add @marrow.mailer@ to the @install_requires@ argument of the call to @setup()@ in your application's @setup.py@ file, @marrow.mailer@ will be automatically installed and made available when your own application is installed. We recommend using "less than" version numbers to ensure there are no unintentional side-effects when updating. Use @"marrow.mailer<4.1"@ to get all bugfixes for the current release, and @"marrow.mailer<5.0"@ to get bugfixes and feature updates, but ensure that large breaking changes are not installed.

*Warning:* The 4.0 series is the last to support Python 2.


h3(#install-dev). %2.1.% Development Version

Expand Down Expand Up @@ -454,7 +456,7 @@ Marrow Mailer has been released under the MIT Open Source license.

h3(#license-mit). %8.1.% The MIT License

Copyright (C) 2006-2016 Alice Bevan-McGregor and contributors.
Copyright (C) 2006-2019 Alice Bevan-McGregor and contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
16 changes: 13 additions & 3 deletions marrow/mailer/message.py
Expand Up @@ -191,6 +191,9 @@ def _build_header_list(self, author, sender):
else:
headers.extend(self.headers)

if 'message-id' not in (header[0].lower() for header in headers):
headers.append(('Message-Id', self.id))

return headers

def _add_headers_to_message(self, message, headers):
Expand Down Expand Up @@ -322,11 +325,18 @@ def attach(self, name, data=None, maintype=None, subtype=None,
filename=(filename_charset, filename_language, filename)

if inline:
part.add_header('Content-Disposition', 'inline', filename=filename)
part.add_header('Content-ID', '<%s>' % filename)
if sys.version_info < (3, 0):
part.add_header('Content-Disposition'.encode('utf-8'), 'inline'.encode('utf-8'), filename=filename)
part.add_header('Content-ID'.encode('utf-8'), '<%s>'.encode('utf-8') % filename)
else:
part.add_header('Content-Disposition', 'inline', filename=filename)
part.add_header('Content-ID', '<%s>' % filename)
self.embedded.append(part)
else:
part.add_header('Content-Disposition', 'attachment', filename=filename)
if sys.version_info < (3, 0):
part.add_header('Content-Disposition'.encode('utf-8'), 'attachment'.encode('utf-8'), filename=filename)
else:
part.add_header('Content-Disposition', 'attachment', filename=filename)
self.attachments.append(part)

def embed(self, name, data=None):
Expand Down
2 changes: 1 addition & 1 deletion marrow/mailer/release.py
Expand Up @@ -5,7 +5,7 @@
from collections import namedtuple


version_info = namedtuple('version_info', ('major', 'minor', 'micro', 'releaselevel', 'serial'))(4, 0, 2, 'final', 0)
version_info = namedtuple('version_info', ('major', 'minor', 'micro', 'releaselevel', 'serial'))(4, 0, 3, 'final', 0)
version = ".".join([str(i) for i in version_info[:3]]) + ((version_info.releaselevel[0] + str(version_info.serial)) if version_info.releaselevel != 'final' else '')

author = namedtuple('Author', ['name', 'email'])("Alice Bevan-McGregor", 'alice@gothcandy.com')
Expand Down
25 changes: 24 additions & 1 deletion test/test_message.py
Expand Up @@ -18,7 +18,7 @@

from marrow.mailer import Message
from marrow.mailer.address import AddressList
from marrow.util.compat import unicode
from marrow.util.compat import basestring, unicode


class TestBasicMessage(TestCase):
Expand Down Expand Up @@ -281,6 +281,29 @@ def test_mime_embed_failures(self):

with pytest.raises(TypeError):
message.embed('test.gif', object())

def test_that_add_header_and_collapse_header_are_inverses_ascii_filename(self):
message = self.build_message()
message.plain = "Hello world."
message.rich = "Farewell cruel world."
message.attach("wat.txt", b"not a unicode snowman") # calls add_header() under the covers
attachment = message.attachments[0]
filename = attachment.get_filename() # calls email.utils.collapse_rfc2231_value() under the covers
assert filename == "wat.txt"

def test_that_add_header_and_collapse_header_are_inverses_non_ascii_filename(self):
message = self.build_message()
message.plain = "Hello world."
message.rich = "Farewell cruel world."
message.attach("☃.txt", b"unicode snowman", filename_language='en-us')
attachment = message.attachments[0]
filename = attachment.get_param('filename', object(), 'content-disposition') # get_filename() calls this under the covers
assert isinstance(filename, tuple) # Since attachment encoded according to RFC2231, should be represented as a tuple
filename = attachment.get_filename() # Calls email.utils.collapse_rfc2231_value() under the covers, currently fails
if sys.version_info < (3, 0):
assert isinstance(filename, basestring) # Successfully converts tuple to a string
else:
assert isinstance(filename, str)

def test_recipients_collection(self):
message = self.build_message()
Expand Down

0 comments on commit 04bfd36

Please sign in to comment.