/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: Gustav Hartvigsson
  • Date: 2021-01-09 21:36:27 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20210109213627-h1xwcutzy9m7a99b
Added 'Case Preserving Working Tree Use Cases' from Canonical Wiki

* Addod a page from the Canonical Bazaar wiki
  with information on the scmeatics of case
  perserving filesystems an a case insensitive
  filesystem works.
  
  * Needs re-work, but this will do as it is the
    same inforamoton as what was on the linked
    page in the currint documentation.

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