Beispiel #1
0
    def __init__(self, **kw):
        smtp_mailer = kw.pop("smtp_mailer", None)
        if smtp_mailer is None:
            host = kw.pop("host", "localhost")
            port = kw.pop("port", 25)
            username = kw.pop("username", None)
            password = kw.pop("password", None)
            tls = kw.pop("tls", False)
            ssl = kw.pop("ssl", False)
            keyfile = kw.pop("keyfile", None)
            certfile = kw.pop("certfile", None)
            debug = kw.pop("debug", 0)
            if ssl:
                smtp_mailer = SMTP_SSLMailer(
                    hostname=host,
                    port=port,
                    username=username,
                    password=password,
                    no_tls=not (tls),
                    force_tls=tls,
                    debug_smtp=debug,
                    keyfile=keyfile,
                    certfile=certfile,
                )
            else:
                smtp_mailer = SMTPMailer(
                    hostname=host,
                    port=port,
                    username=username,
                    password=password,
                    no_tls=not (tls),
                    force_tls=tls,
                    debug_smtp=debug,
                )
        self.smtp_mailer = smtp_mailer

        sendmail_mailer = kw.pop("sendmail_mailer", None)
        if sendmail_mailer is None:
            sendmail_mailer = SendmailMailer(kw.pop("sendmail_app", None), kw.pop("sendmail_template", None))
        self.sendmail_mailer = sendmail_mailer

        self.queue_path = kw.pop("queue_path", None)
        self.default_sender = kw.pop("default_sender", None)

        transaction_manager = kw.pop("transaction_manager", None)
        if transaction_manager is None:
            transaction_manager = transaction.manager
        self.transaction_manager = transaction_manager

        if kw:
            raise ValueError("invalid options: %s" % ", ".join(sorted(kw.keys())))

        self.direct_delivery = DirectMailDelivery(self.smtp_mailer, transaction_manager=transaction_manager)

        if self.queue_path:
            self.queue_delivery = QueuedMailDelivery(self.queue_path, transaction_manager=transaction_manager)
        else:
            self.queue_delivery = None

        self.sendmail_delivery = DirectMailDelivery(self.sendmail_mailer, transaction_manager=transaction_manager)
Beispiel #2
0
    def __init__(self):
        '''
        :ivar to_addr: The default recipient email address
            Will be set to the configuration variable "email_to",
            if configuration is available
        :ivar from_addr: The default sender email address
            Will be set to the configuration variable "admin_email_from",
            if configuration is available
        '''

        self.to_addr = config.get('email_to')
        self.from_addr = config.get('admin_email_from')

        smtp_server = config.get('smtp_server')
        smtp_use_tls = asbool(config.get('smtp_use_tls'))
        smtp_username = config.get('smtp_username')
        smtp_password = config.get('smtp_password')

        test = asbool(config.get('test'))

        if test:
            log.debug('Using DummyDelivery()')
            self.delivery = DummyDelivery()
        else:  # pragma: no cover
            if smtp_server:
                mailer = SMTPMailer(hostname=smtp_server,
                    username=smtp_username, password=smtp_password,
                    force_tls=smtp_use_tls)
                log.debug('Using SMTPMailer(hostname=%s, ...)', smtp_server)
            else:
                mailer = SendmailMailer()
                log.debug('Using SendmailMailer()')
            self.delivery = DirectMailDelivery(mailer)
    def test_alternate_transaction_manager(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        from email.message import Message
        import transaction

        mailer = _makeMailerStub()
        delivery = DirectMailDelivery(mailer)
        tm = transaction.TransactionManager()
        delivery.transaction_manager = tm
        fromaddr = "Jim <*****@*****.**>"
        toaddrs = ("Guido <*****@*****.**>", "Steve <*****@*****.**>")
        message = Message()
        message["From"] = fromaddr
        message["To"] = ",".join(toaddrs)
        message["Date"] = "Date: Mon, 19 May 2003 10:17:36 -0400"
        message["Subject"] = "example"
        message.set_payload("This is just an example\n")

        msgid = delivery.send(fromaddr, toaddrs, message)

        transaction.commit()
        self.assertEqual(len(mailer.sent_messages), 0)
        t = tm.get()
        data_manager = t._resources[0]
        self.assertTrue(data_manager.transaction_manager is tm)
        t.commit()
        self.assertEqual(len(mailer.sent_messages), 1)
        self.assertEqual(mailer.sent_messages[0][0], fromaddr)
        self.assertEqual(mailer.sent_messages[0][1], toaddrs)
        self.assertEqual(mailer.sent_messages[0][2].get_payload(), "This is just an example\n")

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, message)
        tm.get().abort()
        self.assertEqual(len(mailer.sent_messages), 0)
