Fix a regression in the previous release that broke sending of emails with text longer than 900 characters

This commit is contained in:
Kovid Goyal 2021-02-27 22:26:21 +05:30
parent 14ab03a101
commit 195f61d51a
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -112,7 +112,7 @@ def create_mail(from_, to, subject, text=None, attachment_data=None,
filename=Header(attachment_name, 'utf-8').encode()) filename=Header(attachment_name, 'utf-8').encode())
outer.attach(msg) outer.attach(msg)
return outer.as_string() return outer
def get_mx(host, verbose=0): def get_mx(host, verbose=0):
@ -124,8 +124,9 @@ def get_mx(host, verbose=0):
return [unicode_type(x.exchange) for x in answers if hasattr(x, 'exchange')] return [unicode_type(x.exchange) for x in answers if hasattr(x, 'exchange')]
def sendmail_direct(from_, to, msg: bytes, timeout, localhost, verbose, def sendmail_direct(from_, to, msg, timeout, localhost, verbose,
debug_output=None): debug_output=None):
from email.message import Message
import polyglot.smtplib as smtplib import polyglot.smtplib as smtplib
hosts = get_mx(to.split('@')[-1].strip(), verbose) hosts = get_mx(to.split('@')[-1].strip(), verbose)
timeout=None # Non blocking sockets sometimes don't work timeout=None # Non blocking sockets sometimes don't work
@ -140,6 +141,9 @@ def sendmail_direct(from_, to, msg: bytes, timeout, localhost, verbose,
for host in hosts: for host in hosts:
try: try:
s.connect(host, 25) s.connect(host, 25)
if isinstance(msg, Message):
s.send_message(msg, from_, [to])
else:
s.sendmail(from_, [to], msg) s.sendmail(from_, [to], msg)
return s.quit() return s.quit()
except Exception as e: except Exception as e:
@ -163,8 +167,7 @@ def get_smtp_class(use_ssl=False, debuglevel=0):
def sendmail(msg, from_, to, localhost=None, verbose=0, timeout=None, def sendmail(msg, from_, to, localhost=None, verbose=0, timeout=None,
relay=None, username=None, password=None, encryption='TLS', relay=None, username=None, password=None, encryption='TLS',
port=-1, debug_output=None, verify_server_cert=False, cafile=None): port=-1, debug_output=None, verify_server_cert=False, cafile=None):
if isinstance(msg, str): from email.message import Message
msg = msg.encode('utf-8')
if relay is None: if relay is None:
for x in to: for x in to:
return sendmail_direct(from_, x, msg, timeout, localhost, verbose) return sendmail_direct(from_, x, msg, timeout, localhost, verbose)
@ -188,6 +191,9 @@ def sendmail(msg, from_, to, localhost=None, verbose=0, timeout=None,
s.login(username, password) s.login(username, password)
ret = None ret = None
try: try:
if isinstance(msg, Message):
s.send_message(msg, from_, to)
else:
s.sendmail(from_, to, msg) s.sendmail(from_, to, msg)
finally: finally:
try: try:
@ -300,16 +306,15 @@ def main(args=sys.argv):
eto = [extract_email_address(x.strip()) for x in to.split(',')] eto = [extract_email_address(x.strip()) for x in to.split(',')]
efrom = extract_email_address(from_) efrom = extract_email_address(from_)
else: else:
msg = sys.stdin.read() from email import message_from_bytes
from email import message_from_string
from email.utils import getaddresses from email.utils import getaddresses
eml = message_from_string(msg) msg = message_from_bytes(sys.stdin.buffer.read())
tos = eml.get_all('to', []) tos = msg.get_all('to', [])
ccs = eml.get_all('cc', []) + eml.get_all('bcc', []) ccs = msg.get_all('cc', []) + msg.get_all('bcc', [])
eto = [x[1] for x in getaddresses(tos + ccs) if x[1]] eto = [x[1] for x in getaddresses(tos + ccs) if x[1]]
if not eto: if not eto:
raise ValueError('Email from STDIN does not specify any recipients') raise ValueError('Email from STDIN does not specify any recipients')
efrom = getaddresses(eml.get_all('from', [])) efrom = getaddresses(msg.get_all('from', []))
if not efrom: if not efrom:
raise ValueError('Email from STDIN does not specify a sender') raise ValueError('Email from STDIN does not specify a sender')
efrom = efrom[0][1] efrom = efrom[0][1]
@ -323,8 +328,6 @@ def main(args=sys.argv):
if os.fork() != 0: if os.fork() != 0:
return 0 return 0
if isinstance(msg, str):
msg = msg.encode('utf-8')
try: try:
sendmail(msg, efrom, eto, localhost=opts.localhost, verbose=opts.verbose, sendmail(msg, efrom, eto, localhost=opts.localhost, verbose=opts.verbose,
timeout=opts.timeout, relay=opts.relay, username=opts.username, timeout=opts.timeout, relay=opts.relay, username=opts.username,