~jteh/bzr-email/pushPullEnhancements

« back to all changes in this revision

Viewing changes to emailer.py

  • Committer: James Teh
  • Date: 2011-06-08 07:08:58 UTC
  • mfrom: (40.2.9 trunk)
  • Revision ID: jamie@jantrid.net-20110608070858-mmmg2in7iobmzp28
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2005-2011 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
16
16
 
17
17
import errno
18
18
import subprocess
 
19
import tempfile
19
20
 
20
21
from bzrlib import (
21
22
    errors,
69
70
 
70
71
        outf.write('At %s\n\n' % self.url())
71
72
 
72
 
        lf = log.log_formatter('long',
 
73
        log_format = self.config.get_user_option('post_commit_log_format')
 
74
        lf = log.log_formatter(log_format or 'long',
73
75
                               show_ids=True,
74
76
                               to_file=outf
75
77
                               )
125
127
        # 8-bit strings. It is an error to write a Unicode string here.
126
128
        from cStringIO import StringIO
127
129
        diff_content = StringIO()
128
 
        show_diff_trees(tree_old, tree_new, diff_content)
 
130
        diff_options = self.config.get_user_option('post_commit_diffoptions')
 
131
        show_diff_trees(tree_old, tree_new, diff_content, None, diff_options)
129
132
        numlines = diff_content.getvalue().count('\n')+1
130
133
        if numlines <= difflimit:
131
134
            return diff_content.getvalue()
178
181
            result = self.config.username()
179
182
        return result
180
183
 
 
184
    def extra_headers(self):
 
185
        """Additional headers to include when sending."""
 
186
        result = {}
 
187
        headers = self.config.get_user_option('revision_mail_headers')
 
188
        if not headers:
 
189
            return
 
190
        if type(headers) is not list:
 
191
            headers = [headers]
 
192
        for line in headers:
 
193
            key, value = line.split(": ", 1)
 
194
            result[key] = value
 
195
        return result
 
196
 
181
197
    def send(self):
182
198
        """Send the email.
183
199
 
202
218
        """Spawn a 'mail' subprocess to send the email."""
203
219
        # TODO think up a good test for this, but I think it needs
204
220
        # a custom binary shipped with. RBC 20051021
 
221
        msgfile = tempfile.NamedTemporaryFile()
205
222
        try:
 
223
            msgfile.write(self.body().encode('utf8'))
 
224
            diff = self.get_diff()
 
225
            if diff:
 
226
                msgfile.write(diff)
 
227
            msgfile.flush()
 
228
            msgfile.seek(0)
 
229
 
206
230
            process = subprocess.Popen(self._command_line(),
207
 
                                       stdin=subprocess.PIPE)
208
 
            try:
209
 
                message = self.body().encode('utf8')
210
 
                diff = self.get_diff()
211
 
                if diff:
212
 
                    message += diff
213
 
                result = process.communicate(message)[0]
214
 
                if process.returncode is None:
215
 
                    process.wait()
216
 
                if process.returncode != 0:
217
 
                    raise errors.BzrError("Failed to send email")
218
 
                return result
219
 
            except OSError, e:
220
 
                if e.errno == errno.EPIPE:
221
 
                    raise errors.BzrError("Failed to send email.")
222
 
                else:
223
 
                    raise
224
 
        except ValueError:
225
 
            # bad subprocess parameters, should never happen.
226
 
            raise
227
 
        except OSError, e:
228
 
            if e.errno == errno.ENOENT:
229
 
                raise errors.BzrError("mail is not installed !?")
230
 
            else:
231
 
                raise
 
231
                stdin=msgfile.fileno())
 
232
 
 
233
            rc = process.wait()
 
234
            if rc != 0:
 
235
                raise errors.BzrError("Failed to send email: exit status %s" % (rc,))
 
236
        finally:
 
237
            msgfile.close()
232
238
 
233
239
    def _send_using_smtplib(self):
234
240
        """Use python's smtplib to send the email."""
244
250
        if diff:
245
251
            smtp.send_text_and_attachment_email(from_addr, to_addrs,
246
252
                                                subject, body, diff,
247
 
                                                self.diff_filename())
 
253
                                                self.diff_filename(),
 
254
                                                self.extra_headers())
248
255
        else:
249
 
            smtp.send_text_email(from_addr, to_addrs, subject, body)
 
256
            smtp.send_text_email(from_addr, to_addrs, subject, body,
 
257
                                 self.extra_headers())
250
258
 
251
259
    def should_send(self):
252
 
        result = self.config.get_user_option('post_commit_difflimit')
253
260
        post_commit_push_pull = self.config.get_user_option(
254
261
            'post_commit_push_pull') == 'True'
255
262
        if post_commit_push_pull and self.op == 'commit':