|
1 from mercurial.demandload import * |
|
2 from mercurial.i18n import gettext as _ |
|
3 from mercurial.node import * |
|
4 demandload(globals(), 'email.MIMEText mercurial:templater,util fnmatch socket') |
|
5 demandload(globals(), 'time') |
|
6 |
|
7 class notifier(object): |
|
8 def __init__(self, ui, repo): |
|
9 self.ui = ui |
|
10 self.ui.readconfig(self.ui.config('notify', 'config')) |
|
11 self.repo = repo |
|
12 self.stripcount = self.ui.config('notify', 'strip') |
|
13 self.root = self.strip(self.repo.root) |
|
14 |
|
15 def strip(self, path): |
|
16 path = util.pconvert(path) |
|
17 count = self.stripcount |
|
18 while path and count >= 0: |
|
19 c = path.find('/') |
|
20 if c == -1: |
|
21 break |
|
22 path = path[c+1:] |
|
23 count -= 1 |
|
24 return path |
|
25 |
|
26 def subscribers(self): |
|
27 subs = [] |
|
28 for user, pat in self.ui.configitems('usersubs'): |
|
29 if fnmatch.fnmatch(self.root, pat): |
|
30 subs.append(user) |
|
31 for pat, users in self.ui.configitems('reposubs'): |
|
32 if fnmatch.fnmatch(self.root, pat): |
|
33 subs.extend([u.strip() for u in users.split(',')]) |
|
34 subs.sort() |
|
35 return subs |
|
36 |
|
37 def seen(self, node): |
|
38 pass |
|
39 |
|
40 def url(self, path=None): |
|
41 return self.ui.config('web', 'baseurl') + (path or self.root) |
|
42 |
|
43 def message(self, node, changes): |
|
44 sio = templater.stringio() |
|
45 seen = self.seen(node) |
|
46 if seen: |
|
47 seen = self.strip(seen) |
|
48 sio.write('Changeset %s merged to %s\n' % |
|
49 (short(node), self.url())) |
|
50 sio.write('First seen in %s\n' % self.url(seen)) |
|
51 else: |
|
52 sio.write('Changeset %s new to %s\n' % (short(node), self.url())) |
|
53 sio.write('Committed by %s at %s\n' % |
|
54 (changes[1], templater.isodate(changes[2]))) |
|
55 sio.write('See %s?cmd=changeset;node=%s for full details\n' % |
|
56 (self.url(), short(node))) |
|
57 sio.write('\nDescription:\n') |
|
58 sio.write(templater.indent(changes[4], ' ')) |
|
59 msg = email.MIMEText.MIMEText(sio.getvalue(), 'plain') |
|
60 firstline = changes[4].lstrip().split('\n', 1)[0].rstrip() |
|
61 subject = '%s %s: %s' % (self.root, self.repo.rev(node), firstline) |
|
62 if seen: |
|
63 subject = '[merge] ' + subject |
|
64 if subject.endswith('.'): |
|
65 subject = subject[:-1] |
|
66 if len(subject) > 67: |
|
67 subject = subject[:64] + '...' |
|
68 msg['Subject'] = subject |
|
69 msg['X-Hg-Repo'] = self.root |
|
70 if '@' in changes[1]: |
|
71 msg['From'] = changes[1] |
|
72 else: |
|
73 msg['From'] = self.ui.config('email', 'from') |
|
74 msg['Message-Id'] = '<hg.%s.%s.%s@%s>' % (hex(node), |
|
75 int(time.time()), |
|
76 hash(self.repo.root), |
|
77 socket.getfqdn()) |
|
78 return msg |
|
79 |
|
80 def node(self, node): |
|
81 mail = self.ui.sendmail() |
|
82 changes = self.repo.changelog.read(node) |
|
83 fromaddr = self.ui.config('email', 'from', changes[1]) |
|
84 msg = self.message(node, changes) |
|
85 subs = self.subscribers() |
|
86 msg['To'] = ', '.join(subs) |
|
87 msgtext = msg.as_string(0) |
|
88 mail.sendmail(templater.email(fromaddr), |
|
89 [templater.email(s) for s in subs], |
|
90 msgtext) |
|
91 |
|
92 |
|
93 def hook(ui, repo, hooktype, node=None, **kwargs): |
|
94 n = notifier(ui, repo) |
|
95 n.node(bin(node)) |