~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/mail_client.py

  • Committer: John Arbash Meinel
  • Date: 2010-01-13 16:23:07 UTC
  • mto: (4634.119.7 2.0)
  • mto: This revision was merged to the branch mainline in revision 4959.
  • Revision ID: john@arbash-meinel.com-20100113162307-0bs82td16gzih827
Update the MANIFEST.in file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 Canonical Ltd
 
1
# Copyright (C) 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
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
24
import bzrlib
26
25
from bzrlib import (
90
89
 
91
90
 
92
91
class Editor(MailClient):
93
 
    __doc__ = """DIY mail client that uses commit message editor"""
 
92
    """DIY mail client that uses commit message editor"""
94
93
 
95
94
    supports_body = True
96
95
 
231
230
 
232
231
 
233
232
class ExternalMailClient(BodyExternalMailClient):
234
 
    __doc__ = """An external mail client."""
 
233
    """An external mail client."""
235
234
 
236
235
    supports_body = False
237
236
 
238
237
 
239
238
class Evolution(BodyExternalMailClient):
240
 
    __doc__ = """Evolution mail client."""
 
239
    """Evolution mail client."""
241
240
 
242
241
    _client_commands = ['evolution']
243
242
 
259
258
 
260
259
 
261
260
class Mutt(BodyExternalMailClient):
262
 
    __doc__ = """Mutt mail client."""
 
261
    """Mutt mail client."""
263
262
 
264
263
    _client_commands = ['mutt']
265
264
 
287
286
 
288
287
 
289
288
class Thunderbird(BodyExternalMailClient):
290
 
    __doc__ = """Mozilla Thunderbird (or Icedove)
 
289
    """Mozilla Thunderbird (or Icedove)
291
290
 
292
291
    Note that Thunderbird 1.5 is buggy and does not support setting
293
292
    "to" simultaneously with including a attachment.
311
310
            message_options['attachment'] = urlutils.local_path_to_url(
312
311
                attach_path)
313
312
        if body is not None:
314
 
            options_list = ['body=%s' % urlutils.quote(self._encode_safe(body))]
 
313
            options_list = ['body=%s' % urllib.quote(self._encode_safe(body))]
315
314
        else:
316
315
            options_list = []
317
316
        options_list.extend(["%s='%s'" % (k, v) for k, v in
322
321
 
323
322
 
324
323
class KMail(ExternalMailClient):
325
 
    __doc__ = """KDE mail client."""
 
324
    """KDE mail client."""
326
325
 
327
326
    _client_commands = ['kmail']
328
327
 
342
341
 
343
342
 
344
343
class Claws(ExternalMailClient):
345
 
    __doc__ = """Claws mail client."""
 
344
    """Claws mail client."""
346
345
 
347
346
    supports_body = True
348
347
 
353
352
        """See ExternalMailClient._get_compose_commandline"""
354
353
        compose_url = []
355
354
        if from_ is not None:
356
 
            compose_url.append('from=' + urlutils.quote(from_))
 
355
            compose_url.append('from=' + urllib.quote(from_))
357
356
        if subject is not None:
358
 
            # Don't use urlutils.quote_plus because Claws doesn't seem
 
357
            # Don't use urllib.quote_plus because Claws doesn't seem
359
358
            # to recognise spaces encoded as "+".
360
359
            compose_url.append(
361
 
                'subject=' + urlutils.quote(self._encode_safe(subject)))
 
360
                'subject=' + urllib.quote(self._encode_safe(subject)))
362
361
        if body is not None:
363
362
            compose_url.append(
364
 
                'body=' + urlutils.quote(self._encode_safe(body)))
 
363
                'body=' + urllib.quote(self._encode_safe(body)))
365
364
        # to must be supplied for the claws-mail --compose syntax to work.
366
365
        if to is None:
367
366
            raise errors.NoMailAddressSpecified()
388
387
 
389
388
 
390
389
class XDGEmail(BodyExternalMailClient):
391
 
    __doc__ = """xdg-email attempts to invoke the user's preferred mail client"""
 
390
    """xdg-email attempts to invoke the user's preferred mail client"""
392
391
 
393
392
    _client_commands = ['xdg-email']
394
393
 
410
409
 
411
410
 
412
411
class EmacsMail(ExternalMailClient):
413
 
    __doc__ = """Call emacsclient to have a mail buffer.
 
412
    """Call emacsclient to have a mail buffer.
414
413
 
415
414
    This only work for emacs >= 22.1 due to recent -e/--eval support.
416
415
 
425
424
 
426
425
    _client_commands = ['emacsclient']
427
426
 
428
 
    def __init__(self, config):
429
 
        super(EmacsMail, self).__init__(config)
430
 
        self.elisp_tmp_file = None
431
 
 
432
427
    def _prepare_send_function(self):
433
428
        """Write our wrapper function into a temporary file.
434
429
 
505
500
        if attach_path is not None:
506
501
            # Do not create a file if there is no attachment
507
502
            elisp = self._prepare_send_function()
508
 
            self.elisp_tmp_file = elisp
509
503
            lmmform = '(load "%s")' % elisp
510
504
            mmform  = '(bzr-add-mime-att "%s")' % \
511
505
                self._encode_path(attach_path, 'attachment')
520
514
 
521
515
 
522
516
class MAPIClient(BodyExternalMailClient):
523
 
    __doc__ = """Default Windows mail client launched using MAPI."""
 
517
    """Default Windows mail client launched using MAPI."""
524
518
 
525
519
    def _compose(self, prompt, to, subject, attach_path, mime_subtype,
526
520
                 extension, body=None):
540
534
                              help=MAPIClient.__doc__)
541
535
 
542
536
 
543
 
class MailApp(BodyExternalMailClient):
544
 
    __doc__ = """Use MacOS X's Mail.app for sending email messages.
545
 
 
546
 
    Although it would be nice to use appscript, it's not installed
547
 
    with the shipped Python installations.  We instead build an
548
 
    AppleScript and invoke the script using osascript(1).  We don't
549
 
    use the _encode_safe() routines as it's not clear what encoding
550
 
    osascript expects the script to be in.
551
 
    """
552
 
 
553
 
    _client_commands = ['osascript']
554
 
 
555
 
    def _get_compose_commandline(self, to, subject, attach_path, body=None,
556
 
                                from_=None):
557
 
       """See ExternalMailClient._get_compose_commandline"""
558
 
 
559
 
       fd, self.temp_file = tempfile.mkstemp(prefix="bzr-send-",
560
 
                                         suffix=".scpt")
561
 
       try:
562
 
           os.write(fd, 'tell application "Mail"\n')
563
 
           os.write(fd, 'set newMessage to make new outgoing message\n')
564
 
           os.write(fd, 'tell newMessage\n')
565
 
           if to is not None:
566
 
               os.write(fd, 'make new to recipient with properties'
567
 
                   ' {address:"%s"}\n' % to)
568
 
           if from_ is not None:
569
 
               # though from_ doesn't actually seem to be used
570
 
               os.write(fd, 'set sender to "%s"\n'
571
 
                   % sender.replace('"', '\\"'))
572
 
           if subject is not None:
573
 
               os.write(fd, 'set subject to "%s"\n'
574
 
                   % subject.replace('"', '\\"'))
575
 
           if body is not None:
576
 
               # FIXME: would be nice to prepend the body to the
577
 
               # existing content (e.g., preserve signature), but
578
 
               # can't seem to figure out the right applescript
579
 
               # incantation.
580
 
               os.write(fd, 'set content to "%s\\n\n"\n' %
581
 
                   body.replace('"', '\\"').replace('\n', '\\n'))
582
 
 
583
 
           if attach_path is not None:
584
 
               # FIXME: would be nice to first append a newline to
585
 
               # ensure the attachment is on a new paragraph, but
586
 
               # can't seem to figure out the right applescript
587
 
               # incantation.
588
 
               os.write(fd, 'tell content to make new attachment'
589
 
                   ' with properties {file name:"%s"}'
590
 
                   ' at after the last paragraph\n'
591
 
                   % self._encode_path(attach_path, 'attachment'))
592
 
           os.write(fd, 'set visible to true\n')
593
 
           os.write(fd, 'end tell\n')
594
 
           os.write(fd, 'end tell\n')
595
 
       finally:
596
 
           os.close(fd) # Just close the handle but do not remove the file.
597
 
       return [self.temp_file]
598
 
mail_client_registry.register('mail.app', MailApp,
599
 
                              help=MailApp.__doc__)
600
 
 
601
 
 
602
537
class DefaultMail(MailClient):
603
 
    __doc__ = """Default mail handling.  Tries XDGEmail (or MAPIClient on Windows),
 
538
    """Default mail handling.  Tries XDGEmail (or MAPIClient on Windows),
604
539
    falls back to Editor"""
605
540
 
606
541
    supports_body = True
635
570
mail_client_registry.register('default', DefaultMail,
636
571
                              help=DefaultMail.__doc__)
637
572
mail_client_registry.default_key = 'default'
638
 
 
639