/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/email_message.py

  • Committer: Robert Collins
  • Date: 2010-05-06 11:08:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506110810-h3j07fh5gmw54s25
Cleaner matcher matching revised unlocking protocol.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""A convenience class around email.Message and email.MIMEMultipart."""
18
18
 
19
 
from __future__ import absolute_import
20
 
 
21
 
try:
22
 
    from email.message import Message
23
 
    from email.header import Header
24
 
    from email.mime.multipart import MIMEMultipart
25
 
    from email.mime.text import MIMEText
26
 
    from email.utils import formataddr, parseaddr
27
 
except ImportError:   # python < 3
28
 
    from email import (
29
 
        Header,
30
 
        Message,
31
 
        MIMEMultipart,
32
 
        MIMEText,
33
 
        )
34
 
    from email.Utils import formataddr, parseaddr
35
 
from . import __version__ as _breezy_version
36
 
from .osutils import safe_unicode
37
 
from .sixish import (
38
 
    text_type,
 
19
from email import (
 
20
    Header,
 
21
    Message,
 
22
    MIMEMultipart,
 
23
    MIMEText,
 
24
    Utils,
39
25
    )
40
 
from .smtp_connection import SMTPConnection
 
26
 
 
27
from bzrlib import __version__ as _bzrlib_version
 
28
from bzrlib.osutils import safe_unicode
 
29
from bzrlib.smtp_connection import SMTPConnection
41
30
 
42
31
 
43
32
class EmailMessage(object):
69
58
        self._body = body
70
59
        self._parts = []
71
60
 
72
 
        if isinstance(to_address, (bytes, text_type)):
 
61
        if isinstance(to_address, basestring):
73
62
            to_address = [ to_address ]
74
63
 
75
64
        to_addresses = []
79
68
 
80
69
        self._headers['To'] = ', '.join(to_addresses)
81
70
        self._headers['From'] = self.address_to_encoded_header(from_address)
82
 
        self._headers['Subject'] = Header(safe_unicode(subject))
83
 
        self._headers['User-Agent'] = 'Bazaar (%s)' % _breezy_version
 
71
        self._headers['Subject'] = Header.Header(safe_unicode(subject))
 
72
        self._headers['User-Agent'] = 'Bazaar (%s)' % _bzrlib_version
84
73
 
85
74
    def add_inline_attachment(self, body, filename=None, mime_subtype='plain'):
86
75
        """Add an inline attachment to the message.
111
100
            Used for tests.
112
101
        """
113
102
        if not self._parts:
114
 
            msgobj = Message()
 
103
            msgobj = Message.Message()
115
104
            if self._body is not None:
116
105
                body, encoding = self.string_with_encoding(self._body)
117
106
                msgobj.set_payload(body, encoding)
118
107
        else:
119
 
            msgobj = MIMEMultipart()
 
108
            msgobj = MIMEMultipart.MIMEMultipart()
120
109
 
121
110
            if boundary is not None:
122
111
                msgobj.set_boundary(boundary)
123
112
 
124
113
            for body, filename, mime_subtype in self._parts:
125
114
                body, encoding = self.string_with_encoding(body)
126
 
                payload = MIMEText(body, mime_subtype, encoding)
 
115
                payload = MIMEText.MIMEText(body, mime_subtype, encoding)
127
116
 
128
117
                if filename is not None:
129
118
                    content_type = payload['Content-Type']
158
147
 
159
148
    @staticmethod
160
149
    def send(config, from_address, to_address, subject, body, attachment=None,
161
 
             attachment_filename=None, attachment_mime_subtype='plain'):
 
150
            attachment_filename=None, attachment_mime_subtype='plain'):
162
151
        """Create an email message and send it with SMTPConnection.
163
152
 
164
153
        :param config: config object to pass to SMTPConnection constructor.
181
170
        """
182
171
        # Can't call Header over all the address, because that encodes both the
183
172
        # name and the email address, which is not permitted by RFCs.
184
 
        user, email = parseaddr(address)
 
173
        user, email = Utils.parseaddr(address)
185
174
        if not user:
186
175
            return email
187
176
        else:
188
 
            return formataddr((str(Header(safe_unicode(user))),
 
177
            return Utils.formataddr((str(Header.Header(safe_unicode(user))),
189
178
                email))
190
179
 
191
180
    @staticmethod
192
181
    def string_with_encoding(string_):
193
182
        """Return a str object together with an encoding.
194
183
 
195
 
        :param string\\_: A str or unicode object.
 
184
        :param string_: A str or unicode object.
196
185
        :return: A tuple (str, encoding), where encoding is one of 'ascii',
197
186
            'utf-8', or '8-bit', in that preferred order.
198
187
        """
201
190
        # avoid base64 when it's not necessary in order to be most compatible
202
191
        # with the capabilities of the receiving side, we check with encode()
203
192
        # and decode() whether the body is actually ascii-only.
204
 
        if isinstance(string_, text_type):
 
193
        if isinstance(string_, unicode):
205
194
            try:
206
195
                return (string_.encode('ascii'), 'ascii')
207
196
            except UnicodeEncodeError: