Anonymous avatar Anonymous committed 71390d8

smtp-branch

Comments (0)

Files changed (5)

flaskext/mail.py

-# -*- coding: utf-8 -*-
-"""
-    flaskext.mail
-    ~~~~~~~~~~~~~
-
-    Flask extension for sending email.
-
-    :copyright: (c) 2010 by Dan Jacob.
-    :license: BSD, see LICENSE for more details.
-"""
-from __future__ import with_statement
-
-from flask import _request_ctx_stack
-
-from lamson.server import Relay
-from lamson.mail import MailResponse
-
-from contextlib import contextmanager
-
-try:
-    import blinker
-    signals = blinker.Namespace()
-    email_dispatched = signals.signal("email-dispatched")
-    use_signals = True
-except ImportError:
-    use_signals = False
-
-class BadHeaderError(Exception): pass
-
-class Attachment(object):
-
-    """
-    Encapsulates file attachment information.
-
-    :versionadded: 0.3.5
-
-    :param filename: filename of attachment
-    :param content_type: file mimetype
-    :param data: the raw file data
-    :param disposition: content-disposition (if any)
- 
-    """
-
-    def __init__(self, filename=None, content_type=None, data=None, 
-        disposition=None):
-
-        self.filename = filename
-        self.content_type = content_type
-        self.data = data
-        self.disposition = disposition
- 
-class Connection(object):
-
-    """Handles connection to host."""
-
-    def __init__(self, mail, send_many=False):
-
-        self.mail = mail
-        self.app = self.mail.app
-        self.relay = self.mail.relay
-        self.testing = self.mail.testing
-        self.send_many = send_many
-
-    def __enter__(self):
-
-        # if send_many, create a permanent connection to the host
-
-        if self.send_many and not self.testing:
-            self.host = self.relay.configure_relay(self.relay.hostname)
-        else:
-            self.host = None
-        
-        return self
-
-    def __exit__(self, exc_type, exc_value, tb):
-        if self.host:
-            self.host.quit()
-
-    def send_test_mail(self, message):
-        """
-        This will be deprecated. It's difficult to get a handle
-        on the outbox inside of a tested view. 
-
-        Instead use ``record_messages``
-
-        :deprecated:
-        """
-        outbox = getattr(_request_ctx_stack.top.g, 'outbox', [])
-        outbox.append(message)
-
-        _request_ctx_stack.top.g.outbox = outbox
-    
-    def send(self, message):
-        """
-        Sends message.
-        
-        :param message: Message instance.
-        """
-        if self.testing:
-            self.send_test_mail(message)
-        elif self.host:
-            self.host.sendmail(message.sender,
-                               message.recipients,
-                               str(message.get_response()))
-        else:
-            self.relay.deliver(message.get_response())
-        
-        if use_signals:
-            email_dispatched.send(message, app=self.app)
-
-    def send_message(self, *args, **kwargs):
-        """
-        Shortcut for send(msg). 
-
-        Takes same arguments as Message constructor.
-    
-        :versionadded: 0.3.5
-
-        """
-
-        self.send(Message(*args, **kwargs))
-
-
-class Mail(object):
-    
-    """
-    Manages email messaging
-
-    :param app: Flask instance
-    """
-
-    relay_class = Relay
-
-    def __init__(self, app=None):
-        self._relay = None
-        
-        if app is not None:
-            self.init_app(app)
-
-    def init_app(self, app):
-        """
-        Initializes your mail settings from the application
-        settings.
-
-        You can use this if you want to set up your Mail instance
-        at configuration time.
-
-        :param app: Flask application instance
-        """
-
-        server = app.config.get('MAIL_SERVER', '127.0.0.1')
-        username = app.config.get('MAIL_USERNAME')
-        password = app.config.get('MAIL_PASSWORD')
-        port = app.config.get('MAIL_PORT', 25)
-        use_tls = app.config.get('MAIL_USE_TLS', False)
-        use_ssl = app.config.get('MAIL_USE_SSL', False)
-        debug = int(app.config.get('MAIL_DEBUG', app.debug))
-    
-        self.relay = self.relay_class(server, port, username, password,
-            use_ssl, use_tls, debug)
-
-        self.testing = app.config['TESTING']
-        
-        self.app = app
-
-    @contextmanager
-    def record_messages(self):
-        """
-        Records all messages. Use in unit tests for example::
-            
-            with mail.record_messages() as outbox:
-                response = app.test_client.get("/email-sending-view/")
-                assert len(outbox) == 1
-                assert outbox[0].subject == "testing"
-
-        You must have blinker installed in order to use this feature.
-        :versionadded: 0.4
-
-        """
-
-        if not use_signals:
-            raise RuntimeError, "blinker must be installed"
-        
-        outbox = []
-
-        def _record(message, app):
-            outbox.append(message)
-        
-        email_dispatched.connect(_record)
-
-        try:
-            yield outbox
-        finally:
-            email_dispatched.disconnect(_record)
-
-    def send(self, message):
-        """
-        Sends a single message instance. If TESTING is True
-        the message will not actually be sent.
-
-        :param message: a Message instance.
-        """
-
-        with self.connect(send_many=False) as connection:
-            message.send(connection)
-
-    def send_message(self, *args, **kwargs):
-        """
-        Shortcut for send(msg). 
-
-        Takes same arguments as Message constructor.
-    
-        :versionadded: 0.3.5
-        """
-
-        self.send(Message(*args, **kwargs))
-
-    def connect(self, send_many=True):
-        """
-        Opens a connection to the mail host.
-        
-        :param send_many: keep connection alive
-        """
-        return Connection(self, send_many=send_many) 
-                          
-
-class Message(object):
-    
-    """
-    Encapsulates an email message.
-
-    :param subject: email subject header
-    :param recipients: list of email addresses
-    :param body: plain text message
-    :param html: HTML message
-    :param sender: email sender address, or **DEFAULT_MAIL_SENDER** by default
-    :param attachments: list of Attachment instances
-    """
-
-    def __init__(self, subject, 
-                 recipients=None, 
-                 body=None, 
-                 html=None, 
-                 sender=None,
-                 attachments=None):
-
-
-        if sender is None:
-            app = _request_ctx_stack.top.app
-            sender = app.config.get("DEFAULT_MAIL_SENDER")
-
-        if isinstance(sender, tuple):
-            # sender can be tuple of (name, address)
-            sender = "%s <%s>" % sender
-
-        self.subject = subject
-        self.sender = sender
-        self.body = body
-        self.html = html
-
-        if recipients is None:
-            recipients = []
-
-        self.recipients = list(recipients)
-        
-        if attachments is None:
-            attachments = []
-
-        self.attachments = attachments
-
-    def get_response(self):
-        """
-        Creates a Lamson MailResponse instance
-        """
-
-        response = MailResponse(Subject=self.subject, 
-                                To=self.recipients,
-                                From=self.sender,
-                                Body=self.body,
-                                Html=self.html)
-
-        for attachment in self.attachments:
-
-            response.attach(attachment.filename, 
-                            attachment.content_type, 
-                            attachment.data, 
-                            attachment.disposition)
-
-        return response
-    
-    def is_bad_headers(self):
-        """
-        Checks for bad headers i.e. newlines in subject, sender or recipients.
-        """
-       
-        for val in [self.subject, self.sender] + self.recipients:
-            for c in '\r\n':
-                if c in val:
-                    return True
-        return False
-        
-    def send(self, connection):
-        """
-        Verifies and sends the message.
-        """
-        
-        assert self.recipients, "No recipients have been added"
-        assert self.body or self.html, "No body or HTML has been set"
-        assert self.sender, "No sender address has been set"
-
-        if self.is_bad_headers():
-            raise BadHeaderError
-
-        connection.send(self)
-
-    def add_recipient(self, recipient):
-        """
-        Adds another recipient to the message.
-        
-        :param recipient: email address of recipient.
-        """
-        
-        self.recipients.append(recipient)
-
-    def attach(self, 
-               filename=None, 
-               content_type=None, 
-               data=None,
-               disposition=None):
-        
-        """
-        Adds an attachment to the message.
-        
-        :param filename: filename of attachment
-        :param content_type: file mimetype
-        :param data: the raw file data
-        :param disposition: content-disposition (if any)
-        """
-
-        self.attachments.append(
-            Attachment(filename, content_type, data, disposition))
-

