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

  • Committer: Jelmer Vernooij
  • Date: 2018-07-19 22:31:57 UTC
  • mto: (7045.3.3 python3-r)
  • mto: This revision was merged to the branch mainline in revision 7051.
  • Revision ID: jelmer@jelmer.uk-20180719223157-tft7o7wqkfg1adpr
Fix some wsgi tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
from __future__ import absolute_import
 
18
 
17
19
import errno
18
20
import os
19
21
import subprocess
20
22
import sys
21
23
import tempfile
22
 
import urllib
23
24
 
24
 
import bzrlib
25
 
from bzrlib import (
 
25
import breezy
 
26
from . import (
 
27
    config as _mod_config,
26
28
    email_message,
27
29
    errors,
28
30
    msgeditor,
29
31
    osutils,
30
32
    urlutils,
31
 
    registry
 
33
    registry,
 
34
    )
 
35
from .sixish import (
 
36
    text_type,
32
37
    )
33
38
 
34
39
mail_client_registry = registry.Registry()
35
40
 
36
41
 
 
42
class MailClientNotFound(errors.BzrError):
 
43
 
 
44
    _fmt = "Unable to find mail client with the following names:"\
 
45
        " %(mail_command_list_string)s"
 
46
 
 
47
    def __init__(self, mail_command_list):
 
48
        mail_command_list_string = ', '.join(mail_command_list)
 
49
        errors.BzrError.__init__(
 
50
            self, mail_command_list=mail_command_list,
 
51
            mail_command_list_string=mail_command_list_string)
 
52
 
 
53
 
 
54
class NoMessageSupplied(errors.BzrError):
 
55
 
 
56
    _fmt = "No message supplied."
 
57
 
 
58
 
 
59
class NoMailAddressSpecified(errors.BzrError):
 
60
 
 
61
    _fmt = "No mail-to address (--mail-to) or output (-o) specified."
 
62
 
 
63
 
37
64
class MailClient(object):
38
65
    """A mail client that can send messages with attachements."""
39
66
 
105
132
                extension, basename=None, body=None):
106
133
        """See MailClient.compose"""
107
134
        if not to:
108
 
            raise errors.NoMailAddressSpecified()
 
135
            raise NoMailAddressSpecified()
109
136
        body = msgeditor.edit_commit_message(prompt, start_message=body)
110
137
        if body == '':
111
 
            raise errors.NoMessageSupplied()
 
138
            raise NoMessageSupplied()
112
139
        email_message.EmailMessage.send(self.config,
113
 
                                        self.config.username(),
 
140
                                        self.config.get('email'),
114
141
                                        to,
115
142
                                        subject,
116
143
                                        body,
182
209
                                                         **kwargs))
183
210
            try:
184
211
                subprocess.call(cmdline)
185
 
            except OSError, e:
 
212
            except OSError as e:
186
213
                if e.errno != errno.ENOENT:
187
214
                    raise
188
215
            else:
189
216
                break
190
217
        else:
191
 
            raise errors.MailClientNotFound(self._client_commands)
 
218
            raise MailClientNotFound(self._client_commands)
192
219
 
193
220
    def _get_compose_commandline(self, to, subject, attach_path, body):
194
221
        """Determine the commandline to use for composing a message
208
235
        :param  u:  possible unicode string.
209
236
        :return:    encoded string if u is unicode, u itself otherwise.
210
237
        """
211
 
        if isinstance(u, unicode):
 
238
        if isinstance(u, text_type):
212
239
            return u.encode(osutils.get_user_encoding(), 'replace')
213
240
        return u
214
241
 
221
248
                        path itself otherwise.
222
249
        :raise:         UnableEncodePath.
