66 # push changes to, they can manage their own subscriptions. |
66 # push changes to, they can manage their own subscriptions. |
67 |
67 |
68 from mercurial.demandload import * |
68 from mercurial.demandload import * |
69 from mercurial.i18n import gettext as _ |
69 from mercurial.i18n import gettext as _ |
70 from mercurial.node import * |
70 from mercurial.node import * |
71 demandload(globals(), 'mercurial:commands,patch,cmdutil,templater,util,mail') |
71 demandload(globals(), 'mercurial:patch,cmdutil,templater,util,mail') |
72 demandload(globals(), 'email.Parser fnmatch socket time') |
72 demandload(globals(), 'email.Parser fnmatch socket time') |
73 |
73 |
74 # template for single changeset can include email headers. |
74 # template for single changeset can include email headers. |
75 single_template = ''' |
75 single_template = ''' |
76 Subject: changeset in {webroot}: {desc|firstline|strip} |
76 Subject: changeset in {webroot}: {desc|firstline|strip} |
105 self.ui.readsections(cfg, 'usersubs', 'reposubs') |
105 self.ui.readsections(cfg, 'usersubs', 'reposubs') |
106 self.repo = repo |
106 self.repo = repo |
107 self.stripcount = int(self.ui.config('notify', 'strip', 0)) |
107 self.stripcount = int(self.ui.config('notify', 'strip', 0)) |
108 self.root = self.strip(self.repo.root) |
108 self.root = self.strip(self.repo.root) |
109 self.domain = self.ui.config('notify', 'domain') |
109 self.domain = self.ui.config('notify', 'domain') |
110 self.sio = cmdutil.stringio() |
|
111 self.subs = self.subscribers() |
110 self.subs = self.subscribers() |
112 |
111 |
113 mapfile = self.ui.config('notify', 'style') |
112 mapfile = self.ui.config('notify', 'style') |
114 template = (self.ui.config('notify', hooktype) or |
113 template = (self.ui.config('notify', hooktype) or |
115 self.ui.config('notify', 'template')) |
114 self.ui.config('notify', 'template')) |
116 self.t = cmdutil.changeset_templater(self.ui, self.repo, mapfile, |
115 self.t = cmdutil.changeset_templater(self.ui, self.repo, |
117 self.sio) |
116 False, None, mapfile, False) |
118 if not mapfile and not template: |
117 if not mapfile and not template: |
119 template = deftemplates.get(hooktype) or single_template |
118 template = deftemplates.get(hooktype) or single_template |
120 if template: |
119 if template: |
121 template = templater.parsestring(template, quoted=False) |
120 template = templater.parsestring(template, quoted=False) |
122 self.t.use_template(template) |
121 self.t.use_template(template) |
175 def skipsource(self, source): |
174 def skipsource(self, source): |
176 '''true if incoming changes from this source should be skipped.''' |
175 '''true if incoming changes from this source should be skipped.''' |
177 ok_sources = self.ui.config('notify', 'sources', 'serve').split() |
176 ok_sources = self.ui.config('notify', 'sources', 'serve').split() |
178 return source not in ok_sources |
177 return source not in ok_sources |
179 |
178 |
180 def send(self, node, count): |
179 def send(self, node, count, data): |
181 '''send message.''' |
180 '''send message.''' |
182 |
181 |
183 p = email.Parser.Parser() |
182 p = email.Parser.Parser() |
184 self.sio.seek(0) |
183 msg = p.parsestr(data) |
185 msg = p.parse(self.sio) |
|
186 |
184 |
187 def fix_subject(): |
185 def fix_subject(): |
188 '''try to make subject line exist and be useful.''' |
186 '''try to make subject line exist and be useful.''' |
189 |
187 |
190 subject = msg['Subject'] |
188 subject = msg['Subject'] |
235 |
233 |
236 def diff(self, node, ref): |
234 def diff(self, node, ref): |
237 maxdiff = int(self.ui.config('notify', 'maxdiff', 300)) |
235 maxdiff = int(self.ui.config('notify', 'maxdiff', 300)) |
238 if maxdiff == 0: |
236 if maxdiff == 0: |
239 return |
237 return |
240 fp = cmdutil.stringio() |
|
241 prev = self.repo.changelog.parents(node)[0] |
238 prev = self.repo.changelog.parents(node)[0] |
242 patch.diff(self.repo, prev, ref, fp=fp) |
239 self.ui.pushbuffer() |
243 difflines = fp.getvalue().splitlines(1) |
240 patch.diff(self.repo, prev, ref) |
|
241 difflines = self.ui.popbuffer().splitlines(1) |
244 if self.ui.configbool('notify', 'diffstat', True): |
242 if self.ui.configbool('notify', 'diffstat', True): |
245 s = patch.diffstat(difflines) |
243 s = patch.diffstat(difflines) |
246 self.sio.write('\ndiffstat:\n\n' + s) |
244 self.ui.write('\ndiffstat:\n\n' + s) |
247 if maxdiff > 0 and len(difflines) > maxdiff: |
245 if maxdiff > 0 and len(difflines) > maxdiff: |
248 self.sio.write(_('\ndiffs (truncated from %d to %d lines):\n\n') % |
246 self.ui.write(_('\ndiffs (truncated from %d to %d lines):\n\n') % |
249 (len(difflines), maxdiff)) |
247 (len(difflines), maxdiff)) |
250 difflines = difflines[:maxdiff] |
248 difflines = difflines[:maxdiff] |
251 elif difflines: |
249 elif difflines: |
252 self.sio.write(_('\ndiffs (%d lines):\n\n') % len(difflines)) |
250 self.ui.write(_('\ndiffs (%d lines):\n\n') % len(difflines)) |
253 self.sio.write(*difflines) |
251 self.ui.write(*difflines) |
254 |
252 |
255 def hook(ui, repo, hooktype, node=None, source=None, **kwargs): |
253 def hook(ui, repo, hooktype, node=None, source=None, **kwargs): |
256 '''send email notifications to interested subscribers. |
254 '''send email notifications to interested subscribers. |
257 |
255 |
258 if used as changegroup hook, send one email for all changesets in |
256 if used as changegroup hook, send one email for all changesets in |
264 if n.skipsource(source): |
262 if n.skipsource(source): |
265 ui.debug(_('notify: changes have source "%s" - skipping\n') % |
263 ui.debug(_('notify: changes have source "%s" - skipping\n') % |
266 source) |
264 source) |
267 return |
265 return |
268 node = bin(node) |
266 node = bin(node) |
|
267 ui.pushbuffer() |
269 if hooktype == 'changegroup': |
268 if hooktype == 'changegroup': |
270 start = repo.changelog.rev(node) |
269 start = repo.changelog.rev(node) |
271 end = repo.changelog.count() |
270 end = repo.changelog.count() |
272 count = end - start |
271 count = end - start |
273 for rev in xrange(start, end): |
272 for rev in xrange(start, end): |