Mercurial > public > mercurial-scm > hg
annotate mercurial/mail.py @ 5909:f45f7390c1c5
strip: calculate list of extra nodes to save and pass it to changegroupsubset
When we remove revision N from the repository, all revisions >= N are
affected: either it's a descendant from N and will also be removed, or
it's not a descendant of N and will be renumbered.
As a consequence, we have to (at least temporarily) remove all filelog
and manifest revisions that have a linkrev >= N, readding some of them
later.
Unfortunately, it's possible to have a revlog with two revisions
r1 and r2 such that r1 < r2, but linkrev(r1) > linkrev(r2). If we try
to strip revision linkrev(r1) from the repository, we'll also lose
revision r2 when we truncate this revlog.
We already use changegroupsubset to create a temporary changegroup
containing the revisions that have to be restored, but that function is
unable to detect that we also wanted to save the r2 in the case above.
So we manually calculate these extra nodes and pass it to changegroupsubset.
This should fix issue764.
author | Alexis S. L. Carvalho <alexis@cecm.usp.br> |
---|---|
date | Sat, 19 Jan 2008 18:01:16 -0200 |
parents | dc6ed2736c81 |
children | 528c986f0162 |
rev | line source |
---|---|
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
1 # mail.py - mail sending bits for mercurial |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
2 # |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
3 # Copyright 2006 Matt Mackall <mpm@selenic.com> |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
4 # |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
6 # of the GNU General Public License, incorporated herein by reference. |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
7 |
3891 | 8 from i18n import _ |
4096 | 9 import os, smtplib, templater, util, socket |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
10 |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
11 def _smtp(ui): |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
12 '''send mail using smtp.''' |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
13 |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
14 local_hostname = ui.config('smtp', 'local_hostname') |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
15 s = smtplib.SMTP(local_hostname=local_hostname) |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
16 mailhost = ui.config('smtp', 'host') |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
17 if not mailhost: |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
18 raise util.Abort(_('no [smtp]host in hgrc - cannot send mail')) |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
19 mailport = int(ui.config('smtp', 'port', 25)) |
2964
26c8d37496c2
fix typo in mail.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2929
diff
changeset
|
20 ui.note(_('sending mail: smtp host %s, port %s\n') % |
26c8d37496c2
fix typo in mail.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2929
diff
changeset
|
21 (mailhost, mailport)) |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
22 s.connect(host=mailhost, port=mailport) |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
23 if ui.configbool('smtp', 'tls'): |
4093
669f99f78db0
mail.py: don't try to use TLS if python doesn't have SSL support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2964
diff
changeset
|
24 if not hasattr(socket, 'ssl'): |
669f99f78db0
mail.py: don't try to use TLS if python doesn't have SSL support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2964
diff
changeset
|
25 raise util.Abort(_("can't use TLS: Python SSL support " |
669f99f78db0
mail.py: don't try to use TLS if python doesn't have SSL support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2964
diff
changeset
|
26 "not installed")) |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
27 ui.note(_('(using tls)\n')) |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
28 s.ehlo() |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
29 s.starttls() |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
30 s.ehlo() |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
31 username = ui.config('smtp', 'username') |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
32 password = ui.config('smtp', 'password') |
5749
4fba4fee0718
Patchbomb: Prompt password when using SMTP/TLS and no password in .hgrc.
Arun Thomas <arun.thomas@gmail.com>
parents:
5472
diff
changeset
|
33 if username and not password: |
4fba4fee0718
Patchbomb: Prompt password when using SMTP/TLS and no password in .hgrc.
Arun Thomas <arun.thomas@gmail.com>
parents:
5472
diff
changeset
|
34 password = ui.getpass() |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
35 if username and password: |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
36 ui.note(_('(authenticating to mail server as %s)\n') % |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
37 (username)) |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
38 s.login(username, password) |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
39 return s |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
40 |
5866
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
41 def _sendmail(ui, sender, recipients, msg): |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
42 '''send mail using sendmail.''' |
5866
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
43 program = ui.config('email', 'method') |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
44 cmdline = '%s -f %s %s' % (program, templater.email(sender), |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
45 ' '.join(map(templater.email, recipients))) |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
46 ui.note(_('sending mail: %s\n') % cmdline) |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
47 fp = os.popen(cmdline, 'w') |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
48 fp.write(msg) |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
49 ret = fp.close() |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
50 if ret: |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
51 raise util.Abort('%s %s' % ( |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
52 os.path.basename(program.split(None, 1)[0]), |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
53 util.explain_exit(ret)[0])) |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
54 |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
55 def connect(ui): |
5866
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
56 '''make a mail connection. return a function to send mail. |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
57 call as sendmail(sender, list-of-recipients, msg).''' |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
58 |
5866
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
59 func = _sendmail |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
60 if ui.config('email', 'method', 'smtp') == 'smtp': |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
61 func = _smtp(ui) |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
62 |
5866
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
63 def send(ui, sender, recipients, msg): |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
64 try: |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
65 return func.sendmail(sender, recipients, msg) |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
66 except smtplib.SMTPRecipientsRefused, inst: |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
67 recipients = [r[1] for r in inst.recipients.values()] |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
68 raise util.Abort('\n' + '\n'.join(recipients)) |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
69 except smtplib.SMTPException, inst: |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
70 raise util.Abort(inst) |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
71 |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
72 return send |
2889
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
73 |
20b95aef3fe0
Move ui.sendmail to mail.connect/sendmail
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
74 def sendmail(ui, sender, recipients, msg): |
5472
23889160905a
Catch smtp exceptions
Christian Ebert <blacktrash@gmx.net>
parents:
4489
diff
changeset
|
75 try: |
5866
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
76 send = connect(ui) |
dc6ed2736c81
patchbomb: prompt only once for SMTP password
Matt Mackall <mpm@selenic.com>
parents:
5749
diff
changeset
|
77 return send(sender, recipients, msg) |
5472
23889160905a
Catch smtp exceptions
Christian Ebert <blacktrash@gmx.net>
parents:
4489
diff
changeset
|
78 except smtplib.SMTPRecipientsRefused, inst: |
23889160905a
Catch smtp exceptions
Christian Ebert <blacktrash@gmx.net>
parents:
4489
diff
changeset
|
79 recipients = [r[1] for r in inst.recipients.values()] |
23889160905a
Catch smtp exceptions
Christian Ebert <blacktrash@gmx.net>
parents:
4489
diff
changeset
|
80 raise util.Abort('\n' + '\n'.join(recipients)) |
23889160905a
Catch smtp exceptions
Christian Ebert <blacktrash@gmx.net>
parents:
4489
diff
changeset
|
81 except smtplib.SMTPException, inst: |
23889160905a
Catch smtp exceptions
Christian Ebert <blacktrash@gmx.net>
parents:
4489
diff
changeset
|
82 raise util.Abort(inst) |
4489
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
83 |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
84 def validateconfig(ui): |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
85 '''determine if we have enough config data to try sending email.''' |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
86 method = ui.config('email', 'method', 'smtp') |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
87 if method == 'smtp': |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
88 if not ui.config('smtp', 'host'): |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
89 raise util.Abort(_('smtp specified as email transport, ' |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
90 'but no smtp host configured')) |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
91 else: |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
92 if not util.find_exe(method): |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
93 raise util.Abort(_('%r specified as email transport, ' |
a11e13d50645
patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents:
4096
diff
changeset
|
94 'but not in PATH') % method) |