/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/smtp_connection.py

  • Committer: Jelmer Vernooij
  • Date: 2017-06-08 23:30:31 UTC
  • mto: This revision was merged to the branch mainline in revision 6690.
  • Revision ID: jelmer@jelmer.uk-20170608233031-3qavls2o7a1pqllj
Update imports.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""A convenience class around smtplib."""
18
18
 
19
 
from email.utils import getaddresses, parseaddr
 
19
from __future__ import absolute_import
20
20
 
 
21
from email import Utils
21
22
import errno
22
23
import smtplib
23
24
import socket
27
28
    osutils,
28
29
    )
29
30
from .errors import (
30
 
    BzrError,
31
 
    InternalBzrError,
 
31
    NoDestinationAddress,
 
32
    SMTPError,
 
33
    DefaultSMTPConnectionRefused,
 
34
    SMTPConnectionRefused,
32
35
    )
33
36
 
34
37
 
35
38
smtp_password = config.Option('smtp_password', default=None,
36
 
                              help='''\
 
39
        help='''\
37
40
Password to use for authentication to SMTP server.
38
41
''')
39
42
smtp_server = config.Option('smtp_server', default=None,
40
 
                            help='''\
 
43
        help='''\
41
44
Hostname of the SMTP server to use for sending email.
42
45
''')
43
46
smtp_username = config.Option('smtp_username', default=None,
44
 
                              help='''\
 
47
        help='''\
45
48
Username to use for authentication to SMTP server.
46
49
''')
47
50
 
48
51
 
49
 
class SMTPError(BzrError):
50
 
 
51
 
    _fmt = "SMTP error: %(error)s"
52
 
 
53
 
    def __init__(self, error):
54
 
        self.error = error
55
 
 
56
 
 
57
 
class SMTPConnectionRefused(SMTPError):
58
 
 
59
 
    _fmt = "SMTP connection to %(host)s refused"
60
 
 
61
 
    def __init__(self, error, host):
62
 
        self.error = error
63
 
        self.host = host
64
 
 
65
 
 
66
 
class DefaultSMTPConnectionRefused(SMTPConnectionRefused):
67
 
 
68
 
    _fmt = "Please specify smtp_server.  No server at default %(host)s."
69
 
 
70
 
 
71
 
class NoDestinationAddress(InternalBzrError):
72
 
 
73
 
    _fmt = "Message does not have a destination address."
74
 
 
75
 
 
76
52
class SMTPConnection(object):
77
53
    """Connect to an SMTP server and send an email.
78
54
 
105
81
 
106
82
        self._create_connection()
107
83
        # FIXME: _authenticate() should only be called when the server has
108
 
        # refused unauthenticated access, so it can safely try to authenticate
 
84
        # refused unauthenticated access, so it can safely try to authenticate 
109
85
        # with the default username. JRV20090407
110
86
        self._authenticate()
111
87
 
136
112
        if self._connection.has_extn("starttls"):
137
113
            code, resp = self._connection.starttls()
138
114
            if not (200 <= code <= 299):
139
 
                raise SMTPError("server refused STARTTLS: %d %s" %
140
 
                                (code, resp))
 
115
                raise SMTPError("server refused STARTTLS: %d %s" % (code, resp))
141
116
            # Say EHLO again, to check for newly revealed features
142
117
            code, resp = self._connection.ehlo()
143
118
            if not (200 <= code <= 299):
148
123
        auth = config.AuthenticationConfig()
149
124
        if self._smtp_username is None:
150
125
            # FIXME: Since _authenticate gets called even when no authentication
151
 
            # is necessary, it's not possible to use the default username
 
126
            # is necessary, it's not possible to use the default username 
152
127
            # here yet.
153
128
            self._smtp_username = auth.get_user('smtp', self._smtp_server)
154
129
            if self._smtp_username is None:
172
147
        """Get the origin and destination addresses of a message.
173
148
 
174
149
        :param message: A message object supporting get() to access its
175
 
            headers, like email.message.Message or
176
 
            breezy.email_message.EmailMessage.
 
150
            headers, like email.Message or breezy.email_message.EmailMessage.
177
151
        :return: A pair (from_email, to_emails), where from_email is the email
178
152
            address in the From header, and to_emails a list of all the
179
153
            addresses in the To, Cc, and Bcc headers.
180
154
        """
181
 
        from_email = parseaddr(message.get('From', None))[1]
 
155
        from_email = Utils.parseaddr(message.get('From', None))[1]
182
156
        to_full_addresses = []
183
157
        for header in ['To', 'Cc', 'Bcc']:
184
158
            value = message.get(header, None)
185
159
            if value:
186
160
                to_full_addresses.append(value)
187
 
        to_emails = [pair[1] for pair in
188
 
                     getaddresses(to_full_addresses)]
 
161
        to_emails = [ pair[1] for pair in
 
162
                Utils.getaddresses(to_full_addresses) ]
189
163
 
190
164
        return from_email, to_emails
191
165
 
195
169
        The message will be sent to all addresses in the To, Cc and Bcc
196
170
        headers.
197
171
 
198
 
        :param message: An email.message.Message or
199
 
            email.mime.multipart.MIMEMultipart object.
 
172
        :param message: An email.Message or email.MIMEMultipart object.
200
173
        :return: None
201
174
        """
202
175
        from_email, to_emails = self.get_message_addresses(message)
210
183
                                      message.as_string())
211
184
        except smtplib.SMTPRecipientsRefused as e:
212
185
            raise SMTPError('server refused recipient: %d %s' %
213
 
                            next(iter(e.recipients.values())))
 
186
                    next(iter(e.recipients.values())))
214
187
        except smtplib.SMTPResponseException as e:
215
188
            raise SMTPError('%d %s' % (e.smtp_code, e.smtp_error))
216
189
        except smtplib.SMTPException as e: