/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 23:41:35 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506234135-yivbzczw1sejxnxc
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
expected to return an object which can be used to unlock them. This reduces
duplicate code when using cleanups. The previous 'tokens's returned by
``Branch.lock_write`` and ``Repository.lock_write`` are now attributes
on the result of the lock_write. ``repository.RepositoryWriteLockResult``
and ``branch.BranchWriteLockResult`` document this. (Robert Collins)

``log._get_info_for_log_files`` now takes an add_cleanup callable.
(Robert Collins)

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 .errors import BzrBadParameterNotUnicode
37
 
from .osutils import safe_unicode
38
 
from .sixish import (
39
 
    text_type,
 
19
from email import (
 
20
    Header,
 
21
    Message,
 
22
    MIMEMultipart,
 
23
    MIMEText,
 
24
    Utils,
40
25
    )
41
 
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
42
30
 
43
31
 
44
32
class EmailMessage(object):
70
58
        self._body = body
71
59
        self._parts = []
72
60
 
73
 
        if isinstance(to_address, (bytes, text_type)):
74
 
            to_address = [to_address]
 
61
        if isinstance(to_address, basestring):
 
62
            to_address = [ to_address ]
75
63
 
76
64
        to_addresses = []
77
65
 
80
68
 
81
69
        self._headers['To'] = ', '.join(to_addresses)
82
70
        self._headers['From'] = self.address_to_encoded_header(from_address)
83
 
        self._headers['Subject'] = Header(safe_unicode(subject))
84
 
        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
85
73
 
86
74
    def add_inline_attachment(self, body, filename=None, mime_subtype='plain'):
87
75
        """Add an inline attachment to the message.
112
100
            Used for tests.
113
101
        """
114
102
        if not self._parts:
115
 
            msgobj = Message()
 
103
            msgobj = Message.Message()
116
104
            if self._body is not None:
117
105
                body, encoding = self.string_with_encoding(self._body)
118
106
                msgobj.set_payload(body, encoding)
119
107
        else:
120
 
            msgobj = MIMEMultipart()
 
108
            msgobj = MIMEMultipart.MIMEMultipart()
121
109
 
122
110
            if boundary is not None:
123
111
                msgobj.set_boundary(boundary)
124
112
 
125
113
            for body, filename, mime_subtype in self._parts:
126
114
                body, encoding = self.string_with_encoding(body)
127
 
                payload = MIMEText(body, mime_subtype, encoding)
 
115
                payload = MIMEText.MIMEText(body, mime_subtype, encoding)
128
116
 
129
117
                if filename is not None:
130
118
                    content_type = payload['Content-Type']
159
147
 
160
148
    @staticmethod
161
149
    def send(config, from_address, to_address, subject, body, attachment=None,
162
 
             attachment_filename=None, attachment_mime_subtype='plain'):
 
150
            attachment_filename=None, attachment_mime_subtype='plain'):
163
151
        """Create an email message and send it with SMTPConnection.
164
152
 
165
153
        :param config: config object to pass to SMTPConnection constructor.
170
158
        msg = EmailMessage(from_address, to_address, subject, body)
171
159
        if attachment is not None:
172
160
            msg.add_inline_attachment(attachment, attachment_filename,
173
 
                                      attachment_mime_subtype)
 
161
                    attachment_mime_subtype)
174
162
        SMTPConnection(config).send_email(msg)
175
163
 
176
164
    @staticmethod
180
168
        :param address: An unicode string, or UTF-8 byte string.
181
169
        :return: A possibly RFC2047-encoded string.
182
170
        """
183
 
        if not isinstance(address, (str, text_type)):
184
 
            raise BzrBadParameterNotUnicode(address)
185
171
        # Can't call Header over all the address, because that encodes both the
186
172
        # name and the email address, which is not permitted by RFCs.
187
 
        user, email = parseaddr(address)
 
173
        user, email = Utils.parseaddr(address)
188
174
        if not user:
189
175
            return email
190
176
        else:
191
 
            return formataddr((str(Header(safe_unicode(user))),
192
 
                               email))
 
177
            return Utils.formataddr((str(Header.Header(safe_unicode(user))),
 
178
                email))
193
179
 
194
180
    @staticmethod
195
181
    def string_with_encoding(string_):
196
182
        """Return a str object together with an encoding.
197
183
 
198
 
        :param string\\_: A str or unicode object.
 
184
        :param string_: A str or unicode object.
199
185
        :return: A tuple (str, encoding), where encoding is one of 'ascii',
200
186
            'utf-8', or '8-bit', in that preferred order.
201
187
        """
204
190
        # avoid base64 when it's not necessary in order to be most compatible
205
191
        # with the capabilities of the receiving side, we check with encode()
206
192
        # and decode() whether the body is actually ascii-only.
207
 
        if isinstance(string_, text_type):
 
193
        if isinstance(string_, unicode):
208
194
            try:
209
195
                return (string_.encode('ascii'), 'ascii')
210
196
            except UnicodeEncodeError: