Merge pull request #367 from berendiwema/master

#327 - Support STARTTLS / SSL option in email sender
This commit is contained in:
Pablo Hoffman 2013-08-14 07:17:30 -07:00
commit f95b164d06
2 changed files with 39 additions and 7 deletions

View File

@ -39,11 +39,11 @@ MailSender class reference
==========================
MailSender is the preferred class to use for sending emails from Scrapy, as it
uses `Twisted non-blocking IO`_, like the rest of the framework.
uses `Twisted non-blocking IO`_, like the rest of the framework.
.. class:: MailSender(smtphost=None, mailfrom=None, smtpuser=None, smtppass=None, smtpport=None)
:param smtphost: the SMTP host to use for sending the emails. If omitted, the
:param smtphost: the SMTP host to use for sending the emails. If omitted, the
:setting:`MAIL_HOST` setting will be used.
:type smtphost: str
@ -62,6 +62,12 @@ uses `Twisted non-blocking IO`_, like the rest of the framework.
:param smtpport: the SMTP port to connect to
:type smtpport: int
:param smtptls: enforce using SMTP STARTTLS
:type smtpport: boolean
:param smtpssl: enforce using a secure SSL connection
:type smtpport: boolean
.. classmethod:: from_settings(settings)
Instantiate using a Scrapy settings object, which will respect
@ -148,3 +154,21 @@ MAIL_PASS
Default: ``None``
Password to use for SMTP authentication, along with :setting:`MAIL_USER`.
.. setting:: MAIL_TLS
MAIL_TLS
---------
Default: ``False``
Enforce using STARTTLS. STARTTLS is a way to take an existing insecure connection, and upgrade it to a secure connection using SSL/TLS.
.. setting:: MAIL_SSL
MAIL_SSL
---------
Default: ``False``
Enforce connecting using an SSL encrypted connection

View File

@ -11,7 +11,7 @@ from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
from twisted.internet import defer, reactor
from twisted.internet import defer, reactor, ssl
from twisted.mail.smtp import ESMTPSenderFactory
from scrapy import log
@ -19,18 +19,21 @@ from scrapy import log
class MailSender(object):
def __init__(self, smtphost='localhost', mailfrom='scrapy@localhost',
smtpuser=None, smtppass=None, smtpport=25, debug=False):
smtpuser=None, smtppass=None, smtpport=25, smtptls=False, smtpssl=False, debug=False):
self.smtphost = smtphost
self.smtpport = smtpport
self.smtpuser = smtpuser
self.smtppass = smtppass
self.smtptls = smtptls
self.smtpssl = smtpssl
self.mailfrom = mailfrom
self.debug = debug
@classmethod
def from_settings(cls, settings):
return cls(settings['MAIL_HOST'], settings['MAIL_FROM'], settings['MAIL_USER'],
settings['MAIL_PASS'], settings.getint('MAIL_PORT'))
settings['MAIL_PASS'], settings.getint('MAIL_PORT'),
settings.getbool('MAIL_TLS'), settings.getbool('MAIL_SSL'))
def send(self, to, subject, body, cc=None, attachs=(), _callback=None):
if attachs:
@ -91,7 +94,12 @@ class MailSender(object):
d = defer.Deferred()
factory = ESMTPSenderFactory(self.smtpuser, self.smtppass, self.mailfrom, \
to_addrs, msg, d, heloFallback=True, requireAuthentication=False, \
requireTransportSecurity=False)
requireTransportSecurity=self.smtptls)
factory.noisy = False
reactor.connectTCP(self.smtphost, self.smtpport, factory)
if self.smtpssl:
reactor.connectSSL(self.smtphost, self.smtpport, factory, ssl.ClientContextFactory())
else:
reactor.connectTCP(self.smtphost, self.smtpport, factory)
return d