223
250
        """
224
 
        if isinstance(path, unicode):
 
251
        if isinstance(path, text_type):
225
252
            try:
226
253
                return path.encode(osutils.get_user_encoding())
227
254
            except UnicodeEncodeError:
250
277
        if body is not None:
251
278
            message_options['body'] = body
252
279
        options_list = ['%s=%s' % (k, urlutils.escape(v)) for (k, v) in
253
 
                        sorted(message_options.iteritems())]
 
280
                        sorted(message_options.items())]
254
281
        return ['mailto:%s?%s' % (self._encode_safe(to or ''),
255
282
            '&'.join(options_list))]
256
283
mail_client_registry.register('evolution', Evolution,
310
337
            message_options['attachment'] = urlutils.local_path_to_url(
311
338
                attach_path)
312
339
        if body is not None:
313
 
            options_list = ['body=%s' % urllib.quote(self._encode_safe(body))]
 
340
            options_list = ['body=%s' % urlutils.quote(self._encode_safe(body))]
314
341
        else:
315
342
            options_list = []
316
343
        options_list.extend(["%s='%s'" % (k, v) for k, v in
317
 
                        sorted(message_options.iteritems())])
 
344
                        sorted(message_options.items())])
318
345
        return ['-compose', ','.join(options_list)]
319
346
mail_client_registry.register('thunderbird', Thunderbird,
320
347
                              help=Thunderbird.__doc__)
352
379
        """See ExternalMailClient._get_compose_commandline"""
353
380
        compose_url = []
354
381
        if from_ is not None:
355
 
            compose_url.append('from=' + urllib.quote(from_))
 
382
            compose_url.append('from=' + urlutils.quote(from_))
356
383
        if subject is not None:
357
 
            # Don't use urllib.quote_plus because Claws doesn't seem
 
384
            # Don't use urlutils.quote_plus because Claws doesn't seem
358
385
            # to recognise spaces encoded as "+".
359
386
            compose_url.append(
360
 
                'subject=' + urllib.quote(self._encode_safe(subject)))
 
387
                'subject=' + urlutils.quote(self._encode_safe(subject)))
361
388
        if body is not None:
362
389
            compose_url.append(
363
 
                'body=' + urllib.quote(self._encode_safe(body)))
 
390
                'body=' + urlutils.quote(self._encode_safe(body)))
364
391
        # to must be supplied for the claws-mail --compose syntax to work.
365
392
        if to is None:
366
 
            raise errors.NoMailAddressSpecified()
 
393
            raise NoMailAddressSpecified()
367
394
        compose_url = 'mailto:%s?%s' % (
368
395
            self._encode_safe(to), '&'.join(compose_url))
369
396
        # Collect command-line options.
377
404
                 extension, body=None, from_=None):
378
405
        """See ExternalMailClient._compose"""
379
406
        if from_ is None:
380
 
            from_ = self.config.get_user_option('email')
 
407
            from_ = self.config.get('email')
381
408
        super(Claws, self)._compose(prompt, to, subject, attach_path,
382
409
                                    mime_subtype, extension, body, from_)
383
410
 
394
421
    def _get_compose_commandline(self, to, subject, attach_path, body=None):
395
422
        """See ExternalMailClient._get_compose_commandline"""
396
423
        if not to:
397
 
            raise errors.NoMailAddressSpecified()
 
424
            raise NoMailAddressSpecified()
398
425
        commandline = [self._encode_safe(to)]
399
426
        if subject is not None:
400
427
            commandline.extend(['--subject', self._encode_safe(subject)])
527
554
 
528
555
        This implementation uses MAPI via the simplemapi ctypes wrapper
529
556
        """
530
 
        from bzrlib.util import simplemapi
 
557
        from .util import simplemapi
531
558
        try:
532
559
            simplemapi.SendMail(to or '', subject or '', body or '',
533
560
                                attach_path)
534
 
        except simplemapi.MAPIError, e:
 
561
        except simplemapi.MAPIError as e:
535
562
            if e.code != simplemapi.MAPI_USER_ABORT:
536
 
                raise errors.MailClientNotFound(['MAPI supported mail client'
 
563
                raise MailClientNotFound(['MAPI supported mail client'
537
564
                                                 ' (error %d)' % (e.code,)])
538
565
mail_client_registry.register('mapi', MAPIClient,
539
566
                              help=MAPIClient.__doc__)
616
643
        """See MailClient.compose"""
617
644
        try:
618
645
            return self._mail_client().compose(prompt, to, subject,
619
 
                                               attachment, mimie_subtype,
 
646
                                               attachment, mime_subtype,
620
647
                                               extension, basename, body)
621
 
        except errors.MailClientNotFound:
 
648
        except MailClientNotFound:
622
649
            return Editor(self.config).compose(prompt, to, subject,
623
 
                          attachment, mimie_subtype, extension, body)
 
650
                          attachment, mime_subtype, extension, body)
624
651
 
625
652
    def compose_merge_request(self, to, subject, directive, basename=None,
626
653
                              body=None):
628
655
        try:
629
656
            return self._mail_client().compose_merge_request(to, subject,
630
657
                    directive, basename=basename, body=body)
631
 
        except errors.MailClientNotFound:
 
658
        except MailClientNotFound:
632
659
            return Editor(self.config).compose_merge_request(to, subject,
633
660
                          directive, basename=basename, body=body)
634
 
mail_client_registry.register('default', DefaultMail,
 
661
mail_client_registry.register(u'default', DefaultMail,
635
662
                              help=DefaultMail.__doc__)
636
 
mail_client_registry.default_key = 'default'
637
 
 
638
 
 
 
663
mail_client_registry.default_key = u'default'
 
664
 
 
665
opt_mail_client = _mod_config.RegistryOption('mail_client',
 
666
        mail_client_registry, help='E-mail client to use.', invalid='error')