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

  • Committer: Robert Collins
  • Date: 2010-05-06 11:08:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506110810-h3j07fh5gmw54s25
Cleaner matcher matching revised unlocking protocol.

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