Support more than one address in Message.mail_to
This commit is contained in:
parent
37d0b67dd0
commit
12db9e9633
|
@ -7,7 +7,7 @@ from .compat import (string_types, is_callable, to_bytes, formataddr as compat_f
|
|||
from .utils import (SafeMIMEText, SafeMIMEMultipart, sanitize_address,
|
||||
parse_name_and_email, load_email_charsets,
|
||||
encode_header as encode_header_,
|
||||
renderable, format_date_header)
|
||||
renderable, format_date_header, parse_name_and_email_list)
|
||||
from .exc import BadHeaderError
|
||||
from .backend import ObjectFactory, SMTPBackend
|
||||
from .store import MemoryFileStore, BaseFile
|
||||
|
@ -66,10 +66,7 @@ class BaseMessage(object):
|
|||
mail_from = property(get_mail_from, set_mail_from)
|
||||
|
||||
def set_mail_to(self, mail_to):
|
||||
# Now we parse only one to-addr
|
||||
# TODO: parse list of to-addrs
|
||||
mail_to = mail_to and parse_name_and_email(mail_to)
|
||||
self._mail_to = mail_to and [mail_to, ] or []
|
||||
self._mail_to = parse_name_and_email_list(mail_to)
|
||||
|
||||
def get_mail_to(self):
|
||||
return self._mail_to
|
||||
|
|
|
@ -107,15 +107,36 @@ def test_sanitize_header():
|
|||
emails.Message(html='...', **{header: value}).as_message()
|
||||
|
||||
|
||||
def test_address_header_not_double_encoded():
|
||||
msg = {}
|
||||
m = Message()
|
||||
def test_headers_not_double_encoded():
|
||||
|
||||
TEXT = '웃'
|
||||
|
||||
m = Message()
|
||||
m.mail_from = (TEXT, 'a@b.c')
|
||||
m.mail_to = (TEXT, 'a@b.c')
|
||||
m.subject = TEXT
|
||||
m.html = '...'
|
||||
msg = m.as_message()
|
||||
assert decode_header(parseaddr(msg['From'])[0]) == TEXT
|
||||
assert decode_header(parseaddr(msg['To'])[0]) == TEXT
|
||||
assert decode_header(msg['Subject']) == TEXT
|
||||
|
||||
|
||||
def test_message_addresses():
|
||||
|
||||
m = Message()
|
||||
|
||||
m.mail_from = "웃 <b@c.d>"
|
||||
assert m.mail_from == ("웃", "b@c.d")
|
||||
|
||||
m.mail_from = ["웃", "b@c.d"]
|
||||
assert m.mail_from == ("웃", "b@c.d")
|
||||
|
||||
m.mail_to = ("웃", "b@c.d")
|
||||
assert m.mail_to == [("웃", "b@c.d"), ]
|
||||
|
||||
m.mail_to = [("웃", "b@c.d"), "e@f.g"]
|
||||
assert m.mail_to == [("웃", "b@c.d"), (None, "e@f.g")]
|
||||
|
||||
|
||||
def test_message_policy():
|
||||
|
|
|
@ -4,9 +4,10 @@ import pytest
|
|||
import datetime
|
||||
import time
|
||||
from emails.utils import (parse_name_and_email, encode_header, decode_header, sanitize_address, fetch_url,
|
||||
MessageID, format_date_header)
|
||||
MessageID, format_date_header, parse_name_and_email_list)
|
||||
from emails.exc import HTTPLoaderError
|
||||
|
||||
|
||||
def test_parse_name_and_email():
|
||||
assert parse_name_and_email('john@smith.me') == (None, 'john@smith.me')
|
||||
assert parse_name_and_email('"John Smith" <john@smith.me>') == \
|
||||
|
@ -19,6 +20,13 @@ def test_parse_name_and_email():
|
|||
parse_name_and_email([42,])
|
||||
|
||||
|
||||
def test_parse_name_and_list():
|
||||
assert parse_name_and_email_list(['a@b.c', 'd@e.f']) == [(None, 'a@b.c'), (None, 'd@e.f')]
|
||||
assert parse_name_and_email_list(('a@b.c', 'd@e.f')) == [('a@b.c', 'd@e.f'), ]
|
||||
assert parse_name_and_email_list(['a@b.c']) == [(None, 'a@b.c')]
|
||||
assert parse_name_and_email_list("♤ <a@b.c>") == [("♤", 'a@b.c'), ]
|
||||
|
||||
|
||||
def test_header_encode():
|
||||
v = 'Мама мыла раму. ' * 30
|
||||
assert decode_header(encode_header(v)).strip() == v.strip()
|
||||
|
|
|
@ -87,6 +87,38 @@ class MessageID:
|
|||
return "".join(['<', r, '@', self.domain, '>'])
|
||||
|
||||
|
||||
def parse_name_and_email_list(elements, encoding='utf-8'):
|
||||
"""
|
||||
Parse a list of address-like elements, i.e.:
|
||||
* "name <email>"
|
||||
* "email"
|
||||
* (name, email)
|
||||
|
||||
:param elements: one element or list of elements
|
||||
:param encoding: element encoding, if bytes
|
||||
:return: list of pairs (name, email)
|
||||
"""
|
||||
if not elements:
|
||||
return []
|
||||
|
||||
if isinstance(elements, string_types):
|
||||
return [parse_name_and_email(elements, encoding), ]
|
||||
|
||||
if not isinstance(elements, (list, tuple)):
|
||||
raise TypeError("Can not parse_name_and_email_list from %s" % elements.__repr__())
|
||||
|
||||
if len(elements) == 2:
|
||||
# Oops, it may be pair (name, email) or pair of emails [email1, email2]
|
||||
# Let's do some guesses
|
||||
if isinstance(elements, tuple):
|
||||
n, e = elements
|
||||
if isinstance(e, string_types) and (not n or isinstance(e, string_types)):
|
||||
# It is probably a pair (name, email)
|
||||
return [parse_name_and_email(elements, encoding), ]
|
||||
|
||||
return [parse_name_and_email(x, encoding) for x in elements]
|
||||
|
||||
|
||||
def parse_name_and_email(obj, encoding='utf-8'):
|
||||
# In: 'john@smith.me' or '"John Smith" <john@smith.me>' or ('John Smith', 'john@smith.me')
|
||||
# Out: (u'John Smith', u'john@smith.me')
|
||||
|
|
Reference in New Issue