mirror of https://github.com/scrapy/scrapy.git
Added SMTP-AUTH support to scrapy.mail (closes #149)
This commit is contained in:
parent
495f23dea2
commit
bd16d1cd48
|
|
@ -8,17 +8,15 @@ Sending e-mail
|
|||
:synopsis: Email sending facility
|
||||
|
||||
Although Python makes sending e-mails relatively easy via the `smtplib`_
|
||||
library, Scrapy provides its own facility for sending e-mails which is very easy
|
||||
to use and it's implemented using `Twisted non-blocking IO`_, to avoid
|
||||
interfering with the non-blocking IO of the crawler.
|
||||
|
||||
It's also very easy to configure, having only a few settings.
|
||||
library, Scrapy provides its own facility for sending e-mails which is very
|
||||
easy to use and it's implemented using `Twisted non-blocking IO`_, to avoid
|
||||
interfering with the non-blocking IO of the crawler. It also provides a
|
||||
simple API for sending attachments and it's very easy to configure, with a few
|
||||
:ref:`settings <topics-email-settings`.
|
||||
|
||||
.. _smtplib: http://docs.python.org/library/smtplib.html
|
||||
.. _Twisted non-blocking IO: http://twistedmatrix.com/projects/core/documentation/howto/async.html
|
||||
|
||||
It also has built-in support for sending attachments.
|
||||
|
||||
Quick example
|
||||
=============
|
||||
|
||||
|
|
@ -35,7 +33,7 @@ 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.
|
||||
|
||||
.. class:: MailSender(smtphost, mailfrom)
|
||||
.. 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
|
||||
:setting:`MAIL_HOST` setting will be used.
|
||||
|
|
@ -45,6 +43,17 @@ uses `Twisted non-blocking IO`_, like the rest of the framework.
|
|||
If omitted, the :setting:`MAIL_FROM` setting will be used.
|
||||
:type mailfrom: str
|
||||
|
||||
:param smtpuser: the SMTP user. If omitted, the :setting:`MAIL_USER`
|
||||
setting will be used. If not given, no SMTP authentication will be
|
||||
performed.
|
||||
:type smtphost: str
|
||||
|
||||
:param smtppass: the SMTP pass for authetnication.
|
||||
:type smtppass: str
|
||||
|
||||
:param smtpport: the SMTP port to connect to
|
||||
:type smtpport: int
|
||||
|
||||
.. method:: send(to, subject, body, cc=None, attachs=())
|
||||
|
||||
Send email to the given recipients. Emits the :signal:`mail_sent` signal.
|
||||
|
|
@ -72,16 +81,69 @@ uses `Twisted non-blocking IO`_, like the rest of the framework.
|
|||
:type attachs: iterable
|
||||
|
||||
|
||||
MailSender settings
|
||||
===================
|
||||
.. _topics-email-settings:
|
||||
|
||||
Mail settings
|
||||
=============
|
||||
|
||||
These settings define the default constructor values of the :class:`MailSender`
|
||||
class, and can be used to configure e-mail notifications in your project without
|
||||
writing any code (for those extensions that use the :class:`MailSender` class):
|
||||
writing any code (for those extensions and code that uses :class:`MailSender`).
|
||||
|
||||
* :setting:`MAIL_DEBUG`
|
||||
* :setting:`MAIL_FROM`
|
||||
* :setting:`MAIL_HOST`
|
||||
.. setting:: MAIL_FROM
|
||||
|
||||
MAIL_FROM
|
||||
---------
|
||||
|
||||
Default: ``'scrapy@localhost'``
|
||||
|
||||
Sender email to use (``From:`` header) for sending emails.
|
||||
|
||||
.. setting:: MAIL_HOST
|
||||
|
||||
MAIL_HOST
|
||||
---------
|
||||
|
||||
Default: ``'localhost'``
|
||||
|
||||
SMTP host to use for sending emails.
|
||||
|
||||
.. setting:: MAIL_PORT
|
||||
|
||||
MAIL_PORT
|
||||
---------
|
||||
|
||||
Default: ``25``
|
||||
|
||||
SMTP port to use for sending emails.
|
||||
|
||||
.. setting:: MAIL_USER
|
||||
|
||||
MAIL_USER
|
||||
---------
|
||||
|
||||
Default: ``None``
|
||||
|
||||
User to use for SMTP authentication. If disabled no SMTP authentication will be
|
||||
performed.
|
||||
|
||||
.. setting:: MAIL_PASS
|
||||
|
||||
MAIL_PASS
|
||||
---------
|
||||
|
||||
Default: ``None``
|
||||
|
||||
Password to use for SMTP authentication, along with :setting:`MAIL_USER`.
|
||||
|
||||
.. setting:: MAIL_DEBUG
|
||||
|
||||
MAIL_DEBUG
|
||||
----------
|
||||
|
||||
Default: ``False``
|
||||
|
||||
Whether to enable the debugging mode.
|
||||
|
||||
|
||||
Mail signals
|
||||
|
|
|
|||
|
|
@ -615,36 +615,6 @@ If ``True``, all standard output (and error) of your process will be redirected
|
|||
to the log. For example if you ``print 'hello'`` it will appear in the Scrapy
|
||||
log.
|
||||
|
||||
.. setting:: MAIL_DEBUG
|
||||
|
||||
MAIL_DEBUG
|
||||
----------
|
||||
|
||||
Default: ``False``
|
||||
|
||||
Whether to enable the debugging mode in the the :ref:`Scrapy e-mail sending
|
||||
facility <topics-email>`.
|
||||
|
||||
.. setting:: MAIL_FROM
|
||||
|
||||
MAIL_FROM
|
||||
---------
|
||||
|
||||
Default: ``'scrapy@localhost'``
|
||||
|
||||
Email to use as sender address for sending emails using the :ref:`Scrapy e-mail
|
||||
sending facility <topics-email>`.
|
||||
|
||||
.. setting:: MAIL_HOST
|
||||
|
||||
MAIL_HOST
|
||||
---------
|
||||
|
||||
Default: ``'localhost'``
|
||||
|
||||
Host to use for sending emails using the :ref:`Scrapy e-mail sending facility
|
||||
<topics-email>`.
|
||||
|
||||
.. setting:: MEMDEBUG_ENABLED
|
||||
|
||||
MEMDEBUG_ENABLED
|
||||
|
|
|
|||
|
|
@ -138,7 +138,10 @@ LOG_FILE = None
|
|||
|
||||
MAIL_DEBUG = False
|
||||
MAIL_HOST = 'localhost'
|
||||
MAIL_PORT = 25
|
||||
MAIL_FROM = 'scrapy@localhost'
|
||||
MAIL_PASS = None
|
||||
MAIL_USER = None
|
||||
|
||||
MEMDEBUG_ENABLED = False # enable memory debugging
|
||||
MEMDEBUG_NOTIFY = [] # send memory debugging report by mail at engine shutdown
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ from email.Utils import COMMASPACE, formatdate
|
|||
from email import Encoders
|
||||
|
||||
from twisted.internet import defer, reactor
|
||||
from twisted.mail.smtp import SMTPSenderFactory
|
||||
from twisted.mail.smtp import ESMTPSenderFactory
|
||||
|
||||
from scrapy import log
|
||||
from scrapy.core.exceptions import NotConfigured
|
||||
|
|
@ -27,9 +27,13 @@ mail_sent = object()
|
|||
|
||||
class MailSender(object):
|
||||
|
||||
def __init__(self, smtphost=None, mailfrom=None):
|
||||
self.smtphost = smtphost if smtphost else settings['MAIL_HOST']
|
||||
self.mailfrom = mailfrom if mailfrom else settings['MAIL_FROM']
|
||||
def __init__(self, smtphost=None, mailfrom=None, smtpuser=None, smtppass=None, \
|
||||
smtpport=None):
|
||||
self.smtphost = smtphost or settings['MAIL_HOST']
|
||||
self.smtpport = smtpport or settings.getint('MAIL_PORT')
|
||||
self.smtpuser = smtpuser or settings['MAIL_USER']
|
||||
self.smtppass = smtppass or settings['MAIL_PASS']
|
||||
self.mailfrom = mailfrom or settings['MAIL_FROM']
|
||||
|
||||
if not self.smtphost or not self.mailfrom:
|
||||
raise NotConfigured("MAIL_HOST and MAIL_FROM settings are required")
|
||||
|
|
@ -68,11 +72,12 @@ class MailSender(object):
|
|||
(to, cc, subject, len(attachs)), level=log.DEBUG)
|
||||
return
|
||||
|
||||
dfd = self._sendmail(self.smtphost, self.mailfrom, rcpts, msg.as_string())
|
||||
dfd = self._sendmail(rcpts, msg.as_string())
|
||||
dfd.addCallbacks(self._sent_ok, self._sent_failed,
|
||||
callbackArgs=[to, cc, subject, len(attachs)],
|
||||
errbackArgs=[to, cc, subject, len(attachs)])
|
||||
reactor.addSystemEventTrigger('before', 'shutdown', lambda: dfd)
|
||||
return dfd
|
||||
|
||||
def _sent_ok(self, result, to, cc, subject, nattachs):
|
||||
log.msg('Mail sent OK: To=%s Cc=%s Subject="%s" Attachs=%d' % \
|
||||
|
|
@ -83,13 +88,12 @@ class MailSender(object):
|
|||
log.msg('Unable to send mail: To=%s Cc=%s Subject="%s" Attachs=%d - %s' % \
|
||||
(to, cc, subject, nattachs, errstr), level=log.ERROR)
|
||||
|
||||
def _sendmail(self, smtphost, from_addr, to_addrs, msg, port=25):
|
||||
""" This is based on twisted.mail.smtp.sendmail except that it
|
||||
instantiates a quiet (noisy=False) SMTPSenderFactory """
|
||||
def _sendmail(self, to_addrs, msg):
|
||||
msg = StringIO(msg)
|
||||
d = defer.Deferred()
|
||||
factory = SMTPSenderFactory(from_addr, to_addrs, msg, d)
|
||||
factory = ESMTPSenderFactory(self.smtpuser, self.smtppass, self.mailfrom, \
|
||||
to_addrs, msg, d, heloFallback=True, requireAuthentication=False, \
|
||||
requireTransportSecurity=False)
|
||||
factory.noisy = False
|
||||
reactor.connectTCP(smtphost, port, factory)
|
||||
reactor.connectTCP(self.smtphost, self.smtpport, factory)
|
||||
return d
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue