~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/mail_client.py

Add KMail mail client

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
import errno
18
18
import os
19
19
import subprocess
 
20
import sys
20
21
import tempfile
21
22
 
22
23
from bzrlib import (
23
24
    email_message,
24
25
    errors,
25
26
    msgeditor,
 
27
    osutils,
26
28
    urlutils,
27
29
    )
28
30
 
68
70
                                        attachment_mime_subtype=mime_subtype)
69
71
 
70
72
 
71
 
class Evolution(MailClient):
72
 
    """Evolution mail client."""
 
73
class ExternalMailClient(MailClient):
 
74
    """An external mail client."""
73
75
 
74
 
    _client_commands = ['evolution']
 
76
    def _get_client_commands(self):
 
77
        if sys.platform == 'win32':
 
78
            import win32utils
 
79
            return [win32utils.get_app_path(i) for i in self._client_commands]
 
80
        else:
 
81
            return self._client_commands
75
82
 
76
83
    def compose(self, prompt, to, subject, attachment, mime_subtype,
77
84
                extension):
80
87
            os.write(fd, attachment)
81
88
        finally:
82
89
            os.close(fd)
83
 
        for name in self._client_commands:
 
90
        self._compose(prompt, to, subject, pathname, mime_subtype, extension)
 
91
 
 
92
    def _compose(self, prompt, to, subject, attach_path, mime_subtype,
 
93
                extension):
 
94
        for name in self._get_client_commands():
84
95
            cmdline = [name]
85
96
            cmdline.extend(self._get_compose_commandline(to, subject,
86
 
                                                         pathname))
 
97
                                                         attach_path))
87
98
            try:
88
99
                subprocess.call(cmdline)
89
100
            except OSError, e:
95
106
            raise errors.MailClientNotFound(self._client_commands)
96
107
 
97
108
    def _get_compose_commandline(self, to, subject, attach_path):
 
109
        raise NotImplementedError
 
110
 
 
111
 
 
112
class Evolution(ExternalMailClient):
 
113
    """Evolution mail client."""
 
114
 
 
115
    _client_commands = ['evolution']
 
116
 
 
117
    def _get_compose_commandline(self, to, subject, attach_path):
98
118
        message_options = {}
99
119
        if subject is not None:
100
120
            message_options['subject'] = subject
105
125
        return ['mailto:%s?%s' % (to or '', '&'.join(options_list))]
106
126
 
107
127
 
108
 
class Thunderbird(Evolution):
 
128
class Thunderbird(ExternalMailClient):
109
129
    """Mozilla Thunderbird (or Icedove)
110
130
 
111
131
    Note that Thunderbird 1.5 is buggy and does not support setting
131
151
        return ['-compose', ','.join(options_list)]
132
152
 
133
153
 
134
 
class KMail(Evolution):
 
154
class KMail(ExternalMailClient):
135
155
    """KDE mail client."""
136
156
 
137
157
    _client_commands = ['kmail']
148
168
        return message_options
149
169
 
150
170
 
151
 
class XDGEmail(Evolution):
 
171
class XDGEmail(ExternalMailClient):
152
172
    """xdg-email attempts to invoke the user's preferred mail client"""
153
173
 
154
174
    _client_commands = ['xdg-email']
162
182
        return commandline
163
183
 
164
184
 
 
185
class MAPIClient(ExternalMailClient):
 
186
    """Default Windows mail client launched using MAPI."""
 
187
 
 
188
    def _compose(self, prompt, to, subject, attach_path, mime_subtype,
 
189
                 extension):
 
190
        from bzrlib.util import simplemapi
 
191
        try:
 
192
            simplemapi.SendMail(to or '', subject or '', '', attach_path)
 
193
        except simplemapi.MAPIError, e:
 
194
            if e.code != simplemapi.MAPI_USER_ABORT:
 
195
                raise errors.MailClientNotFound(['MAPI supported mail client'
 
196
                                                 ' (error %d)' % (e.code,)])
 
197
 
 
198
 
165
199
class DefaultMail(MailClient):
166
 
    """Default mail handling.  Tries XDGEmail, falls back to Editor"""
 
200
    """Default mail handling.  Tries XDGEmail (or MAPIClient on Windows),
 
201
    falls back to Editor"""
 
202
 
 
203
    def _mail_client(self):
 
204
        if osutils.supports_mapi():
 
205
            return MAPIClient(self.config)
 
206
        else:
 
207
            return XDGEmail(self.config)
167
208
 
168
209
    def compose(self, prompt, to, subject, attachment, mime_subtype,
169
210
                extension):
170
211
        try:
171
 
            return XDGEmail(self.config).compose(prompt, to, subject,
172
 
                            attachment, mimie_subtype, extension)
 
212
            return self._mail_client().compose(prompt, to, subject,
 
213
                                               attachment, mimie_subtype,
 
214
                                               extension)
173
215
        except errors.MailClientNotFound:
174
216
            return Editor(self.config).compose(prompt, to, subject,
175
217
                          attachment, mimie_subtype, extension)
176
218
 
177
219
    def compose_merge_request(self, to, subject, directive):
178
220
        try:
179
 
            return XDGEmail(self.config).compose_merge_request(to, subject,
180
 
                            directive)
 
221
            return self._mail_client().compose_merge_request(to, subject,
 
222
                                                             directive)
181
223
        except errors.MailClientNotFound:
182
224
            return Editor(self.config).compose_merge_request(to, subject,
183
225
                          directive)