flaskext/mail/__init__.py

+# -*- coding: utf-8 -*-
+"""
+    flaskext.mail
+    ~~~~~~~~~~~~~
+
+    Flask extension for sending email.
+
+    :copyright: (c) 2010 by Dan Jacob.
+    :license: BSD, see LICENSE for more details.
+"""
+from __future__ import with_statement
+
+import smtplib
+
+from lamson.server import Relay
+from lamson.mail import MailResponse
+
+from flask import _request_ctx_stack
+
+from contextlib import contextmanager
+
+try:
+    import blinker
+    signals = blinker.Namespace()
+    email_dispatched = signals.signal("email-dispatched")
+    use_signals = True
+except ImportError:
+    use_signals = False
+
+class BadHeaderError(Exception): pass
+
+class Attachment(object):
+
+    """
+    Encapsulates file attachment information.
+
+    :versionadded: 0.3.5
+
+    :param filename: filename of attachment
+    :param content_type: file mimetype
+    :param data: the raw file data
+    :param disposition: content-disposition (if any)
+ 
+    """
+
+    def __init__(self, filename=None, content_type=None, data=None, 
+        disposition=None):
+
+        self.filename = filename
+        self.content_type = content_type
+        self.data = data
+        self.disposition = disposition
+ 
+
+class Connection(object):
+
+    """Handles connection to host."""
+
+    def __init__(self, mail):
+
+        self.mail = mail
+        self.app = self.mail.app
+        self.testing = self.app.testing
+
+    def __enter__(self):
+
+        # if send_many, create a permanent connection to the host
+
+        if self.testing:
+            self.host = None
+        else:
+            self.host = self.configure_host()
+        
+        return self
+
+    def __exit__(self, exc_type, exc_value, tb):
+        if self.host:
+            self.host.quit()
+    
+    def configure_host(self):
+        
+        if self.mail.use_ssl:
+            host = smtplib.SMTP_SSL(self.mail.server, self.mail.port)
+        else:
+            host = smtplib.SMTP(self.mail.server, self.mail.port)
+
+        host.set_debuglevel(int(self.app.debug))
+
+        if self.mail.use_tls:
+            host.starttls()
+        if self.mail.username and self.mail.password:
+            host.login(self.mail.username, self.mail.password)
+
+        return host
+
+    def send(self, message):
+        """
+        Sends message.
+        
+        :param message: Message instance.
+        """
+        if self.host:
+            self.host.sendmail(message.sender,
+                               message.recipients,
+                               str(message.get_response()))
+        
+        if use_signals:
+            email_dispatched.send(message, app=self.app)
+
+    def send_message(self, *args, **kwargs):
+        """
+        Shortcut for send(msg). 
+
+        Takes same arguments as Message constructor.
+    
+        :versionadded: 0.3.5
+
+        """
+
+        self.send(Message(*args, **kwargs))
+
+
+class Mail(object):
+    
+    """
+    Manages email messaging
+
+    :param app: Flask instance
+    """
+
+    relay_class = Relay
+
+    def __init__(self, app=None):
+        self._relay = None
+        
+        if app is not None:
+            self.init_app(app)
+
+    def init_app(self, app):
+        """
+        Initializes your mail settings from the application
+        settings.
+
+        You can use this if you want to set up your Mail instance
+        at configuration time.
+
+        :param app: Flask application instance
+        """
+
+        self.server = app.config.get('MAIL_SERVER', '127.0.0.1')
+        self.username = app.config.get('MAIL_USERNAME')
+        self.password = app.config.get('MAIL_PASSWORD')
+        self.port = app.config.get('MAIL_PORT', 25)
+        self.use_tls = app.config.get('MAIL_USE_TLS', False)
+        self.use_ssl = app.config.get('MAIL_USE_SSL', False)
+        self.debug = int(app.config.get('MAIL_DEBUG', app.debug))
+        self.testing = app.testing
+        
+        self.app = app
+
+    @contextmanager
+    def record_messages(self):
+        """
+        Records all messages. Use in unit tests for example::
+            
+            with mail.record_messages() as outbox:
+                response = app.test_client.get("/email-sending-view/")
+                assert len(outbox) == 1
+                assert outbox[0].subject == "testing"
+
+        You must have blinker installed in order to use this feature.
+        :versionadded: 0.4
+
+        """
+
+        if not use_signals:
+            raise RuntimeError, "blinker must be installed"
+        
+        outbox = []
+
+        def _record(message, app):
+            outbox.append(message)
+        
+        email_dispatched.connect(_record)
+
+        try:
+            yield outbox
+        finally:
+            email_dispatched.disconnect(_record)
+
+    def send(self, message):
+        """
+        Sends a single message instance. If TESTING is True
+        the message will not actually be sent.
+
+        :param message: a Message instance.
+        """
+
+        with self.connect() as connection:
+            message.send(connection)
+
+    def send_message(self, *args, **kwargs):
+        """
+        Shortcut for send(msg). 
+
+        Takes same arguments as Message constructor.
+    
+        :versionadded: 0.3.5
+        """
+
+        self.send(Message(*args, **kwargs))
+
+    def connect(self):
+        """
+        Opens a connection to the mail host.
+        """
+        return Connection(self) 
+                          
+
+class Message(object):
+    
+    """
+    Encapsulates an email message.
+
+    :param subject: email subject header
+    :param recipients: list of email addresses
+    :param body: plain text message
+    :param html: HTML message
+    :param sender: email sender address, or **DEFAULT_MAIL_SENDER** by default
+    :param attachments: list of Attachment instances
+    """
+
+    def __init__(self, subject, 
+                 recipients=None, 
+                 body=None, 
+                 html=None, 
+                 sender=None,
+                 attachments=None):
+
+
+        if sender is None:
+            app = _request_ctx_stack.top.app
+            sender = app.config.get("DEFAULT_MAIL_SENDER")
+
+        if isinstance(sender, tuple):
+            # sender can be tuple of (name, address)
+            sender = "%s <%s>" % sender
+
+        self.subject = subject
+        self.sender = sender
+        self.body = body
+        self.html = html
+
+        if recipients is None:
+            recipients = []
+
+        self.recipients = list(recipients)
+        
+        if attachments is None:
+            attachments = []
+
+        self.attachments = attachments
+
+    def get_response(self):
+        """
+        Creates a Lamson MailResponse instance
+        """
+
+        response = MailResponse(Subject=self.subject, 
+                                To=self.recipients,
+                                From=self.sender,
+                                Body=self.body,
+                                Html=self.html)
+
+        for attachment in self.attachments:
+
+            response.attach(attachment.filename, 
+                            attachment.content_type, 
+                            attachment.data, 
+                            attachment.disposition)
+
+        return response
+    
+    def is_bad_headers(self):
+        """
+        Checks for bad headers i.e. newlines in subject, sender or recipients.
+        """
+       
+        for val in [self.subject, self.sender] + self.recipients:
+            for c in '\r\n':
+                if c in val:
+                    return True
+        return False
+        
+    def send(self, connection):
+        """
+        Verifies and sends the message.
+        """
+        
+        assert self.recipients, "No recipients have been added"
+        assert self.body or self.html, "No body or HTML has been set"
+        assert self.sender, "No sender address has been set"
+
+        if self.is_bad_headers():
+            raise BadHeaderError
+
+        connection.send(self)
+
+    def add_recipient(self, recipient):
+        """
+        Adds another recipient to the message.
+        
+        :param recipient: email address of recipient.
+        """
+        
+        self.recipients.append(recipient)
+
+    def attach(self, 
+               filename=None, 
+               content_type=None, 
+               data=None,
+               disposition=None):
+        
+        """
+        Adds an attachment to the message.
+        
+        :param filename: filename of attachment
+        :param content_type: file mimetype
+        :param data: the raw file data
+        :param disposition: content-disposition (if any)
+        """
+
+        self.attachments.append(
+            Attachment(filename, content_type, data, disposition))
+
Add a comment to this file

flaskext/mail/connection.py

Empty file added.

Add a comment to this file

flaskext/mail/encoding.py

Empty file added.

Add a comment to this file

flaskext/mail/message.py

Empty file added.

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.