162 for s in subs] |
161 for s in subs] |
163 |
162 |
164 def url(self, path=None): |
163 def url(self, path=None): |
165 return self.ui.config('web', 'baseurl') + (path or self.root) |
164 return self.ui.config('web', 'baseurl') + (path or self.root) |
166 |
165 |
167 def node(self, node): |
166 def node(self, ctx): |
168 '''format one changeset.''' |
167 '''format one changeset.''' |
169 |
168 self.t.show(ctx, changes=ctx.changeset(), |
170 self.t.show(self.repo[node], changes=self.repo.changelog.read(node), |
|
171 baseurl=self.ui.config('web', 'baseurl'), |
169 baseurl=self.ui.config('web', 'baseurl'), |
172 root=self.repo.root, |
170 root=self.repo.root, webroot=self.root) |
173 webroot=self.root) |
|
174 |
171 |
175 def skipsource(self, source): |
172 def skipsource(self, source): |
176 '''true if incoming changes from this source should be skipped.''' |
173 '''true if incoming changes from this source should be skipped.''' |
177 ok_sources = self.ui.config('notify', 'sources', 'serve').split() |
174 ok_sources = self.ui.config('notify', 'sources', 'serve').split() |
178 return source not in ok_sources |
175 return source not in ok_sources |
179 |
176 |
180 def send(self, node, count, data): |
177 def send(self, ctx, count, data): |
181 '''send message.''' |
178 '''send message.''' |
182 |
179 |
183 p = email.Parser.Parser() |
180 p = email.Parser.Parser() |
184 msg = p.parsestr(data) |
181 msg = p.parsestr(data) |
185 |
182 |
201 # try to make subject line exist and be useful |
198 # try to make subject line exist and be useful |
202 if not subject: |
199 if not subject: |
203 if count > 1: |
200 if count > 1: |
204 subject = _('%s: %d new changesets') % (self.root, count) |
201 subject = _('%s: %d new changesets') % (self.root, count) |
205 else: |
202 else: |
206 changes = self.repo.changelog.read(node) |
203 s = ctx.description().lstrip().split('\n', 1)[0].rstrip() |
207 s = changes[4].lstrip().split('\n', 1)[0].rstrip() |
|
208 subject = '%s: %s' % (self.root, s) |
204 subject = '%s: %s' % (self.root, s) |
209 maxsubject = int(self.ui.config('notify', 'maxsubject', 67)) |
205 maxsubject = int(self.ui.config('notify', 'maxsubject', 67)) |
210 if maxsubject and len(subject) > maxsubject: |
206 if maxsubject and len(subject) > maxsubject: |
211 subject = subject[:maxsubject-3] + '...' |
207 subject = subject[:maxsubject-3] + '...' |
212 msg['Subject'] = mail.headencode(self.ui, subject, |
208 msg['Subject'] = mail.headencode(self.ui, subject, |
218 if '@' not in sender or '@localhost' in sender: |
214 if '@' not in sender or '@localhost' in sender: |
219 sender = self.fixmail(sender) |
215 sender = self.fixmail(sender) |
220 msg['From'] = mail.addressencode(self.ui, sender, |
216 msg['From'] = mail.addressencode(self.ui, sender, |
221 self.charsets, self.test) |
217 self.charsets, self.test) |
222 |
218 |
223 msg['X-Hg-Notification'] = 'changeset ' + short(node) |
219 msg['X-Hg-Notification'] = 'changeset %s' % ctx |
224 if not msg['Message-Id']: |
220 if not msg['Message-Id']: |
225 msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' % |
221 msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' % |
226 (short(node), int(time.time()), |
222 (ctx, int(time.time()), |
227 hash(self.repo.root), socket.getfqdn())) |
223 hash(self.repo.root), socket.getfqdn())) |
228 msg['To'] = ', '.join(self.subs) |
224 msg['To'] = ', '.join(self.subs) |
229 |
225 |
230 msgtext = msg.as_string(0) |
226 msgtext = msg.as_string(0) |
231 if self.test: |
227 if self.test: |
236 self.ui.status(_('notify: sending %d subscribers %d changes\n') % |
232 self.ui.status(_('notify: sending %d subscribers %d changes\n') % |
237 (len(self.subs), count)) |
233 (len(self.subs), count)) |
238 mail.sendmail(self.ui, util.email(msg['From']), |
234 mail.sendmail(self.ui, util.email(msg['From']), |
239 self.subs, msgtext) |
235 self.subs, msgtext) |
240 |
236 |
241 def diff(self, node, ref): |
237 def diff(self, ctx, ref=None): |
|
238 |
242 maxdiff = int(self.ui.config('notify', 'maxdiff', 300)) |
239 maxdiff = int(self.ui.config('notify', 'maxdiff', 300)) |
243 prev = self.repo.changelog.parents(node)[0] |
240 prev = ctx.parents()[0].node() |
244 |
241 ref = ref and ref.node() or ctx.node() |
245 chunks = patch.diff(self.repo, prev, ref, opts=patch.diffopts(self.ui)) |
242 chunks = patch.diff(self.repo, prev, ref, opts=patch.diffopts(self.ui)) |
246 difflines = ''.join(chunks).splitlines() |
243 difflines = ''.join(chunks).splitlines() |
247 |
244 |
248 if self.ui.configbool('notify', 'diffstat', True): |
245 if self.ui.configbool('notify', 'diffstat', True): |
249 s = patch.diffstat(difflines) |
246 s = patch.diffstat(difflines) |
250 # s may be nil, don't include the header if it is |
247 # s may be nil, don't include the header if it is |
251 if s: |
248 if s: |
252 self.ui.write('\ndiffstat:\n\n%s' % s) |
249 self.ui.write('\ndiffstat:\n\n%s' % s) |
|
250 |
253 if maxdiff == 0: |
251 if maxdiff == 0: |
254 return |
252 return |
255 if maxdiff > 0 and len(difflines) > maxdiff: |
253 elif maxdiff > 0 and len(difflines) > maxdiff: |
256 self.ui.write(_('\ndiffs (truncated from %d to %d lines):\n\n') % |
254 msg = _('\ndiffs (truncated from %d to %d lines):\n\n') |
257 (len(difflines), maxdiff)) |
255 self.ui.write(msg % (len(difflines), maxdiff)) |
258 difflines = difflines[:maxdiff] |
256 difflines = difflines[:maxdiff] |
259 elif difflines: |
257 elif difflines: |
260 self.ui.write(_('\ndiffs (%d lines):\n\n') % len(difflines)) |
258 self.ui.write(_('\ndiffs (%d lines):\n\n') % len(difflines)) |
|
259 |
261 self.ui.write("\n".join(difflines)) |
260 self.ui.write("\n".join(difflines)) |
262 |
261 |
263 def hook(ui, repo, hooktype, node=None, source=None, **kwargs): |
262 def hook(ui, repo, hooktype, node=None, source=None, **kwargs): |
264 '''send email notifications to interested subscribers. |
263 '''send email notifications to interested subscribers. |
265 |
264 |
266 if used as changegroup hook, send one email for all changesets in |
265 if used as changegroup hook, send one email for all changesets in |
267 changegroup. else send one email per changeset.''' |
266 changegroup. else send one email per changeset.''' |
|
267 |
268 n = notifier(ui, repo, hooktype) |
268 n = notifier(ui, repo, hooktype) |
|
269 ctx = repo[node] |
|
270 |
269 if not n.subs: |
271 if not n.subs: |
270 ui.debug(_('notify: no subscribers to repo %s\n') % n.root) |
272 ui.debug(_('notify: no subscribers to repo %s\n') % n.root) |
271 return |
273 return |
272 if n.skipsource(source): |
274 if n.skipsource(source): |
273 ui.debug(_('notify: changes have source "%s" - skipping\n') % |
275 ui.debug(_('notify: changes have source "%s" - skipping\n') % source) |
274 source) |
|
275 return |
276 return |
276 node = bin(node) |
277 |
277 ui.pushbuffer() |
278 ui.pushbuffer() |
278 if hooktype == 'changegroup': |
279 if hooktype == 'changegroup': |
279 start = repo[node].rev() |
280 start, end = ctx.rev(), len(repo) |
280 end = len(repo) |
|
281 count = end - start |
281 count = end - start |
282 for rev in xrange(start, end): |
282 for rev in xrange(start, end): |
283 n.node(repo[rev].node()) |
283 n.node(repo[rev]) |
284 n.diff(node, repo.changelog.tip()) |
284 n.diff(ctx, repo['tip']) |
285 else: |
285 else: |
286 count = 1 |
286 count = 1 |
287 n.node(node) |
287 n.node(ctx) |
288 n.diff(node, node) |
288 n.diff(ctx) |
|
289 |
289 data = ui.popbuffer() |
290 data = ui.popbuffer() |
290 n.send(node, count, data) |
291 n.send(ctx, count, data) |