~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/mail_client.py

  • Committer: Alexander Belchenko
  • Date: 2008-03-02 16:54:19 UTC
  • mto: This revision was merged to the branch mainline in revision 3267.
  • Revision ID: bialix@ukr.net-20080302165419-2u0r0ogn1h7s4gib
because every mail client has different rules to compose command line we should encode arguments to 8 bit string only when needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
import sys
21
21
import tempfile
22
22
 
 
23
import bzrlib
23
24
from bzrlib import (
24
25
    email_message,
25
26
    errors,
144
145
            the attachment type.
145
146
        """
146
147
        for name in self._get_client_commands():
147
 
            cmdline = _get_compose_8bit_commandline(name, to, subject,
148
 
                attach_path)
 
148
            cmdline = [self._encode_path(name, 'executable')]
 
149
            cmdline.extend(self._get_compose_commandline(to, subject,
 
150
                                                         attach_path))
149
151
            try:
150
152
                subprocess.call(cmdline)
151
153
            except OSError, e:
166
168
        """
167
169
        raise NotImplementedError
168
170
 
169
 
    def _get_compose_8bit_commandline(self, name, to, subject, attach_path):
170
 
        """Wrapper around _get_compose_commandline()
171
 
        to ensure that resulting command line is plain string.
172
 
 
173
 
        :param  name:   name of external mail client (first argument).
174
 
        """
175
 
        cmdline = [name]
176
 
        user_encoding = osutils.get_user_encoding()
177
 
        if to:
178
 
            to = to.encode(user_encoding, 'replace')
179
 
        if subject:
180
 
            subject = subject.encode(user_encoding, 'replace')
181
 
        cmdline.extend(self._get_compose_commandline(to, subject,
182
 
                                                     attach_path))
183
 
        return cmdline
 
171
    def _encode_safe(self, u):
 
172
        """Encode possible unicode string argument to 8-bit string
 
173
        in user_encoding. Unencodable characters will be replaced
 
174
        with '?'.
 
175
 
 
176
        :param  u:  possible unicode string.
 
177
        :return:    encoded string if u is unicode, u itself otherwise.
 
178
        """
 
179
        if isinstance(u, unicode):
 
180
            return u.encode(bzrlib.user_encoding, 'replace')
 
181
        return u
 
182
 
 
183
    def _encode_path(self, path, kind):
 
184
        """Encode unicode path in user encoding.
 
185
 
 
186
        :param  path:   possible unicode path.
 
187
        :param  kind:   path kind ('executable' or 'attachment').
 
188
        :return:        encoded path if path is unicode,
 
189
                        path itself otherwise.
 
190
        :raise:         UnableEncodePath.
 
191
        """
 
192
        if isinstance(path, unicode):
 
193
            try:
 
194
                return path.encode(bzrlib.user_encoding)
 
195
            except UnicodeEncodeError:
 
196
                raise errors.UnableEncodePath(path, kind)
 
197
        return path
184
198
 
185
199
 
186
200
class Evolution(ExternalMailClient):
196
210
        if attach_path is not None:
197
211
            message_options['attach'] = attach_path
198
212
        options_list = ['%s=%s' % (k, urlutils.escape(v)) for (k, v) in
199
 
                        message_options.iteritems()]
200
 
        return ['mailto:%s?%s' % (to or '', '&'.join(options_list))]
 
213
                        sorted(message_options.iteritems())]
 
214
        return ['mailto:%s?%s' % (self._encode_safe(to or ''),
 
215
            '&'.join(options_list))]
201
216
 
202
217
 
203
218
class Mutt(ExternalMailClient):
209
224
        """See ExternalMailClient._get_compose_commandline"""
210
225
        message_options = []
211
226
        if subject is not None:
212
 
            message_options.extend(['-s', subject ])
 
227
            message_options.extend(['-s', self._encode_safe(subject)])
213
228
        if attach_path is not None:
214
 
            message_options.extend(['-a', attach_path])
 
229
            message_options.extend(['-a',
 
230
                self._encode_path(attach_path, 'attachment')])
215
231
        if to is not None:
216
 
            message_options.append(to)
 
232
            message_options.append(self._encode_safe(to))
217
233
        return message_options
218
234
 
219
235
 
234
250
        """See ExternalMailClient._get_compose_commandline"""
235
251
        message_options = {}
236
252
        if to is not None:
237
 
            message_options['to'] = to
 
253
            message_options['to'] = self._encode_safe(to)
238
254
        if subject is not None:
239
 
            message_options['subject'] = subject
 
255
            message_options['subject'] = self._encode_safe(subject)
240
256
        if attach_path is not None:
241
257
            message_options['attachment'] = urlutils.local_path_to_url(
242
258
                attach_path)
254
270
        """See ExternalMailClient._get_compose_commandline"""
255
271
        message_options = []
256
272
        if subject is not None:
257
 
            message_options.extend( ['-s', subject ] )
 
273
            message_options.extend(['-s', self._encode_safe(subject)])
258
274
        if attach_path is not None:
259
 
            message_options.extend( ['--attach', attach_path] )
 
275
            message_options.extend(['--attach',
 
276
                self._encode_path(attach_path, 'attachment')])
260
277
        if to is not None:
261
 
            message_options.extend( [ to ] )
262
 
 
 
278
            message_options.extend([self._encode_safe(to)])
263
279
        return message_options
264
280
 
265
281
 
272
288
        """See ExternalMailClient._get_compose_commandline"""
273
289
        if not to:
274
290
            raise errors.NoMailAddressSpecified()
275
 
        commandline = [to]
 
291
        commandline = [self._encode_safe(to)]
276
292
        if subject is not None:
277
 
            commandline.extend(['--subject', subject])
 
293
            commandline.extend(['--subject', self._encode_safe(subject)])
278
294
        if attach_path is not None:
279
 
            commandline.extend(['--attach', attach_path])
 
295
            commandline.extend(['--attach',
 
296
                self._encode_path(attach_path, 'attachment')])
280
297
        return commandline
281
298
 
282
299