Beispiel #4
0
    def __init__(self):
        '''
        :ivar to_addr: The default recipient email address
            Will be set to the configuration variable "email_to",
            if configuration is available
        :ivar from_addr: The default sender email address
            Will be set to the configuration variable "admin_email_from",
            if configuration is available
        '''

        self.to_addr = config.get('email_to')
        self.from_addr = config.get('admin_email_from')

        smtp_server = config.get('smtp_server')
        smtp_use_tls = asbool(config.get('smtp_use_tls'))
        smtp_username = config.get('smtp_username')
        smtp_password = config.get('smtp_password')

        test = asbool(config.get('test'))

        if test:
            log.debug('Using DummyDelivery()')
            self.delivery = DummyDelivery()
        else:  # pragma: no cover
            if smtp_server:
                mailer = SMTPMailer(hostname=smtp_server,
                                    username=smtp_username,
                                    password=smtp_password,
                                    force_tls=smtp_use_tls)
                log.debug('Using SMTPMailer(hostname=%s, ...)', smtp_server)
            else:
                mailer = SendmailMailer()
                log.debug('Using SendmailMailer()')
            self.delivery = DirectMailDelivery(mailer)
    def test_alternate_transaction_manager(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        from email.message import Message
        import transaction
        mailer = _makeMailerStub()
        delivery = DirectMailDelivery(mailer)
        tm = transaction.TransactionManager()
        delivery.transaction_manager = tm
        fromaddr = "Jim <*****@*****.**>"
        toaddrs = ('Guido <*****@*****.**>', 'Steve <*****@*****.**>')
        message = Message()
        message["From"] = fromaddr
        message["To"] = ",".join(toaddrs)
        message["Date"] = "Date: Mon, 19 May 2003 10:17:36 -0400"
        message["Subject"] = "example"
        message.set_payload("This is just an example\n")

        msgid = delivery.send(fromaddr, toaddrs, message)

        transaction.commit()
        self.assertEqual(len(mailer.sent_messages), 0)
        t = tm.get()
        data_manager = t._resources[0]
        self.assertTrue(data_manager.transaction_manager is tm)
        t.commit()
        self.assertEqual(len(mailer.sent_messages), 1)
        self.assertEqual(mailer.sent_messages[0][0], fromaddr)
        self.assertEqual(mailer.sent_messages[0][1], toaddrs)
        self.assertEqual(mailer.sent_messages[0][2].get_payload(),
                         "This is just an example\n")

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, message)
        tm.get().abort()
        self.assertEqual(len(mailer.sent_messages), 0)
    def testRefusingMailerDiesInVote(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        mailer = RefusingMailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>', 'Steve <steve@examplecom>')
        opt_headers = ('From: Jim <*****@*****.**>\n'
                       'To: some-zope-coders:;\n'
                       'Date: Mon, 19 May 2003 10:17:36 -0400\n'
                       'Message-Id: <*****@*****.**>\n')
        message = ('Subject: example\n' '\n' 'This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, opt_headers + message)
        try:
            transaction.commit()
        except:
            if transaction.get()._voted:
                # We voted for commit then failed, reraise
                raise
            else:
                # We vetoed a commit, that's good.
                pass
        else:
            self.fail("Did not raise an exception in vote")
        finally:
            # Clean up after ourselves
            transaction.abort()
    def testRefusingMailerDiesInVote(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        mailer = RefusingMailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>',
                   'Steve <steve@examplecom>')
        opt_headers = ('From: Jim <*****@*****.**>\n'
                       'To: some-zope-coders:;\n'
                       'Date: Mon, 19 May 2003 10:17:36 -0400\n'
                       'Message-Id: <*****@*****.**>\n')
        message =     ('Subject: example\n'
                       '\n'
                       'This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, opt_headers + message)
        try:
            transaction.commit()
        except:
            if transaction.get()._voted:
                # We voted for commit then failed, reraise
                raise
            else:
                # We vetoed a commit, that's good.
                pass
        else:
            self.fail("Did not raise an exception in vote")
        finally:
            # Clean up after ourselves
            transaction.abort()
Beispiel #8
0
    def test_abort(self):
        import transaction
        mailer = _makeMailerStub()
        delivery = DirectMailDelivery(mailer)

        ( fromaddr , toaddrs ) = fromaddr_toaddrs()
        message = sample_message()
        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertEqual(msgid, '<*****@*****.**>')
        self.assertEqual(mailer.sent_messages, [])
        transaction.abort()
        transaction.commit()
        self.assertEqual(mailer.sent_messages,[])
Beispiel #9
0
    def __init__(self, 
                 host='localhost', 
                 port=25, 
                 username=None,
                 password=None, 
                 tls=False,
                 ssl=False,
                 keyfile=None,
                 certfile=None,
                 queue_path=None,
                 default_sender=None,
                 sendmail_app=None,
                 sendmail_template=None,
                 debug=0):


        if ssl:

            self.smtp_mailer = SMTP_SSLMailer(
                hostname=host,
                port=port,
                username=username,
                password=password,
                no_tls=not(tls),
                force_tls=tls,
                debug_smtp=debug,
                keyfile=keyfile,
                certfile=certfile)

        else:

            self.smtp_mailer = SMTPMailer(
                hostname=host, 
                port=port, 
                username=username, 
                password=password, 
                no_tls=not(tls), 
                force_tls=tls, 
                debug_smtp=debug)

        self.direct_delivery = DirectMailDelivery(self.smtp_mailer)

        if queue_path:
            self.queue_delivery = QueuedMailDelivery(queue_path)
        else:
            self.queue_delivery = None
            
        self.sendmail_mailer = SendmailMailer(sendmail_app, sendmail_template)
        self.sendmail_delivery = DirectMailDelivery(self.sendmail_mailer)

        self.default_sender = default_sender
 def testInterface(self):
     from repoze.sendmail.interfaces import IDirectMailDelivery
     from repoze.sendmail.delivery import DirectMailDelivery
     mailer = MailerStub()
     delivery = DirectMailDelivery(mailer)
     verifyObject(IDirectMailDelivery, delivery)
     self.assertEqual(delivery.mailer, mailer)
Beispiel #11
0
    def createDirectDelivery():
        mailerObject = queryUtility(IMailer, mailer)
        if mailerObject is None:
            raise ConfigurationError("Mailer %r is not defined" % mailer)

        delivery = DirectMailDelivery(mailerObject)

        handler('registerUtility', delivery, IMailDelivery, name)
Beispiel #12
0
    def testMakeMessageId(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        from email.message import Message
        mailer = _makeMailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>', 'Steve <steve@examplecom>')
        message = Message()
        message['From'] = 'Jim <*****@*****.**>'
        message['To'] = 'some-zope-coders:;'
        message['Date'] = 'Date: Mon, 19 May 2003 10:17:36 -0400'
        message['Subject'] = 'example'
        message.set_payload('This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertTrue('.repoze.sendmail@' in msgid)
        self.assertEqual(message['Message-Id'], msgid)
Beispiel #13
0
    def __init__(self,
                 host='localhost',
                 port=25,
                 username=None,
                 password=None,
                 tls=False,
                 ssl=False,
                 keyfile=None,
                 certfile=None,
                 queue_path=None,
                 default_sender=None,
                 sendmail_app=None,
                 sendmail_template=None,
                 debug=0):
        if ssl:
            self.smtp_mailer = SMTP_SSLMailer(
                hostname=host,
                port=port,
                username=username,
                password=password,
                no_tls=not(tls),
                force_tls=tls,
                debug_smtp=debug,
                keyfile=keyfile,
                certfile=certfile)
        else:
            self.smtp_mailer = SMTPMailer(
                hostname=host,
                port=port,
                username=username,
                password=password,
                no_tls=not(tls),
                force_tls=tls,
                debug_smtp=debug)

        self.direct_delivery = DirectMailDelivery(self.smtp_mailer)

        if queue_path:
            self.queue_delivery = QueuedMailDelivery(queue_path)
        else:
            self.queue_delivery = None

        self.sendmail_mailer = SendmailMailer(sendmail_app, sendmail_template)
        self.sendmail_delivery = DirectMailDelivery(self.sendmail_mailer)
        self.default_sender = default_sender
    def test_send_returns_messageId(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        from email.message import Message
        mailer = _makeMailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>',
                   'Steve <steve@examplecom>')
        message = Message()
        message['From'] = 'Jim <*****@*****.**>'
        message['To'] = 'some-zope-coders:;'
        message['Date'] = 'Date: Mon, 19 May 2003 10:17:36 -0400'
        message['Subject'] = 'example'
        message.set_payload('This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertTrue('.repoze.sendmail@' in msgid)
        self.assertEqual(message['Message-Id'],  msgid)
Beispiel #15
0
    def test_send_returns_messageId(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        from email.message import Message

        mailer = _makeMailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = "Jim <*****@*****.**"
        toaddrs = ("Guido <*****@*****.**>", "Steve <steve@examplecom>")
        message = Message()
        message["From"] = "Jim <*****@*****.**>"
        message["To"] = "some-zope-coders:;"
        message["Date"] = "Date: Mon, 19 May 2003 10:17:36 -0400"
        message["Subject"] = "example"
        message.set_payload("This is just an example\n")

        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertTrue(".repoze.sendmail@" in msgid)
        self.assertEqual(message["Message-Id"], msgid)
    def testBrokenMailerErrorsAreEaten(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        mailer = BrokenMailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>', 'Steve <steve@examplecom>')
        opt_headers = ('From: Jim <*****@*****.**>\n'
                       'To: some-zope-coders:;\n'
                       'Date: Mon, 19 May 2003 10:17:36 -0400\n'
                       'Message-Id: <*****@*****.**>\n')
        message = ('Subject: example\n' '\n' 'This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, opt_headers + message)
        try:
            transaction.commit()
        finally:
            # Clean up after ourselves
            transaction.abort()
Beispiel #17
0
    def run(self):
        other_threads = threading.enumerate()
        other_threads.remove(threading.current_thread())
        if self.name in [t.name for t in other_threads]:
            return
        mailer = SMTPMailer(port=config.SMTP_PORT)
        delivery = DirectMailDelivery(mailer)
        a = True
        while True:
            items = deepcopy(self.root)
            for hash, search in items.iteritems():
                if not search['active']:
                    continue
                results = performSearch(self.root, search)
                tell = []
                for result in results:
                    key = result.copy()
                    del key['total_price']
                    del key['book_link']
                    if key not in search['told']:
                        tell.append(result)
                        search['told'].append(key)

                if not tell:
                    continue

                url = config.URL
                remove_link = '%s/remove?email=%s&code=%s' % (url, search['email'], hash)
                journies = []
                for result in tell:
                    journey = config.JOURNEY_STR % result
                    journies.append(journey)

                journies = config.JOURNEY_JOINER.join(journies)

                message_text = config.EMAIL_MATCHES % {'journies': journies,
                                                       'remove_link': remove_link}

                message = Message()
                message.set_payload(message_text)
                delivery.send(config.FROM_ADDR, [search['email'],], message)
                transaction.commit()
            time.sleep(20)
Beispiel #18
0
    def test_send(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        import transaction
        from email.message import Message
        mailer = _makeMailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>',
                   'Steve <steve@examplecom>')
        message = Message()
        message['From'] = 'Jim <*****@*****.**>'
        message['To'] = 'some-zope-coders:;'
        message['Date'] = 'Date: Mon, 19 May 2003 10:17:36 -0400'
        message['Message-Id'] = ext_msgid = '<*****@*****.**>'
        message['Subject'] = 'example'
        message.set_payload('This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertEqual(msgid, '<*****@*****.**>')
        self.assertEqual(mailer.sent_messages, [])
        transaction.commit()
        self.assertEqual(mailer.sent_messages,
                          [(fromaddr, toaddrs, message)])

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertTrue('@' in msgid)
        self.assertEqual(mailer.sent_messages, [])
        transaction.commit()
        self.assertEqual(len(mailer.sent_messages), 1)
        self.assertEqual(mailer.sent_messages[0][0], fromaddr)
        self.assertEqual(mailer.sent_messages[0][1], toaddrs)
        self.assertEqual(mailer.sent_messages[0][2].get_payload(),
                          'This is just an example\n')
        self.assertEqual(message['Message-Id'],  msgid)
        self.assertEqual(message['Message-Id'], ext_msgid)

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertEqual(mailer.sent_messages, [])
        transaction.abort()
        self.assertEqual(mailer.sent_messages, [])
    def test_send(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        import transaction
        from email.message import Message
        mailer = _makeMailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>',
                   'Steve <steve@examplecom>')
        message = Message()
        message['From'] = 'Jim <*****@*****.**>'
        message['To'] = 'some-zope-coders:;'
        message['Date'] = 'Date: Mon, 19 May 2003 10:17:36 -0400'
        message['Message-Id'] = ext_msgid = '<*****@*****.**>'
        message['Subject'] = 'example'
        message.set_payload('This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertEqual(msgid, '<*****@*****.**>')
        self.assertEqual(mailer.sent_messages, [])
        transaction.commit()
        self.assertEqual(mailer.sent_messages,
                          [(fromaddr, toaddrs, message)])

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertTrue('@' in msgid)
        self.assertEqual(mailer.sent_messages, [])
        transaction.commit()
        self.assertEqual(len(mailer.sent_messages), 1)
        self.assertEqual(mailer.sent_messages[0][0], fromaddr)
        self.assertEqual(mailer.sent_messages[0][1], toaddrs)
        self.assertEqual(mailer.sent_messages[0][2].get_payload(),
                          'This is just an example\n')
        self.assertEqual(message['Message-Id'],  msgid)
        self.assertEqual(message['Message-Id'], ext_msgid)

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertEqual(mailer.sent_messages, [])
        transaction.abort()
        self.assertEqual(mailer.sent_messages, [])
    def testSMTPErrorInSendDoesntAbortTPC(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        mailer = SMTPResponseExceptionMailerStub(505)
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>', 'Steve <steve@examplecom>')
        opt_headers = ('From: Jim <*****@*****.**>\n'
                       'To: some-zope-coders:;\n'
                       'Date: Mon, 19 May 2003 10:17:36 -0400\n'
                       'Message-Id: <*****@*****.**>\n')
        message = ('Subject: example\n' '\n' 'This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, opt_headers + message)
        try:
            transaction.commit()
        except Exception as e:
            self.fail(str(e))
        finally:
            # Clean up after ourselves
            transaction.abort()
Beispiel #21
0
def sendAddEmail(request, email, hash, destinations):
    mailer = SMTPMailer(port=config.SMTP_PORT)
    delivery = DirectMailDelivery(mailer)
    human_destinations = [config.IATA_CODE_MAP[d] for d in destinations]
    if len(human_destinations)>1:
        human_destinations = '%s and %s' % (', '.join(human_destinations[:-1]),
                                            human_destinations[-1])
    elif len(human_destinations)==1:
        human_destinations = human_destinations[0]

    confirm_link = request.relative_url('confirm?email=%s&code=%s' %
                                        (urllib.quote(email),
                                         urllib.quote(hash))
                                        )
    message_text = config.EMAIL_CONFIRM % \
                       {'destinations': human_destinations,
                        'confirm_link': confirm_link}
    message = Message()
    message.set_payload(message_text)
    delivery.send(config.FROM_ADDR, [email,], message)
Beispiel #22
0
def send_mail(message: Message,
              _from: str,
              to: list,
              smtp_settings: dict,
              username: str,
              password: str,
              tls: bool = False,
              ssl: bool = False,
              debug: bool = False) -> None:

    host = smtp_settings['host']
    port = smtp_settings['port']

    # Begin transaction. Idk fully how this lib works but it's needed
    transaction.manager.begin()

    try:
        # Create a new SMTP mailer using vars declared above.
        # TODO Debug should be True or False depending on if debug mode is on
        # Idea TO DO to Github Issue plugin

        mailer = SMTPMailer(hostname=host,
                            port=port,
                            username=username,
                            password=password,
                            ssl=ssl,
                            no_tls=not tls,
                            debug_smtp=debug)

        # Need an object to deliver mail (for some reason)
        # TODO QueuedMailLDelvery support
        delivery = DirectMailDelivery(mailer)

        delivery.send(_from, to, message)

        # Commit transaction, this actually makes sure the thing is done
        transaction.manager.commit()
    # TODO Make Exception handling more specific
    except Exception as e:
        transaction.manager.abort()
        raise e
    def testBrokenMailerErrorsAreEaten(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        mailer = BrokenMailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>',
                   'Steve <steve@examplecom>')
        opt_headers = ('From: Jim <*****@*****.**>\n'
                       'To: some-zope-coders:;\n'
                       'Date: Mon, 19 May 2003 10:17:36 -0400\n'
                       'Message-Id: <*****@*****.**>\n')
        message =     ('Subject: example\n'
                       '\n'
                       'This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, opt_headers + message)
        try:
            transaction.commit()
        finally:
            # Clean up after ourselves
            transaction.abort()
Beispiel #24
0
    def test_send(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        import transaction
        from email.message import Message

        mailer = _makeMailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = "Jim <*****@*****.**"
        toaddrs = ("Guido <*****@*****.**>", "Steve <steve@examplecom>")
        message = Message()
        message["From"] = "Jim <*****@*****.**>"
        message["To"] = "some-zope-coders:;"
        message["Date"] = "Date: Mon, 19 May 2003 10:17:36 -0400"
        message["Message-Id"] = ext_msgid = "<*****@*****.**>"
        message["Subject"] = "example"
        message.set_payload("This is just an example\n")

        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertEqual(msgid, "<*****@*****.**>")
        self.assertEqual(mailer.sent_messages, [])
        transaction.commit()
        self.assertEqual(mailer.sent_messages, [(fromaddr, toaddrs, message)])

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertTrue("@" in msgid)
        self.assertEqual(mailer.sent_messages, [])
        transaction.commit()
        self.assertEqual(len(mailer.sent_messages), 1)
        self.assertEqual(mailer.sent_messages[0][0], fromaddr)
        self.assertEqual(mailer.sent_messages[0][1], toaddrs)
        self.assertEqual(mailer.sent_messages[0][2].get_payload(), "This is just an example\n")
        self.assertEqual(message["Message-Id"], msgid)
        self.assertEqual(message["Message-Id"], ext_msgid)

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assertEqual(mailer.sent_messages, [])
        transaction.abort()
        self.assertEqual(mailer.sent_messages, [])
    def testSend(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        mailer = MailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>',
                   'Steve <steve@examplecom>')
        opt_headers = ('From: Jim <*****@*****.**>\n'
                       'To: some-zope-coders:;\n'
                       'Date: Mon, 19 May 2003 10:17:36 -0400\n'
                       'Message-Id: <*****@*****.**>\n')
        message =     ('Subject: example\n'
                       '\n'
                       'This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, opt_headers + message)
        self.assertEquals(msgid, '*****@*****.**')
        self.assertEquals(mailer.sent_messages, [])
        transaction.commit()
        self.assertEquals(mailer.sent_messages,
                          [(fromaddr, toaddrs, opt_headers + message)])

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assert_('@' in msgid)
        self.assertEquals(mailer.sent_messages, [])
        transaction.commit()
        self.assertEquals(len(mailer.sent_messages), 1)
        self.assertEquals(mailer.sent_messages[0][0], fromaddr)
        self.assertEquals(mailer.sent_messages[0][1], toaddrs)
        self.assert_(mailer.sent_messages[0][2].endswith(message))
        new_headers = mailer.sent_messages[0][2][:-len(message)]
        self.assert_(new_headers.find('Message-Id: <%s>' % msgid) != -1)

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, opt_headers + message)
        self.assertEquals(mailer.sent_messages, [])
        transaction.abort()
        self.assertEquals(mailer.sent_messages, [])
    def testSMTPErrorInSendDoesntAbortTPC(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        mailer = SMTPResponseExceptionMailerStub(505)
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>',
                   'Steve <steve@examplecom>')
        opt_headers = ('From: Jim <*****@*****.**>\n'
                       'To: some-zope-coders:;\n'
                       'Date: Mon, 19 May 2003 10:17:36 -0400\n'
                       'Message-Id: <*****@*****.**>\n')
        message =     ('Subject: example\n'
                       '\n'
                       'This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, opt_headers + message)
        try:
            transaction.commit()
        except Exception as e:
            self.fail(str(e))
        finally:
            # Clean up after ourselves
            transaction.abort()
    def testSend(self):
        from repoze.sendmail.delivery import DirectMailDelivery
        mailer = MailerStub()
        delivery = DirectMailDelivery(mailer)
        fromaddr = 'Jim <*****@*****.**'
        toaddrs = ('Guido <*****@*****.**>', 'Steve <steve@examplecom>')
        opt_headers = ('From: Jim <*****@*****.**>\n'
                       'To: some-zope-coders:;\n'
                       'Date: Mon, 19 May 2003 10:17:36 -0400\n'
                       'Message-Id: <*****@*****.**>\n')
        message = ('Subject: example\n' '\n' 'This is just an example\n')

        msgid = delivery.send(fromaddr, toaddrs, opt_headers + message)
        self.assertEquals(msgid, '*****@*****.**')
        self.assertEquals(mailer.sent_messages, [])
        transaction.commit()
        self.assertEquals(mailer.sent_messages,
                          [(fromaddr, toaddrs, opt_headers + message)])

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, message)
        self.assert_('@' in msgid)
        self.assertEquals(mailer.sent_messages, [])
        transaction.commit()
        self.assertEquals(len(mailer.sent_messages), 1)
        self.assertEquals(mailer.sent_messages[0][0], fromaddr)
        self.assertEquals(mailer.sent_messages[0][1], toaddrs)
        self.assert_(mailer.sent_messages[0][2].endswith(message))
        new_headers = mailer.sent_messages[0][2][:-len(message)]
        self.assert_(new_headers.find('Message-Id: <%s>' % msgid) != -1)

        mailer.sent_messages = []
        msgid = delivery.send(fromaddr, toaddrs, opt_headers + message)
        self.assertEquals(mailer.sent_messages, [])
        transaction.abort()
        self.assertEquals(mailer.sent_messages, [])
Beispiel #28
0
from pyramid.url import resource_url
from repoze.sendmail.delivery import DirectMailDelivery
from repoze.sendmail.mailer import SMTPMailer
from repoze.sendmail.interfaces import IMailDelivery
from repoze.who.api import get_api
from zope.interface import directlyProvides
from zope.password.password import SSHAPasswordManager

from cartouche.interfaces import IAutoLogin
from cartouche.interfaces import ICameFromURL
from cartouche.interfaces import IPasswordGenerator
from cartouche.interfaces import ITokenGenerator

# By default, deliver e-mail via localhost, port 25.
localhost_mta = DirectMailDelivery(SMTPMailer())


def _fixup_url(context, request, base_url, **extra_qs):
    if base_url.startswith('/'):
        base_url = urljoin(resource_url(context, request), base_url)
    (sch, netloc, path, parms, qs, frag) = urlparse(base_url)
    qs_items = parse_qsl(qs) + extra_qs.items()
    qs = urlencode(qs_items, 1)
    return urlunparse((sch, netloc, path, parms, qs, frag))


def view_url(context, request, key, default_name, **extra_qs):
    configured = request.registry.settings.get('cartouche.%s' % key)
    if configured is None:
        if extra_qs:
Beispiel #29
0
class Mailer(object):
    """
    Manages sending of email messages.

    :param host: SMTP hostname
    :param port: SMTP port
    :param username: SMTP username
    :param password: SMPT password
    :param tls: use TLS
    :param ssl: use SSL
    :param keyfile: SSL key file 
    :param certfile: SSL certificate file
    :param queue_path: path to maildir for queued messages
    :param default_sender: default "from" address
    :param sendmail_app: path to "sendmail" binary.
           repoze defaults to "/usr/sbin/sendmail"
    :param sendmail_template: custom commandline template passed to sendmail
           binary, defaults to'["{sendmail_app}", "-t", "-i", "-f", "{sender}"]'
    :param debug: SMTP debug level
    """

    def __init__(self, 
                 host='localhost', 
                 port=25, 
                 username=None,
                 password=None, 
                 tls=False,
                 ssl=False,
                 keyfile=None,
                 certfile=None,
                 queue_path=None,
                 default_sender=None,
                 sendmail_app=None,
                 sendmail_template=None,
                 debug=0):


        if ssl:

            self.smtp_mailer = SMTP_SSLMailer(
                hostname=host,
                port=port,
                username=username,
                password=password,
                no_tls=not(tls),
                force_tls=tls,
                debug_smtp=debug,
                keyfile=keyfile,
                certfile=certfile)

        else:

            self.smtp_mailer = SMTPMailer(
                hostname=host, 
                port=port, 
                username=username, 
                password=password, 
                no_tls=not(tls), 
                force_tls=tls, 
                debug_smtp=debug)

        self.direct_delivery = DirectMailDelivery(self.smtp_mailer)

        if queue_path:
            self.queue_delivery = QueuedMailDelivery(queue_path)
        else:
            self.queue_delivery = None
            
        self.sendmail_mailer = SendmailMailer(sendmail_app, sendmail_template)
        self.sendmail_delivery = DirectMailDelivery(self.sendmail_mailer)

        self.default_sender = default_sender

    @classmethod
    def from_settings(cls, settings, prefix='mail.'):
        """
        Creates a new instance of **Mailer** from settings dict.

        :param settings: a settings dict-like
        :param prefix: prefix separating **pyramid_mailer** settings
        """

        settings = settings or {}

        kwarg_names = [prefix + k for k in (
                       'host', 'port', 'username',
                       'password', 'tls', 'ssl', 'keyfile', 
                       'certfile', 'queue_path', 'debug', 'default_sender')]
        
        size = len(prefix)

        kwargs = dict(((k[size:], settings[k]) for k in settings.keys() if
                        k in kwarg_names))

        for key in ('tls', 'ssl'):
            val = kwargs.get(key)
            if val:
                kwargs[key] = asbool(val)

        return cls(**kwargs)

    def send(self, message):
        """
        Sends a message. The message is handled inside a transaction, so 
        in case of failure (or the message fails) the message will not be sent.

        :param message: a **Message** instance.
        """

        return self.direct_delivery.send(*self._message_args(message))

    def send_immediately(self, message, fail_silently=False):
        """
        Sends a message immediately, outside the transaction manager. 

        If there is a connection error to the mail server this will have to 
        be handled manually. However if you pass ``fail_silently`` the error
        will be swallowed.

        :versionadded: 0.3

        :param message: a **Message** instance.

        :param fail_silently: silently handle connection errors.
        """

        try:
            return self.smtp_mailer.send(*self._message_args(message))
        except smtplib.socket.error:
            if not fail_silently:
                raise

    def send_to_queue(self, message):
        """
        Adds a message to a maildir queue.
        
        In order to handle this, the setting **mail.queue_path** must be 
        provided and must point to a valid maildir.

        :param message: a **Message** instance.
        """

        if not self.queue_delivery:
            raise RuntimeError("No queue_path provided")
    
        return self.queue_delivery.send(*self._message_args(message))

    def _message_args(self, message):

        message.sender = message.sender or self.default_sender
        # convert Lamson message to Python email package msessage
        msg = message.to_message() 
        return (message.sender, message.send_to, msg)

    def send_sendmail(self, message ):
        """
        Sends a message within the transaction manager.

        Uses the local sendmail option

        :param message: a **Message** instance.
        """
        return self.sendmail_delivery.send(*self._message_args(message))

    def send_immediately_sendmail(self, message, fail_silently=False):
        """
        Sends a message immediately, outside the transaction manager.

        Uses the local sendmail option

        If there is a connection error to the mail server this will have to
        be handled manually. However if you pass ``fail_silently`` the error
        will be swallowed.

        :param message: a **Message** instance.

        :param fail_silently: silently handle connection errors.
        """

        try:
            return self.sendmail_mailer.send(*self._message_args(message))
        except:
            if not fail_silently:
                raise
Beispiel #30
0
class Mailer(object):
    """Manages sending of email messages.

    :param host: SMTP hostname
    :param port: SMTP port
    :param username: SMTP username
    :param password: SMPT password
    :param tls: use TLS
    :param ssl: use SSL
    :param keyfile: SSL key file
    :param certfile: SSL certificate file
    :param queue_path: path to maildir for queued messages
    :param default_sender: default "from" address
    :param sendmail_app: path to "sendmail" binary.
           repoze defaults to "/usr/sbin/sendmail"
    :param sendmail_template: custom commandline template for sendmail binary,
           defaults to'["{sendmail_app}", "-t", "-i", "-f", "{sender}"]'
    :param transaction_manager: a transaction manager to join with when
           sending transactional emails
    :param debug: SMTP debug level
    """
    def __init__(self, **kw):
        smtp_mailer = kw.pop('smtp_mailer', None)
        if smtp_mailer is None:
            host = kw.pop('host', 'localhost')
            port = kw.pop('port', 25)
            username = kw.pop('username', None)
            password = kw.pop('password', None)
            tls = kw.pop('tls', False)
            ssl = kw.pop('ssl', False)
            keyfile = kw.pop('keyfile', None)
            certfile = kw.pop('certfile', None)
            debug = kw.pop('debug', 0)
            if ssl:
                smtp_mailer = SMTP_SSLMailer(hostname=host,
                                             port=port,
                                             username=username,
                                             password=password,
                                             no_tls=not (tls),
                                             force_tls=tls,
                                             debug_smtp=debug,
                                             keyfile=keyfile,
                                             certfile=certfile)
            else:
                smtp_mailer = SMTPMailer(hostname=host,
                                         port=port,
                                         username=username,
                                         password=password,
                                         no_tls=not (tls),
                                         force_tls=tls,
                                         debug_smtp=debug)
        self.smtp_mailer = smtp_mailer

        sendmail_mailer = kw.pop('sendmail_mailer', None)
        if sendmail_mailer is None:
            sendmail_mailer = SendmailMailer(
                kw.pop('sendmail_app', None),
                kw.pop('sendmail_template', None),
            )
        self.sendmail_mailer = sendmail_mailer

        self.queue_path = kw.pop('queue_path', None)
        self.default_sender = kw.pop('default_sender', None)

        transaction_manager = kw.pop('transaction_manager', None)
        if transaction_manager is None:
            transaction_manager = transaction.manager
        self.transaction_manager = transaction_manager

        if kw:
            raise ValueError('invalid options: %s' %
                             ', '.join(sorted(kw.keys())))

        self.direct_delivery = DirectMailDelivery(
            self.smtp_mailer, transaction_manager=transaction_manager)

        if self.queue_path:
            self.queue_delivery = QueuedMailDelivery(
                self.queue_path, transaction_manager=transaction_manager)
        else:
            self.queue_delivery = None

        self.sendmail_delivery = DirectMailDelivery(
            self.sendmail_mailer, transaction_manager=transaction_manager)

    @classmethod
    def from_settings(cls, settings, prefix='mail.'):
        """Create a new instance of 'Mailer' from settings dict.

        :param settings: a settings dict-like
        :param prefix: prefix separating 'pyramid_mailer' settings
        """
        settings = settings or {}

        kwarg_names = [
            prefix + k
            for k in ('host', 'port', 'username', 'password', 'tls', 'ssl',
                      'keyfile', 'certfile', 'queue_path', 'debug',
                      'default_sender', 'sendmail_app', 'sendmail_template')
        ]

        size = len(prefix)

        kwargs = dict(((k[size:], settings[k]) for k in settings.keys()
                       if k in kwarg_names))

        for key in ('tls', 'ssl'):
            val = kwargs.get(key)
            if val:
                kwargs[key] = asbool(val)

        for key in ('debug', 'port'):
            val = kwargs.get(key)
            if val:
                kwargs[key] = int(val)

        # list values
        for key in ('sendmail_template', ):
            if key in kwargs:
                kwargs[key] = aslist(kwargs.get(key))

        username = kwargs.pop('username', None)
        password = kwargs.pop('password', None)
        if not (username or password):
            # Setting both username and password to the empty string,
            # causes repoze.sendmail.mailer.SMTPMailer to authenticate.
            # This most likely makes no sense, so, in that case
            # set username to None to skip authentication.
            username = password = None

        return cls(username=username, password=password, **kwargs)

    def bind(self, **kw):
        """Create a new mailer with the same server configuration but with
        different delivery options.

        :param default_sender: default "from" address
        :param transaction_manager: a transaction manager to join with when
            sending transactional emails

        """
        _check_bind_options(kw)
        default_sender = kw.get('default_sender', self.default_sender)
        transaction_manager = kw.get('transaction_manager',
                                     self.transaction_manager)

        return self.__class__(
            smtp_mailer=self.smtp_mailer,
            sendmail_mailer=self.sendmail_mailer,
            queue_path=self.queue_path,
            default_sender=default_sender,
            transaction_manager=transaction_manager,
        )

    def send(self, message):
        """Send a message.

        The message is handled inside a transaction, so in case of failure
        (or the message fails) the message will not be sent.

        :param message: a 'Message' instance.
        """
        return self.direct_delivery.send(*self._message_args(message))

    def send_immediately(self, message, fail_silently=False):
        """Send a message immediately, outside the transaction manager.

        If there is a connection error to the mail server this will have to
        be handled manually. However if you pass ``fail_silently`` the error
        will be swallowed.

        :versionadded: 0.3

        :param message: a 'Message' instance.

        :param fail_silently: silently handle connection errors.
        """
        try:
            return self.smtp_mailer.send(*self._message_args(message))
        except smtplib.socket.error:
            if not fail_silently:
                raise

    def send_to_queue(self, message):
        """Add a message to a maildir queue.

        In order to handle this, the setting 'mail.queue_path' must be
        provided and must point to a valid maildir.

        :param message: a 'Message' instance.
        """
        if not self.queue_delivery:
            raise RuntimeError("No queue_path provided")

        return self.queue_delivery.send(*self._message_args(message))

    def _message_args(self, message):

        message.sender = message.sender or self.default_sender
        # convert Lamson message to Python email package msessage
        msg = message.to_message()
        return (message.sender, message.send_to, msg)

    def send_sendmail(self, message):
        """Send a message within the transaction manager.

        Uses the local sendmail option

        :param message: a 'Message' instance.
        """
        return self.sendmail_delivery.send(*self._message_args(message))

    def send_immediately_sendmail(self, message, fail_silently=False):
        """Send a message immediately, outside the transaction manager.

        Uses the local sendmail option

        If there is a connection error to the mail server this will have to
        be handled manually. However if you pass ``fail_silently`` the error
        will be swallowed.

        :param message: a 'Message' instance.

        :param fail_silently: silently handle connection errors.
        """
        try:
            return self.sendmail_mailer.send(*self._message_args(message))
        except:
            if not fail_silently:
                raise
Beispiel #31
0
class Mailer(object):
    """Manages sending of email messages.

    :param host: SMTP hostname
    :param port: SMTP port
    :param username: SMTP username
    :param password: SMPT password
    :param tls: use TLS
    :param ssl: use SSL
    :param keyfile: SSL key file
    :param certfile: SSL certificate file
    :param queue_path: path to maildir for queued messages
    :param default_sender: default "from" address
    :param sendmail_app: path to "sendmail" binary.
           repoze defaults to "/usr/sbin/sendmail"
    :param sendmail_template: custom commandline template passed to sendmail
           binary, defaults to'["{sendmail_app}", "-t", "-i", "-f", "{sender}"]'
    :param debug: SMTP debug level
    """

    def __init__(self,
                 host='localhost',
                 port=25,
                 username=None,
                 password=None,
                 tls=False,
                 ssl=False,
                 keyfile=None,
                 certfile=None,
                 queue_path=None,
                 default_sender=None,
                 sendmail_app=None,
                 sendmail_template=None,
                 debug=0):
        if ssl:
            self.smtp_mailer = SMTP_SSLMailer(
                hostname=host,
                port=port,
                username=username,
                password=password,
                no_tls=not(tls),
                force_tls=tls,
                debug_smtp=debug,
                keyfile=keyfile,
                certfile=certfile)
        else:
            self.smtp_mailer = SMTPMailer(
                hostname=host,
                port=port,
                username=username,
                password=password,
                no_tls=not(tls),
                force_tls=tls,
                debug_smtp=debug)

        self.direct_delivery = DirectMailDelivery(self.smtp_mailer)

        if queue_path:
            self.queue_delivery = QueuedMailDelivery(queue_path)
        else:
            self.queue_delivery = None

        self.sendmail_mailer = SendmailMailer(sendmail_app, sendmail_template)
        self.sendmail_delivery = DirectMailDelivery(self.sendmail_mailer)
        self.default_sender = default_sender

    @classmethod
    def from_settings(cls, settings, prefix='mail.'):
        """Create a new instance of 'Mailer' from settings dict.

        :param settings: a settings dict-like
        :param prefix: prefix separating 'pyramid_mailer' settings
        """
        settings = settings or {}

        kwarg_names = [prefix + k for k in (
                       'host', 'port', 'username',
                       'password', 'tls', 'ssl', 'keyfile',
                       'certfile', 'queue_path', 'debug', 'default_sender')]

        size = len(prefix)

        kwargs = dict(((k[size:], settings[k]) for k in settings.keys() if
                        k in kwarg_names))

        for key in ('tls', 'ssl'):
            val = kwargs.get(key)
            if val:
                kwargs[key] = asbool(val)

        return cls(**kwargs)

    def send(self, message):
        """Send a message.

        The message is handled inside a transaction, so in case of failure
        (or the message fails) the message will not be sent.

        :param message: a 'Message' instance.
        """
        return self.direct_delivery.send(*self._message_args(message))

    def send_immediately(self, message, fail_silently=False):
        """Send a message immediately, outside the transaction manager.

        If there is a connection error to the mail server this will have to
        be handled manually. However if you pass ``fail_silently`` the error
        will be swallowed.

        :versionadded: 0.3

        :param message: a 'Message' instance.

        :param fail_silently: silently handle connection errors.
        """
        try:
            return self.smtp_mailer.send(*self._message_args(message))
        except smtplib.socket.error:
            if not fail_silently:
                raise

    def send_to_queue(self, message):
        """Add a message to a maildir queue.

        In order to handle this, the setting 'mail.queue_path' must be
        provided and must point to a valid maildir.

        :param message: a 'Message' instance.
        """
        if not self.queue_delivery:
            raise RuntimeError("No queue_path provided")

        return self.queue_delivery.send(*self._message_args(message))

    def _message_args(self, message):

        message.sender = message.sender or self.default_sender
        # convert Lamson message to Python email package msessage
        msg = message.to_message()
        return (message.sender, message.send_to, msg)

    def send_sendmail(self, message ):
        """Send a message within the transaction manager.

        Uses the local sendmail option

        :param message: a 'Message' instance.
        """
        return self.sendmail_delivery.send(*self._message_args(message))

    def send_immediately_sendmail(self, message, fail_silently=False):
        """Send a message immediately, outside the transaction manager.

        Uses the local sendmail option

        If there is a connection error to the mail server this will have to
        be handled manually. However if you pass ``fail_silently`` the error
        will be swallowed.

        :param message: a 'Message' instance.

        :param fail_silently: silently handle connection errors.
        """
        try:
            return self.sendmail_mailer.send(*self._message_args(message))
        except:
            if not fail_silently:
                raise
Beispiel #32
0
    def __init__(self, **kw):
        smtp_mailer = kw.pop('smtp_mailer', None)
        if smtp_mailer is None:
            host = kw.pop('host', 'localhost')
            port = kw.pop('port', 25)
            username = kw.pop('username', None)
            password = kw.pop('password', None)
            tls = kw.pop('tls', False)
            ssl = kw.pop('ssl', False)
            keyfile = kw.pop('keyfile', None)
            certfile = kw.pop('certfile', None)
            debug = kw.pop('debug', 0)
            if ssl:
                smtp_mailer = SMTP_SSLMailer(hostname=host,
                                             port=port,
                                             username=username,
                                             password=password,
                                             no_tls=not (tls),
                                             force_tls=tls,
                                             debug_smtp=debug,
                                             keyfile=keyfile,
                                             certfile=certfile)
            else:
                smtp_mailer = SMTPMailer(hostname=host,
                                         port=port,
                                         username=username,
                                         password=password,
                                         no_tls=not (tls),
                                         force_tls=tls,
                                         debug_smtp=debug)
        self.smtp_mailer = smtp_mailer

        sendmail_mailer = kw.pop('sendmail_mailer', None)
        if sendmail_mailer is None:
            sendmail_mailer = SendmailMailer(
                kw.pop('sendmail_app', None),
                kw.pop('sendmail_template', None),
            )
        self.sendmail_mailer = sendmail_mailer

        self.queue_path = kw.pop('queue_path', None)
        self.default_sender = kw.pop('default_sender', None)

        transaction_manager = kw.pop('transaction_manager', None)
        if transaction_manager is None:
            transaction_manager = transaction.manager
        self.transaction_manager = transaction_manager

        if kw:
            raise ValueError('invalid options: %s' %
                             ', '.join(sorted(kw.keys())))

        self.direct_delivery = DirectMailDelivery(
            self.smtp_mailer, transaction_manager=transaction_manager)

        if self.queue_path:
            self.queue_delivery = QueuedMailDelivery(
                self.queue_path, transaction_manager=transaction_manager)
        else:
            self.queue_delivery = None

        self.sendmail_delivery = DirectMailDelivery(
            self.sendmail_mailer, transaction_manager=transaction_manager)
Beispiel #33
0
    def test_savepoint(self):
        import transaction
        
        mailer = _makeMailerStub()
        delivery = DirectMailDelivery(mailer)
        ( fromaddr , toaddrs ) = fromaddr_toaddrs()
        
        bodies_good = {}
        bodies_bad = {}
        for i in ( 1,3,5, ):
            bodies_good[i] = 'Sample Body - %s | Good' % i
        for i in ( 2,4,6, ):
            bodies_bad[i] = 'Sample Body - %s | Bad' % i
            
        bodies_all = dict(list(bodies_good.items()) +
                          list(bodies_bad.items()))

        transaction.begin()
        for i in range(1,7) :
            sp = transaction.savepoint()
            body = bodies_all[i]
            message = sample_message(body=body)
            msgid = delivery.send(fromaddr, toaddrs, message)
            self.assertEqual(msgid, '<*****@*****.**>')
            self.assertEqual(mailer.sent_messages, [])
            if i in bodies_bad :
                sp.rollback()
        
        # we shouldn't have sent anything
        self.assertEqual(mailer.sent_messages, [])
        
        # so now let's commit
        transaction.commit()
        
        # make sure we have the right number of messages
        self.assertEqual(len(mailer.sent_messages), len(bodies_good.values()))

        # generate our expected body
        bodies_expected = bodies_good.values()

        # make sure our bodies are only good        
        for f, t, m in mailer.sent_messages :
            self.assertTrue(m._payload in bodies_expected)

        ## ok, can we do multiple savepoints ?
        active_transaction = transaction.manager.get()

        mailer.sent_messages = []
        transaction.begin()
        sp_outer = transaction.savepoint()
        for i in range(1,7) :
            sp = transaction.savepoint()
            body = bodies_all[i]
            message = sample_message(body=body)
            msgid = delivery.send(fromaddr, toaddrs, message)
            self.assertEqual(msgid, '<*****@*****.**>')
            self.assertEqual(mailer.sent_messages, [])
            sp3 = transaction.savepoint()
            sp3.rollback()
            if i in bodies_bad :
                sp.rollback()
        sp_outer.rollback()
Beispiel #34
0
class Sendmail(object):

    def __init__(self):
        '''
        :ivar to_addr: The default recipient email address
            Will be set to the configuration variable "email_to",
            if configuration is available
        :ivar from_addr: The default sender email address
            Will be set to the configuration variable "admin_email_from",
            if configuration is available
        '''

        self.to_addr = config.get('email_to')
        self.from_addr = config.get('admin_email_from')

        smtp_server = config.get('smtp_server')
        smtp_use_tls = asbool(config.get('smtp_use_tls'))
        smtp_username = config.get('smtp_username')
        smtp_password = config.get('smtp_password')

        test = asbool(config.get('test'))

        if test:
            log.debug('Using DummyDelivery()')
            self.delivery = DummyDelivery()
        else:  # pragma: no cover
            if smtp_server:
                mailer = SMTPMailer(hostname=smtp_server,
                    username=smtp_username, password=smtp_password,
                    force_tls=smtp_use_tls)
                log.debug('Using SMTPMailer(hostname=%s, ...)', smtp_server)
            else:
                mailer = SendmailMailer()
                log.debug('Using SendmailMailer()')
            self.delivery = DirectMailDelivery(mailer)

    def __call__(self, subject, body, to_addrs=None, from_addr=None, cc_managers=False):
        '''
        :param subject:
        :param body:
        :param to_addrs: List of recipient email addresses
            If to_addrs is None, the default to_addr will be used.
            Additionally, if to_addrs is a list and contains None as an item,
            that item will also be replaced by the default to_addr.
            (see :py:attr:`Sendmail.to_addr`)
        :param from_addr: Sender email address
            If from_addr is None, the default from_addr will be used.
            (see :py:attr:`Sendmail.from_addr`)
        :param cc_managers: Whether to Cc the email to all managers
        '''

        if to_addrs is None:
            to_addrs = [self.to_addr]
        elif isinstance(to_addrs, basestring):
            to_addrs = [to_addrs]
        else:
            to_addrs = set(to_addrs)  #: :type to_addrs: set
            try:
                to_addrs.remove(None)
            except KeyError:
                pass
            else:
                to_addrs.add(self.to_addr)

        if from_addr is None:
            from_addr = self.from_addr

        cc_addrs = None
        if cc_managers:
            cc_addrs = []
            for manager in User.query.join(User.groups).join(Group.permissions).filter_by(permission_name='manage'):
                cc_addrs.append(manager.email_address)

        # Make human-readable message for logging
        _msg = _make_message(from_addr, to_addrs, subject, body, charset=None, cc_addrs=cc_addrs)
        log.debug(_msg.as_string())

        msg = _make_message(from_addr, to_addrs, subject, body, cc_addrs=cc_addrs)
        msgid = self.delivery.send(from_addr, to_addrs, msg)

        return msgid
Beispiel #35
0
class Sendmail(object):
    def __init__(self):
        '''
        :ivar to_addr: The default recipient email address
            Will be set to the configuration variable "email_to",
            if configuration is available
        :ivar from_addr: The default sender email address
            Will be set to the configuration variable "admin_email_from",
            if configuration is available
        '''

        self.to_addr = config.get('email_to')
        self.from_addr = config.get('admin_email_from')

        smtp_server = config.get('smtp_server')
        smtp_use_tls = asbool(config.get('smtp_use_tls'))
        smtp_username = config.get('smtp_username')
        smtp_password = config.get('smtp_password')

        test = asbool(config.get('test'))

        if test:
            log.debug('Using DummyDelivery()')
            self.delivery = DummyDelivery()
        else:  # pragma: no cover
            if smtp_server:
                mailer = SMTPMailer(hostname=smtp_server,
                                    username=smtp_username,
                                    password=smtp_password,
                                    force_tls=smtp_use_tls)
                log.debug('Using SMTPMailer(hostname=%s, ...)', smtp_server)
            else:
                mailer = SendmailMailer()
                log.debug('Using SendmailMailer()')
            self.delivery = DirectMailDelivery(mailer)

    def __call__(self,
                 subject,
                 body,
                 to_addrs=None,
                 from_addr=None,
                 cc_managers=False):
        '''
        :param subject:
        :param body:
        :param to_addrs: List of recipient email addresses
            If to_addrs is None, the default to_addr will be used.
            Additionally, if to_addrs is a list and contains None as an item,
            that item will also be replaced by the default to_addr.
            (see :py:attr:`Sendmail.to_addr`)
        :param from_addr: Sender email address
            If from_addr is None, the default from_addr will be used.
            (see :py:attr:`Sendmail.from_addr`)
        :param cc_managers: Whether to Cc the email to all managers
        '''

        if to_addrs is None:
            to_addrs = [self.to_addr]
        elif isinstance(to_addrs, basestring):
            to_addrs = [to_addrs]
        else:
            to_addrs = set(to_addrs)  #: :type to_addrs: set
            try:
                to_addrs.remove(None)
            except KeyError:
                pass
            else:
                to_addrs.add(self.to_addr)

        if from_addr is None:
            from_addr = self.from_addr

        cc_addrs = None
        if cc_managers:
            cc_addrs = []
            for manager in User.query.join(User.groups).join(
                    Group.permissions).filter_by(permission_name='manage'):
                cc_addrs.append(manager.email_address)

        # Make human-readable message for logging
        _msg = _make_message(from_addr,
                             to_addrs,
                             subject,
                             body,
                             charset=None,
                             cc_addrs=cc_addrs)
        log.debug(_msg.as_string())

        msg = _make_message(from_addr,
                            to_addrs,
                            subject,
                            body,
                            cc_addrs=cc_addrs)
        msgid = self.delivery.send(from_addr, to_addrs, msg)

        return msgid
Beispiel #36
0
class Mailer(object):
    """Manages sending of email messages.

    :param host: SMTP hostname
    :param port: SMTP port
    :param username: SMTP username
    :param password: SMPT password
    :param tls: use TLS
    :param ssl: use SSL
    :param keyfile: SSL key file
    :param certfile: SSL certificate file
    :param queue_path: path to maildir for queued messages
    :param default_sender: default "from" address
    :param sendmail_app: path to "sendmail" binary.
           repoze defaults to "/usr/sbin/sendmail"
    :param sendmail_template: custom commandline template for sendmail binary,
           defaults to'["{sendmail_app}", "-t", "-i", "-f", "{sender}"]'
    :param transaction_manager: a transaction manager to join with when
           sending transactional emails
    :param debug: SMTP debug level
    """

    def __init__(self, **kw):
        smtp_mailer = kw.pop("smtp_mailer", None)
        if smtp_mailer is None:
            host = kw.pop("host", "localhost")
            port = kw.pop("port", 25)
            username = kw.pop("username", None)
            password = kw.pop("password", None)
            tls = kw.pop("tls", False)
            ssl = kw.pop("ssl", False)
            keyfile = kw.pop("keyfile", None)
            certfile = kw.pop("certfile", None)
            debug = kw.pop("debug", 0)
            if ssl:
                smtp_mailer = SMTP_SSLMailer(
                    hostname=host,
                    port=port,
                    username=username,
                    password=password,
                    no_tls=not (tls),
                    force_tls=tls,
                    debug_smtp=debug,
                    keyfile=keyfile,
                    certfile=certfile,
                )
            else:
                smtp_mailer = SMTPMailer(
                    hostname=host,
                    port=port,
                    username=username,
                    password=password,
                    no_tls=not (tls),
                    force_tls=tls,
                    debug_smtp=debug,
                )
        self.smtp_mailer = smtp_mailer

        sendmail_mailer = kw.pop("sendmail_mailer", None)
        if sendmail_mailer is None:
            sendmail_mailer = SendmailMailer(kw.pop("sendmail_app", None), kw.pop("sendmail_template", None))
        self.sendmail_mailer = sendmail_mailer

        self.queue_path = kw.pop("queue_path", None)
        self.default_sender = kw.pop("default_sender", None)

        transaction_manager = kw.pop("transaction_manager", None)
        if transaction_manager is None:
            transaction_manager = transaction.manager
        self.transaction_manager = transaction_manager

        if kw:
            raise ValueError("invalid options: %s" % ", ".join(sorted(kw.keys())))

        self.direct_delivery = DirectMailDelivery(self.smtp_mailer, transaction_manager=transaction_manager)

        if self.queue_path:
            self.queue_delivery = QueuedMailDelivery(self.queue_path, transaction_manager=transaction_manager)
        else:
            self.queue_delivery = None

        self.sendmail_delivery = DirectMailDelivery(self.sendmail_mailer, transaction_manager=transaction_manager)

    @classmethod
    def from_settings(cls, settings, prefix="mail."):
        """Create a new instance of 'Mailer' from settings dict.

        :param settings: a settings dict-like
        :param prefix: prefix separating 'pyramid_mailer' settings
        """
        settings = settings or {}

        kwarg_names = [
            prefix + k
            for k in (
                "host",
                "port",
                "username",
                "password",
                "tls",
                "ssl",
                "keyfile",
                "certfile",
                "queue_path",
                "debug",
                "default_sender",
                "sendmail_app",
                "sendmail_template",
            )
        ]

        size = len(prefix)

        kwargs = dict(((k[size:], settings[k]) for k in settings.keys() if k in kwarg_names))

        for key in ("tls", "ssl"):
            val = kwargs.get(key)
            if val:
                kwargs[key] = asbool(val)

        for key in ("debug", "port"):
            val = kwargs.get(key)
            if val:
                kwargs[key] = int(val)

        # list values
        for key in ("sendmail_template",):
            if key in kwargs:
                kwargs[key] = aslist(kwargs.get(key))

        username = kwargs.pop("username", None)
        password = kwargs.pop("password", None)
        if not (username or password):
            # Setting both username and password to the empty string,
            # causes repoze.sendmail.mailer.SMTPMailer to authenticate.
            # This most likely makes no sense, so, in that case
            # set username to None to skip authentication.
            username = password = None

        return cls(username=username, password=password, **kwargs)

    def bind(self, **kw):
        """Create a new mailer with the same server configuration but with
        different delivery options.

        :param default_sender: default "from" address
        :param transaction_manager: a transaction manager to join with when
            sending transactional emails

        """
        _check_bind_options(kw)
        default_sender = kw.get("default_sender", self.default_sender)
        transaction_manager = kw.get("transaction_manager", self.transaction_manager)

        return self.__class__(
            smtp_mailer=self.smtp_mailer,
            sendmail_mailer=self.sendmail_mailer,
            queue_path=self.queue_path,
            default_sender=default_sender,
            transaction_manager=transaction_manager,
        )

    def send(self, message):
        """Send a message.

        The message is handled inside a transaction, so in case of failure
        (or the message fails) the message will not be sent.

        :param message: a 'Message' instance.
        """
        return self.direct_delivery.send(*self._message_args(message))

    def send_immediately(self, message, fail_silently=False):
        """Send a message immediately, outside the transaction manager.

        If there is a connection error to the mail server this will have to
        be handled manually. However if you pass ``fail_silently`` the error
        will be swallowed.

        :versionadded: 0.3

        :param message: a 'Message' instance.

        :param fail_silently: silently handle connection errors.
        """
        try:
            return self.smtp_mailer.send(*self._message_args(message))
        except smtplib.socket.error:
            if not fail_silently:
                raise

    def send_to_queue(self, message):
        """Add a message to a maildir queue.

        In order to handle this, the setting 'mail.queue_path' must be
        provided and must point to a valid maildir.

        :param message: a 'Message' instance.
        """
        if not self.queue_delivery:
            raise RuntimeError("No queue_path provided")

        return self.queue_delivery.send(*self._message_args(message))

    def _message_args(self, message):

        message.sender = message.sender or self.default_sender
        # convert Lamson message to Python email package msessage
        msg = message.to_message()
        return (message.sender, message.send_to, msg)

    def send_sendmail(self, message):
        """Send a message within the transaction manager.

        Uses the local sendmail option

        :param message: a 'Message' instance.
        """
        return self.sendmail_delivery.send(*self._message_args(message))

    def send_immediately_sendmail(self, message, fail_silently=False):
        """Send a message immediately, outside the transaction manager.

        Uses the local sendmail option

        If there is a connection error to the mail server this will have to
        be handled manually. However if you pass ``fail_silently`` the error
        will be swallowed.

        :param message: a 'Message' instance.

        :param fail_silently: silently handle connection errors.
        """
        try:
            return self.sendmail_mailer.send(*self._message_args(message))
        except:
            if not fail_silently:
                raise
Beispiel #37
0
class Mailer(object):
    """
    Manages sending of email messages.

    :param host: SMTP hostname
    :param port: SMTP port
    :param username: SMTP username
    :param password: SMPT password
    :param tls: use TLS
    :param ssl: use SSL
    :param keyfile: SSL key file 
    :param certfile: SSL certificate file
    :param queue_path: path to maildir for queued messages
    :param default_sender: default "from" address
    :param debug: SMTP debug level
    """
    def __init__(self,
                 host='localhost',
                 port=25,
                 username=None,
                 password=None,
                 tls=False,
                 ssl=False,
                 keyfile=None,
                 certfile=None,
                 queue_path=None,
                 default_sender=None,
                 debug=0):

        if ssl:

            self.smtp_mailer = SMTP_SSLMailer(hostname=host,
                                              port=port,
                                              username=username,
                                              password=password,
                                              no_tls=not (tls),
                                              force_tls=tls,
                                              debug_smtp=debug,
                                              keyfile=keyfile,
                                              certfile=certfile)

        else:

            self.smtp_mailer = SMTPMailer(hostname=host,
                                          port=port,
                                          username=username,
                                          password=password,
                                          no_tls=not (tls),
                                          force_tls=tls,
                                          debug_smtp=debug)

        self.direct_delivery = DirectMailDelivery(self.smtp_mailer)

        if queue_path:
            self.queue_delivery = QueuedMailDelivery(queue_path)
        else:
            self.queue_delivery = None

        self.default_sender = default_sender

    @classmethod
    def from_settings(cls, settings, prefix='mail.'):
        """
        Creates a new instance of **Message** from settings dict.

        :param settings: a settings dict-like
        :param prefix: prefix separating **pyramid_mailer** settings
        """

        settings = settings or {}

        kwarg_names = [
            prefix + k for k in ('host', 'port', 'username', 'password', 'tls',
                                 'ssl', 'keyfile', 'certfile', 'queue_path',
                                 'debug', 'default_sender')
        ]

        size = len(prefix)

        kwargs = dict(((k[size:], settings[k]) for k in settings.keys()
                       if k in kwarg_names))

        return cls(**kwargs)

    def send(self, message):
        """
        Sends a message. The message is handled inside a transaction, so 
        in case of failure (or the message fails) the message will not be sent.

        :param message: a **Message** instance.
        """

        return self.direct_delivery.send(*self._message_args(message))

    def send_immediately(self, message, fail_silently=False):
        """
        Sends a message immediately, outside the transaction manager. 

        If there is a connection error to the mail server this will have to 
        be handled manually. However if you pass ``fail_silently`` the error
        will be swallowed.

        :versionadded: 0.3

        :param message: a **Message** instance.

        :param fail_silently: silently handle connection errors.
        """

        try:
            return self.smtp_mailer.send(*self._message_args(message))
        except smtplib.socket.error:
            if not fail_silently:
                raise

    def send_to_queue(self, message):
        """
        Adds a message to a maildir queue.
        
        In order to handle this, the setting **mail.queue_path** must be 
        provided and must point to a valid maildir.

        :param message: a **Message** instance.
        """

        if not self.queue_delivery:
            raise RuntimeError, "No queue_path provided"

        return self.queue_delivery.send(*self._message_args(message))

    def _message_args(self, message):

        message.sender = message.sender or self.default_sender

        return (message.sender, message.send_to, message.to_message())