/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 breezy/email_message.py

  • Committer: Jelmer Vernooij
  • Date: 2020-04-05 19:11:34 UTC
  • mto: (7490.7.16 work)
  • mto: This revision was merged to the branch mainline in revision 7501.
  • Revision ID: jelmer@jelmer.uk-20200405191134-0aebh8ikiwygxma5
Populate the .gitignore file.

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