mirror of https://github.com/scrapy/scrapy.git
Some mail improvements and tests.
* Add mail_sent signal and use it in MailSender * Add MAIL_DEBUG setting to not send mails when testing * Add MailSender tests
This commit is contained in:
parent
dfa7b23959
commit
a71dc295af
|
|
@ -47,7 +47,10 @@ uses `Twisted non-blocking IO`_, like the rest of the framework.
|
|||
|
||||
.. method:: send(to, subject, body, cc=None, attachs=())
|
||||
|
||||
Send email to the given recipients
|
||||
Send email to the given recipients. Emits the :signal:`mail_sent` signal.
|
||||
|
||||
If :setting:`MAIL_DEBUG` is enabled the :signal:`mail_sent` signal will
|
||||
be emmited and no actual email will be sent.
|
||||
|
||||
:param to: the e-mail recipients
|
||||
:type to: list
|
||||
|
|
@ -76,6 +79,37 @@ 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):
|
||||
|
||||
* :setting:`MAIL_DEBUG`
|
||||
* :setting:`MAIL_FROM`
|
||||
* :setting:`MAIL_HOST`
|
||||
|
||||
|
||||
Mail signals
|
||||
============
|
||||
|
||||
.. signal:: mail_sent
|
||||
.. function:: mail_sent(to, subject, body, cc, attachs, msg)
|
||||
|
||||
Emitted by :meth:`MailSender.send` after an email has been sent.
|
||||
|
||||
:param to: the e-mail recipients
|
||||
:type to: list
|
||||
|
||||
:param subject: the subject of the e-mail
|
||||
:type subject: str
|
||||
|
||||
:param cc: the e-mails to CC
|
||||
:type cc: list
|
||||
|
||||
:param body: the e-mail body
|
||||
:type body: str
|
||||
|
||||
:param attachs: an iterable of tuples ``(attach_name, mimetype,
|
||||
file_object)`` where ``attach_name`` is a string with the name that will
|
||||
appear on the e-mail's attachment, ``mimetype`` is the mimetype of the
|
||||
attachment and ``file_object`` is a readable file object with the
|
||||
contents of the attachment
|
||||
:type attachs: iterable
|
||||
|
||||
:param msg: the generated message
|
||||
:type msg: ``MIMEMultipart`` or ``MIMENonMultipart``
|
||||
|
|
|
|||
|
|
@ -620,6 +620,16 @@ 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
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ LOG_STDOUT = False
|
|||
LOG_LEVEL = 'DEBUG'
|
||||
LOG_FILE = None
|
||||
|
||||
MAIL_DEBUG = False
|
||||
MAIL_HOST = 'localhost'
|
||||
MAIL_FROM = 'scrapy@localhost'
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,13 @@ from twisted.mail.smtp import SMTPSenderFactory
|
|||
from scrapy import log
|
||||
from scrapy.core.exceptions import NotConfigured
|
||||
from scrapy.conf import settings
|
||||
from scrapy.utils.signal import send_catch_log
|
||||
|
||||
|
||||
# signal sent when message is sent
|
||||
# args: to, subject, body, cc, attach, msg
|
||||
mail_sent = object()
|
||||
|
||||
|
||||
class MailSender(object):
|
||||
|
||||
|
|
@ -53,6 +60,14 @@ class MailSender(object):
|
|||
else:
|
||||
msg.set_payload(body)
|
||||
|
||||
send_catch_log(signal=mail_sent, to=to, subject=subject, body=body,
|
||||
cc=cc, attach=attachs, msg=msg)
|
||||
|
||||
if settings.getbool('MAIL_DEBUG'):
|
||||
log.msg('Debug mail sent OK: To=%s Cc=%s Subject="%s" Attachs=%d' % \
|
||||
(to, cc, subject, len(attachs)), level=log.DEBUG)
|
||||
return
|
||||
|
||||
dfd = self._sendmail(self.smtphost, self.mailfrom, rcpts, msg.as_string())
|
||||
dfd.addCallbacks(self._sent_ok, self._sent_failed,
|
||||
callbackArgs=[to, cc, subject, len(attachs)],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
from cStringIO import StringIO
|
||||
import unittest
|
||||
|
||||
from scrapy.xlib.pydispatch import dispatcher
|
||||
|
||||
from scrapy.conf import settings
|
||||
from scrapy.mail import MailSender, mail_sent
|
||||
|
||||
|
||||
class MailSenderTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
settings.disabled = False
|
||||
settings.overrides['MAIL_DEBUG'] = True
|
||||
|
||||
self.catched_msg = None
|
||||
|
||||
dispatcher.connect(self._catch_mail_sent, signal=mail_sent)
|
||||
|
||||
def test_send(self):
|
||||
mailsender = MailSender()
|
||||
mailsender.send(to=['test@scrapy.org'], subject='subject', body='body')
|
||||
|
||||
assert self.catched_msg
|
||||
|
||||
self.assertEqual(self.catched_msg['to'], ['test@scrapy.org'])
|
||||
self.assertEqual(self.catched_msg['subject'], 'subject')
|
||||
self.assertEqual(self.catched_msg['body'], 'body')
|
||||
|
||||
msg = self.catched_msg['msg']
|
||||
self.assertEqual(msg['to'], 'test@scrapy.org')
|
||||
self.assertEqual(msg['subject'], 'subject')
|
||||
self.assertEqual(msg.get_payload(), 'body')
|
||||
|
||||
def test_send_attach(self):
|
||||
attach = StringIO()
|
||||
attach.write('content')
|
||||
attach.seek(0)
|
||||
attachs = [('attachment', 'text/plain', attach)]
|
||||
|
||||
mailsender = MailSender()
|
||||
mailsender.send(to=['test@scrapy.org'], subject='subject', body='body',
|
||||
attachs=attachs)
|
||||
|
||||
assert self.catched_msg
|
||||
self.assertEqual(self.catched_msg['to'], ['test@scrapy.org'])
|
||||
self.assertEqual(self.catched_msg['subject'], 'subject')
|
||||
self.assertEqual(self.catched_msg['body'], 'body')
|
||||
|
||||
msg = self.catched_msg['msg']
|
||||
self.assertEqual(msg['to'], 'test@scrapy.org')
|
||||
self.assertEqual(msg['subject'], 'subject')
|
||||
|
||||
payload = msg.get_payload()
|
||||
assert isinstance(payload, list)
|
||||
self.assertEqual(len(payload), 2)
|
||||
|
||||
text, attach = payload
|
||||
self.assertEqual(text.get_payload(decode=True), 'body')
|
||||
self.assertEqual(attach.get_payload(decode=True), 'content')
|
||||
|
||||
def tearDown(self):
|
||||
del settings.overrides['MAIL_DEBUG']
|
||||
settings.disabled = True
|
||||
|
||||
def _catch_mail_sent(self, **kwargs):
|
||||
self.catched_msg = dict(**kwargs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Reference in New Issue