From bd16d1cd488eca45eeac079bb4644388fd9d6214 Mon Sep 17 00:00:00 2001 From: Pablo Hoffman Date: Sun, 13 Jun 2010 17:14:46 -0300 Subject: [PATCH] Added SMTP-AUTH support to scrapy.mail (closes #149) --- docs/topics/email.rst | 90 ++++++++++++++++++++++++++++----- docs/topics/settings.rst | 30 ----------- scrapy/conf/default_settings.py | 3 ++ scrapy/mail.py | 26 ++++++---- 4 files changed, 94 insertions(+), 55 deletions(-) diff --git a/docs/topics/email.rst b/docs/topics/email.rst index c372e2122..c2dd0a450 100644 --- a/docs/topics/email.rst +++ b/docs/topics/email.rst @@ -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 `. - -.. 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 `. - -.. setting:: MAIL_HOST - -MAIL_HOST ---------- - -Default: ``'localhost'`` - -Host to use for sending emails using the :ref:`Scrapy e-mail sending facility -`. - .. setting:: MEMDEBUG_ENABLED MEMDEBUG_ENABLED diff --git a/scrapy/conf/default_settings.py b/scrapy/conf/default_settings.py index e53d8be90..809a62b98 100644 --- a/scrapy/conf/default_settings.py +++ b/scrapy/conf/default_settings.py @@ -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 diff --git a/scrapy/mail.py b/scrapy/mail.py index 8703a65c5..8ce7b1798 100644 --- a/scrapy/mail.py +++ b/scrapy/mail.py @@ -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 - -- GitLab