mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix sending by email not working on computers with non-ascii hostnames. Fixes #1256549 [E-mailing has problems on French Windows installation](https://bugs.launchpad.net/calibre/+bug/1256549)
This commit is contained in:
parent
4accf0954c
commit
2f194b2776
@ -9,8 +9,9 @@ This module implements a simple commandline SMTP client that supports:
|
|||||||
* Background delivery with failures being saved in a maildir mailbox
|
* Background delivery with failures being saved in a maildir mailbox
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys, traceback, os
|
import sys, traceback, os, socket
|
||||||
from calibre import isbytestring
|
from calibre import isbytestring
|
||||||
|
from calibre.utils.filenames import ascii_text
|
||||||
|
|
||||||
def create_mail(from_, to, subject, text=None, attachment_data=None,
|
def create_mail(from_, to, subject, text=None, attachment_data=None,
|
||||||
attachment_type=None, attachment_name=None):
|
attachment_type=None, attachment_name=None):
|
||||||
@ -61,12 +62,34 @@ def get_mx(host, verbose=0):
|
|||||||
int(getattr(y, 'preference', sys.maxint))))
|
int(getattr(y, 'preference', sys.maxint))))
|
||||||
return [str(x.exchange) for x in answers if hasattr(x, 'exchange')]
|
return [str(x.exchange) for x in answers if hasattr(x, 'exchange')]
|
||||||
|
|
||||||
|
def safe_localhost():
|
||||||
|
# RFC 2821 says we should use the fqdn in the EHLO/HELO verb, and
|
||||||
|
# if that can't be calculated, that we should use a domain literal
|
||||||
|
# instead (essentially an encoded IP address like [A.B.C.D]).
|
||||||
|
fqdn = socket.getfqdn()
|
||||||
|
if '.' in fqdn:
|
||||||
|
# Some mail servers have problems with non-ascii local hostnames, see
|
||||||
|
# https://bugs.launchpad.net/bugs/1256549
|
||||||
|
try:
|
||||||
|
local_hostname = ascii_text(fqdn)
|
||||||
|
except:
|
||||||
|
local_hostname = 'localhost.localdomain'
|
||||||
|
else:
|
||||||
|
# We can't find an fqdn hostname, so use a domain literal
|
||||||
|
addr = '127.0.0.1'
|
||||||
|
try:
|
||||||
|
addr = socket.gethostbyname(socket.gethostname())
|
||||||
|
except socket.gaierror:
|
||||||
|
pass
|
||||||
|
local_hostname = '[%s]' % addr
|
||||||
|
return local_hostname
|
||||||
|
|
||||||
def sendmail_direct(from_, to, msg, timeout, localhost, verbose,
|
def sendmail_direct(from_, to, msg, timeout, localhost, verbose,
|
||||||
debug_output=None):
|
debug_output=None):
|
||||||
import calibre.utils.smtplib as smtplib
|
import calibre.utils.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
|
||||||
kwargs = dict(timeout=timeout, local_hostname=localhost)
|
kwargs = dict(timeout=timeout, local_hostname=localhost or safe_localhost())
|
||||||
if debug_output is not None:
|
if debug_output is not None:
|
||||||
kwargs['debug_to'] = debug_output
|
kwargs['debug_to'] = debug_output
|
||||||
s = smtplib.SMTP(**kwargs)
|
s = smtplib.SMTP(**kwargs)
|
||||||
@ -94,9 +117,9 @@ def sendmail(msg, from_, to, localhost=None, verbose=0, timeout=None,
|
|||||||
return sendmail_direct(from_, x, msg, timeout, localhost, verbose)
|
return sendmail_direct(from_, x, msg, timeout, localhost, verbose)
|
||||||
import calibre.utils.smtplib as smtplib
|
import calibre.utils.smtplib as smtplib
|
||||||
cls = smtplib.SMTP_SSL if encryption == 'SSL' else smtplib.SMTP
|
cls = smtplib.SMTP_SSL if encryption == 'SSL' else smtplib.SMTP
|
||||||
timeout = None # Non-blocking sockets sometimes don't work
|
timeout = None # Non-blocking sockets sometimes don't work
|
||||||
port = int(port)
|
port = int(port)
|
||||||
kwargs = dict(timeout=timeout, local_hostname=localhost)
|
kwargs = dict(timeout=timeout, local_hostname=localhost or safe_localhost())
|
||||||
if debug_output is not None:
|
if debug_output is not None:
|
||||||
kwargs['debug_to'] = debug_output
|
kwargs['debug_to'] = debug_output
|
||||||
s = cls(**kwargs)
|
s = cls(**kwargs)
|
||||||
@ -118,7 +141,7 @@ def sendmail(msg, from_, to, localhost=None, verbose=0, timeout=None,
|
|||||||
try:
|
try:
|
||||||
ret = s.quit()
|
ret = s.quit()
|
||||||
except:
|
except:
|
||||||
pass # Ignore so as to not hide original error
|
pass # Ignore so as to not hide original error
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
@ -203,7 +226,6 @@ def main(args=sys.argv):
|
|||||||
parser = option_parser()
|
parser = option_parser()
|
||||||
opts, args = parser.parse_args(args)
|
opts, args = parser.parse_args(args)
|
||||||
|
|
||||||
|
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
if len(args) < 4:
|
if len(args) < 4:
|
||||||
print ('You must specify the from address, to address and body text'
|
print ('You must specify the from address, to address and body text'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user