##// END OF EJS Templates
py3: use dict.items() instead of dict.iteritems()...
py3: use dict.items() instead of dict.iteritems() dict.iteritems() does not exist on Python 3. Differential Revision: https://phab.mercurial-scm.org/D5304

File last commit:

r40340:f6ef89cf default
r40765:5d1550b9 default
Show More
notify.py
515 lines | 16.8 KiB | text/x-python | PythonLexer
Vadim Gelfer
add email notification hook. hook written in python....
r2203 # notify.py - email notifications for mercurial
#
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Dirkjan Ochtman
help: better documentation intro for a few extensions
r7127
Patrick Mezard
notify: rewrite user documentation...
r14940 '''hooks for sending email push notifications
Dirkjan Ochtman
help: better documentation intro for a few extensions
r7127
David Champion
notify: various fixes to docstring...
r16950 This extension implements hooks to send email notifications when
changesets are sent from or received by the local repository.
Dirkjan Ochtman
help: better documentation intro for a few extensions
r7127
Patrick Mezard
notify: rewrite user documentation...
r14940 First, enable the extension as explained in :hg:`help extensions`, and
FUJIWARA Katsunori
doc: fix careless document miss in help of hgext/notify...
r16500 register the hook you want to run. ``incoming`` and ``changegroup`` hooks
David Champion
notify: various fixes to docstring...
r16950 are run when changesets are received, while ``outgoing`` hooks are for
changesets sent to another repository::
Dirkjan Ochtman
help: better documentation intro for a few extensions
r7127
Martin Geisler
notify: fix indentation in module docstring
r9105 [hooks]
# one email for each incoming changeset
incoming.notify = python:hgext.notify.hook
Patrick Mezard
notify: rewrite user documentation...
r14940 # one email for all incoming changesets
Martin Geisler
notify: fix indentation in module docstring
r9105 changegroup.notify = python:hgext.notify.hook
Patrick Mezard
notify: rewrite user documentation...
r14940
# one email for all outgoing changesets
Ingo Bressler
notify: send changesets on 'outgoing' hook, updated doc
r14617 outgoing.notify = python:hgext.notify.hook
Dirkjan Ochtman
help: better documentation intro for a few extensions
r7127
David Champion
notify: various fixes to docstring...
r16950 This registers the hooks. To enable notification, subscribers must
be assigned to repositories. The ``[usersubs]`` section maps multiple
repositories to a given recipient. The ``[reposubs]`` section maps
multiple recipients to a single repository::
Martin Geisler
commands: use minirst parser when displaying help
r9157
Martin Geisler
notify: fix indentation in module docstring
r9105 [usersubs]
Michal Sznajder
notify: support revset selection for subscriptions...
r17754 # key is subscriber email, value is a comma-separated list of repo patterns
Martin Geisler
notify: fix indentation in module docstring
r9105 user@host = pattern
Dirkjan Ochtman
help: better documentation intro for a few extensions
r7127
Martin Geisler
notify: fix indentation in module docstring
r9105 [reposubs]
Michal Sznajder
notify: support revset selection for subscriptions...
r17754 # key is repo pattern, value is a comma-separated list of subscriber emails
Martin Geisler
notify: fix indentation in module docstring
r9105 pattern = user@host
Dirkjan Ochtman
help: better documentation intro for a few extensions
r7127
Michal Sznajder
notify: support revset selection for subscriptions...
r17754 A ``pattern`` is a ``glob`` matching the absolute path to a repository,
optionally combined with a revset expression. A revset expression, if
present, is separated from the glob by a hash. Example::
[reposubs]
*/widgets#branch(release) = qa-team@example.com
This sends to ``qa-team@example.com`` whenever a changeset on the ``release``
branch triggers a notification in any repository ending in ``widgets``.
David Champion
notify: various fixes to docstring...
r16950
In order to place them under direct user management, ``[usersubs]`` and
``[reposubs]`` sections may be placed in a separate ``hgrc`` file and
incorporated by reference::
Patrick Mezard
notify: rewrite user documentation...
r14940
[notify]
config = /path/to/subscriptionsfile
David Champion
notify: various fixes to docstring...
r16950 Notifications will not be sent until the ``notify.test`` value is set
to ``False``; see below.
Patrick Mezard
notify: rewrite user documentation...
r14940
Notifications content can be tweaked with the following configuration entries:
notify.test
If ``True``, print messages to stdout instead of sending them. Default: True.
notify.sources
David Champion
notify: various fixes to docstring...
r16950 Space-separated list of change sources. Notifications are activated only
when a changeset's source is in this list. Sources may be:
:``serve``: changesets received via http or ssh
:``pull``: changesets received via ``hg pull``
:``unbundle``: changesets received via ``hg unbundle``
:``push``: changesets sent or received via ``hg push``
:``bundle``: changesets sent via ``hg unbundle``
Default: serve.
Patrick Mezard
notify: rewrite user documentation...
r14940
notify.strip
Number of leading slashes to strip from url paths. By default, notifications
David Champion
notify: various fixes to docstring...
r16950 reference repositories with their absolute path. ``notify.strip`` lets you
Patrick Mezard
notify: rewrite user documentation...
r14940 turn them into relative paths. For example, ``notify.strip=3`` will change
``/long/path/repository`` into ``repository``. Default: 0.
notify.domain
David Champion
notify: various fixes to docstring...
r16950 Default email domain for sender or recipients with no explicit domain.
Dirkjan Ochtman
help: better documentation intro for a few extensions
r7127
Patrick Mezard
notify: rewrite user documentation...
r14940 notify.style
Style file to use when formatting emails.
notify.template
Template to use when formatting emails.
notify.incoming
David Champion
notify: various fixes to docstring...
r16950 Template to use when run as an incoming hook, overriding ``notify.template``.
Patrick Mezard
notify: rewrite user documentation...
r14940
notify.outgoing
David Champion
notify: various fixes to docstring...
r16950 Template to use when run as an outgoing hook, overriding ``notify.template``.
Patrick Mezard
notify: rewrite user documentation...
r14940
notify.changegroup
David Champion
notify: various fixes to docstring...
r16950 Template to use when running as a changegroup hook, overriding
Patrick Mezard
notify: rewrite user documentation...
r14940 ``notify.template``.
notify.maxdiff
Maximum number of diff lines to include in notification email. Set to 0
David Champion
notify: various fixes to docstring...
r16950 to disable the diff, or -1 to include all of it. Default: 300.
Patrick Mezard
notify: rewrite user documentation...
r14940
Joerg Sonnenberger
notify: add maxdiffstat option to truncate long file lists...
r37795 notify.maxdiffstat
Maximum number of diffstat lines to include in notification email. Set to -1
to include all of it. Default: -1.
Patrick Mezard
notify: rewrite user documentation...
r14940 notify.maxsubject
David Champion
notify: various fixes to docstring...
r16950 Maximum number of characters in email's subject line. Default: 67.
Patrick Mezard
notify: rewrite user documentation...
r14940
notify.diffstat
Set to True to include a diffstat before diff content. Default: True.
Joerg Sonnenberger
notify: add option to include function names in the diff output...
r38048 notify.showfunc
If set, override ``diff.showfunc`` for the diff content. Default: None.
Patrick Mezard
notify: rewrite user documentation...
r14940 notify.merge
If True, send notifications for merge changesets. Default: True.
Mads Kiilerich
notify: add option for writing to mbox...
r15561 notify.mbox
If set, append mails to this mbox file instead of sending. Default: None.
Nikolaus Schueler
notify: change behavior of "changegroup" hook...
r15654 notify.fromauthor
David Champion
notify: various fixes to docstring...
r16950 If set, use the committer of the first changeset in a changegroup for
the "From" field of the notification mail. If not set, take the user
from the pushing repo. Default: False.
Nikolaus Schueler
notify: change behavior of "changegroup" hook...
r15654
David Champion
notify: various fixes to docstring...
r16950 If set, the following entries will also be used to customize the
notifications:
Patrick Mezard
notify: rewrite user documentation...
r14940
email.from
David Champion
notify: various fixes to docstring...
r16950 Email ``From`` address to use if none can be found in the generated
email content.
Patrick Mezard
notify: rewrite user documentation...
r14940
web.baseurl
David Champion
notify: various fixes to docstring...
r16950 Root repository URL to combine with repository paths when making
Patrick Mezard
notify: rewrite user documentation...
r14940 references. See also ``notify.strip``.
Martin Geisler
notify: wrapped docstrings at 78 characters
r9068 '''
timeless
notify: use absolute_import
r28416 from __future__ import absolute_import
Vadim Gelfer
add email notification hook. hook written in python....
r2203
Yuya Nishihara
notify: just use email.errors...
r40326 import email.errors as emailerrors
Pulkit Goyal
py3: use email.parser module to parse email messages...
r35651 import email.parser as emailparser
timeless
notify: use absolute_import
r28416 import fnmatch
import socket
import time
Yuya Nishihara
py3: move up symbol imports to enforce import-checker rules...
r29205 from mercurial.i18n import _
timeless
notify: use absolute_import
r28416 from mercurial import (
Augie Fackler
notify: a ton of encoding dancing to deal with the email module...
r40340 encoding,
timeless
notify: use absolute_import
r28416 error,
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 logcmdutil,
timeless
notify: use absolute_import
r28416 mail,
patch,
Boris Feld
configitems: register the 'notify.config' config
r33738 registrar,
timeless
notify: use absolute_import
r28416 util,
)
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 from mercurial.utils import (
dateutil,
stringutil,
)
Vadim Gelfer
add email notification hook. hook written in python....
r2203
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
Augie Fackler
extensions: document that `testedwith = 'internal'` is special...
r25186 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
# leave the attribute unspecified.
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 testedwith = 'ships-with-hg-core'
Augie Fackler
hgext: mark all first-party extensions as such
r16743
Boris Feld
configitems: register the 'notify.config' config
r33738 configtable = {}
configitem = registrar.configitem(configtable)
Boris Feld
configitem: register the 'notify.changegroup' config
r34755 configitem('notify', 'changegroup',
default=None,
)
Boris Feld
configitems: register the 'notify.config' config
r33738 configitem('notify', 'config',
default=None,
)
Boris Feld
configitems: register the 'notify.diffstat' config
r33739 configitem('notify', 'diffstat',
default=True,
)
Boris Feld
configitems: register the 'notify.domain' config
r33740 configitem('notify', 'domain',
default=None,
)
Boris Feld
configitems: register the 'notify.fromauthor' config
r33741 configitem('notify', 'fromauthor',
default=None,
)
Boris Feld
configitem: register the 'notify.incoming' config
r34753 configitem('notify', 'incoming',
default=None,
)
Boris Feld
configitems: register the 'notify.maxdiff' config
r33742 configitem('notify', 'maxdiff',
default=300,
)
Joerg Sonnenberger
notify: add maxdiffstat option to truncate long file lists...
r37795 configitem('notify', 'maxdiffstat',
default=-1,
)
Boris Feld
configitems: register the 'notify.maxsubject' config
r33743 configitem('notify', 'maxsubject',
default=67,
)
Boris Feld
configitems: register the 'notify.mbox' config
r33744 configitem('notify', 'mbox',
default=None,
)
Boris Feld
configitems: register the 'notify.merge' config
r33745 configitem('notify', 'merge',
default=True,
)
Boris Feld
configitem: register the 'notify.outgoing' config
r34754 configitem('notify', 'outgoing',
default=None,
)
Boris Feld
configitems: register the 'notify.sources' config
r33746 configitem('notify', 'sources',
default='serve',
)
Joerg Sonnenberger
notify: add option to include function names in the diff output...
r38048 configitem('notify', 'showfunc',
default=None,
)
Boris Feld
configitems: register the 'notify.strip' config
r33747 configitem('notify', 'strip',
default=0,
)
Boris Feld
configitems: register the 'notify.style' config
r33748 configitem('notify', 'style',
default=None,
)
Boris Feld
configitems: register the 'notify.template' config
r33749 configitem('notify', 'template',
default=None,
)
Boris Feld
configitems: register the 'notify.test' config
r33750 configitem('notify', 'test',
default=True,
)
Boris Feld
configitems: register the 'notify.config' config
r33738
Vadim Gelfer
add email notification hook. hook written in python....
r2203 # template for single changeset can include email headers.
Augie Fackler
notify: add some b prefixes...
r40319 single_template = b'''
Vadim Gelfer
add email notification hook. hook written in python....
r2203 Subject: changeset in {webroot}: {desc|firstline|strip}
From: {author}
changeset {node|short} in {root}
details: {baseurl}{webroot}?cmd=changeset;node={node|short}
description:
\t{desc|tabindent|strip}
'''.lstrip()
# template for multiple changesets should not contain email headers,
# because only first set of headers will be used and result will look
# strange.
Augie Fackler
notify: add some b prefixes...
r40319 multiple_template = b'''
Vadim Gelfer
add email notification hook. hook written in python....
r2203 changeset {node|short} in {root}
details: {baseurl}{webroot}?cmd=changeset;node={node|short}
summary: {desc|firstline}
'''
deftemplates = {
'changegroup': multiple_template,
Thomas Arendsen Hein
Fixed indentation in hgext/notify.py
r4498 }
Bryan O'Sullivan
patch queue: notify.patch
r2201
class notifier(object):
Vadim Gelfer
add email notification hook. hook written in python....
r2203 '''email notification class.'''
def __init__(self, ui, repo, hooktype):
Bryan O'Sullivan
patch queue: notify.patch
r2201 self.ui = ui
Vadim Gelfer
notify: add debug output. do not fail if no config file....
r2329 cfg = self.ui.config('notify', 'config')
if cfg:
Matt Mackall
ui: fold readsections into readconfig...
r8142 self.ui.readconfig(cfg, sections=['usersubs', 'reposubs'])
Bryan O'Sullivan
patch queue: notify.patch
r2201 self.repo = repo
Boris Feld
configitems: register the 'notify.strip' config
r33747 self.stripcount = int(self.ui.config('notify', 'strip'))
Bryan O'Sullivan
patch queue: notify.patch
r2201 self.root = self.strip(self.repo.root)
Vadim Gelfer
add email notification hook. hook written in python....
r2203 self.domain = self.ui.config('notify', 'domain')
Mads Kiilerich
notify: add option for writing to mbox...
r15561 self.mbox = self.ui.config('notify', 'mbox')
Boris Feld
configitems: register the 'notify.test' config
r33750 self.test = self.ui.configbool('notify', 'test')
Christian Ebert
notify: mime-encode messages...
r7116 self.charsets = mail._charsets(self.ui)
Vadim Gelfer
add email notification hook. hook written in python....
r2203 self.subs = self.subscribers()
Boris Feld
configitems: register the 'notify.merge' config
r33745 self.merge = self.ui.configbool('notify', 'merge')
Joerg Sonnenberger
notify: add option to include function names in the diff output...
r38048 self.showfunc = self.ui.configbool('notify', 'showfunc')
if self.showfunc is None:
self.showfunc = self.ui.configbool('diff', 'showfunc')
Vadim Gelfer
add email notification hook. hook written in python....
r2203
Yuya Nishihara
notify: do not load style file if template is specified (BC)...
r28951 mapfile = None
Vadim Gelfer
add email notification hook. hook written in python....
r2203 template = (self.ui.config('notify', hooktype) or
self.ui.config('notify', 'template'))
Yuya Nishihara
notify: do not load style file if template is specified (BC)...
r28951 if not template:
mapfile = self.ui.config('notify', 'style')
Vadim Gelfer
add email notification hook. hook written in python....
r2203 if not mapfile and not template:
template = deftemplates.get(hooktype) or single_template
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 spec = logcmdutil.templatespec(template, mapfile)
Yuya Nishihara
logcmdutil: drop default arguments from changesetdisplayer/templater() calls
r35972 self.t = logcmdutil.changesettemplater(self.ui, self.repo, spec)
Bryan O'Sullivan
patch queue: notify.patch
r2201
def strip(self, path):
Vadim Gelfer
add email notification hook. hook written in python....
r2203 '''strip leading slashes from local path, turn into web-safe path.'''
Bryan O'Sullivan
patch queue: notify.patch
r2201 path = util.pconvert(path)
count = self.stripcount
Vadim Gelfer
notify: fix off by one error.
r2326 while count > 0:
Bryan O'Sullivan
patch queue: notify.patch
r2201 c = path.find('/')
if c == -1:
break
Matt Mackall
many, many trivial check-code fixups
r10282 path = path[c + 1:]
Bryan O'Sullivan
patch queue: notify.patch
r2201 count -= 1
return path
Vadim Gelfer
add email notification hook. hook written in python....
r2203 def fixmail(self, addr):
'''try to clean up email addresses.'''
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 addr = stringutil.email(addr.strip())
Alexis S. L. Carvalho
notify: don't try to fix addresses if notify.domain is not set
r4094 if self.domain:
a = addr.find('@localhost')
if a != -1:
addr = addr[:a]
if '@' not in addr:
return addr + '@' + self.domain
Vadim Gelfer
add email notification hook. hook written in python....
r2203 return addr
Bryan O'Sullivan
patch queue: notify.patch
r2201 def subscribers(self):
Vadim Gelfer
add email notification hook. hook written in python....
r2203 '''return list of email addresses of subscribers to this repo.'''
Martin Geisler
notify: turned a set-like dict into a real set
r8154 subs = set()
Vadim Gelfer
add email notification hook. hook written in python....
r2203 for user, pats in self.ui.configitems('usersubs'):
for pat in pats.split(','):
Michal Sznajder
notify: support revset selection for subscriptions...
r17754 if '#' in pat:
pat, revs = pat.split('#', 1)
else:
revs = None
Vadim Gelfer
add email notification hook. hook written in python....
r2203 if fnmatch.fnmatch(self.repo.root, pat.strip()):
Michal Sznajder
notify: support revset selection for subscriptions...
r17754 subs.add((self.fixmail(user), revs))
Bryan O'Sullivan
patch queue: notify.patch
r2201 for pat, users in self.ui.configitems('reposubs'):
Michal Sznajder
notify: support revset selection for subscriptions...
r17754 if '#' in pat:
pat, revs = pat.split('#', 1)
else:
revs = None
Vadim Gelfer
add email notification hook. hook written in python....
r2203 if fnmatch.fnmatch(self.repo.root, pat):
for user in users.split(','):
Michal Sznajder
notify: support revset selection for subscriptions...
r17754 subs.add((self.fixmail(user), revs))
return [(mail.addressencode(self.ui, s, self.charsets, self.test), r)
for s, r in sorted(subs)]
Bryan O'Sullivan
patch queue: notify.patch
r2201
Bryan O'Sullivan
notify: make it possible to pass extra info into templates
r9486 def node(self, ctx, **props):
David Champion
notify: permit suppression of merge changeset notification...
r9516 '''format one changeset, unless it is a suppressed merge.'''
if not self.merge and len(ctx.parents()) > 1:
return False
Dirkjan Ochtman
notify: use contexts more pervasively
r7726 self.t.show(ctx, changes=ctx.changeset(),
Vadim Gelfer
add email notification hook. hook written in python....
r2203 baseurl=self.ui.config('web', 'baseurl'),
Bryan O'Sullivan
notify: make it possible to pass extra info into templates
r9486 root=self.repo.root, webroot=self.root, **props)
David Champion
notify: permit suppression of merge changeset notification...
r9516 return True
Vadim Gelfer
add email notification hook. hook written in python....
r2203
Vadim Gelfer
localrepository.addchangegroup: add more source infos to hooks
r2230 def skipsource(self, source):
'''true if incoming changes from this source should be skipped.'''
Boris Feld
configitems: register the 'notify.sources' config
r33746 ok_sources = self.ui.config('notify', 'sources').split()
Vadim Gelfer
localrepository.addchangegroup: add more source infos to hooks
r2230 return source not in ok_sources
Dirkjan Ochtman
notify: use contexts more pervasively
r7726 def send(self, ctx, count, data):
Vadim Gelfer
add email notification hook. hook written in python....
r2203 '''send message.'''
Michal Sznajder
notify: support revset selection for subscriptions...
r17754 # Select subscribers by revset
subs = set()
for sub, spec in self.subs:
if spec is None:
subs.add(sub)
continue
revs = self.repo.revs('%r and %d:', spec, ctx.rev())
if len(revs):
subs.add(sub)
continue
if len(subs) == 0:
self.ui.debug('notify: no subscribers to selected repo '
'and revset\n')
return
Pulkit Goyal
py3: use email.parser module to parse email messages...
r35651 p = emailparser.Parser()
Christian Ebert
notify: do not mime encode multipart templates...
r9313 try:
Augie Fackler
notify: a ton of encoding dancing to deal with the email module...
r40340 msg = p.parsestr(encoding.strfromlocal(data))
Augie Fackler
notify: adapt to new location of email module's errors...
r40320 except emailerrors.MessageParseError as inst:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(inst)
Vadim Gelfer
add email notification hook. hook written in python....
r2203
Christian Ebert
notify: mime-encode messages...
r7116 # store sender and subject
Augie Fackler
notify: a ton of encoding dancing to deal with the email module...
r40340 sender = encoding.strtolocal(msg[r'From'])
subject = encoding.strtolocal(msg[r'Subject'])
del msg[r'From'], msg[r'Subject']
Christian Ebert
notify: do not mime encode multipart templates...
r9313
if not msg.is_multipart():
# create fresh mime message from scratch
# (multipart templates must take care of this themselves)
headers = msg.items()
payload = msg.get_payload()
# for notification prefer readability over data precision
msg = mail.mimeencode(self.ui, payload, self.charsets, self.test)
# reinstate custom headers
for k, v in headers:
msg[k] = v
Christian Ebert
notify: mime-encode messages...
r7116
Augie Fackler
notify: a ton of encoding dancing to deal with the email module...
r40340 msg[r'Date'] = encoding.strfromlocal(
dateutil.datestr(format="%a, %d %b %Y %H:%M:%S %1%2"))
Vadim Gelfer
add email notification hook. hook written in python....
r2203
Christian Ebert
notify: remove subfunctions that are called only once
r7705 # try to make subject line exist and be useful
if not subject:
if count > 1:
subject = _('%s: %d new changesets') % (self.root, count)
else:
Dirkjan Ochtman
notify: use contexts more pervasively
r7726 s = ctx.description().lstrip().split('\n', 1)[0].rstrip()
Christian Ebert
notify: remove subfunctions that are called only once
r7705 subject = '%s: %s' % (self.root, s)
Boris Feld
configitems: register the 'notify.maxsubject' config
r33743 maxsubject = int(self.ui.config('notify', 'maxsubject'))
Yuya Nishihara
notify: use util.ellipsis() to truncate long subject
r13202 if maxsubject:
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 subject = stringutil.ellipsis(subject, maxsubject)
Augie Fackler
notify: a ton of encoding dancing to deal with the email module...
r40340 msg[r'Subject'] = encoding.strfromlocal(
mail.headencode(self.ui, subject, self.charsets, self.test))
Vadim Gelfer
add email notification hook. hook written in python....
r2203
Christian Ebert
notify: remove subfunctions that are called only once
r7705 # try to make message have proper sender
if not sender:
sender = self.ui.config('email', 'from') or self.ui.username()
if '@' not in sender or '@localhost' in sender:
sender = self.fixmail(sender)
Augie Fackler
notify: a ton of encoding dancing to deal with the email module...
r40340 msg[r'From'] = encoding.strfromlocal(
mail.addressencode(self.ui, sender, self.charsets, self.test))
Vadim Gelfer
add email notification hook. hook written in python....
r2203
Augie Fackler
notify: a ton of encoding dancing to deal with the email module...
r40340 msg[r'X-Hg-Notification'] = r'changeset %s' % ctx
if not msg[r'Message-Id']:
msg[r'Message-Id'] = encoding.strfromlocal(
'<hg.%s.%d.%d@%s>' % (ctx, int(time.time()),
hash(self.repo.root),
encoding.strtolocal(socket.getfqdn())))
msg[r'To'] = encoding.strfromlocal(', '.join(sorted(subs)))
Vadim Gelfer
add email notification hook. hook written in python....
r2203
Augie Fackler
notify: a ton of encoding dancing to deal with the email module...
r40340 msgtext = encoding.strtolocal(msg.as_string())
Christian Ebert
notify: no charset conversion when testing...
r7498 if self.test:
Vadim Gelfer
add email notification hook. hook written in python....
r2203 self.ui.write(msgtext)
if not msgtext.endswith('\n'):
self.ui.write('\n')
Bryan O'Sullivan
patch queue: notify.patch
r2201 else:
Vadim Gelfer
notify: add debug output. do not fail if no config file....
r2329 self.ui.status(_('notify: sending %d subscribers %d changes\n') %
Michal Sznajder
notify: support revset selection for subscriptions...
r17754 (len(subs), count))
Augie Fackler
notify: a ton of encoding dancing to deal with the email module...
r40340 mail.sendmail(self.ui, stringutil.email(msg[r'From']),
Michal Sznajder
notify: support revset selection for subscriptions...
r17754 subs, msgtext, mbox=self.mbox)
Bryan O'Sullivan
patch queue: notify.patch
r2201
Dirkjan Ochtman
notify: use contexts more pervasively
r7726 def diff(self, ctx, ref=None):
Boris Feld
configitems: register the 'notify.maxdiff' config
r33742 maxdiff = int(self.ui.config('notify', 'maxdiff'))
Matt Mackall
misc: replace .parents()[0] with p1()
r13878 prev = ctx.p1().node()
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if ref:
ref = ref.node()
else:
ref = ctx.node()
Joerg Sonnenberger
notify: add option to include function names in the diff output...
r38048 diffopts = patch.diffallopts(self.ui)
diffopts.showfunc = self.showfunc
chunks = patch.diff(self.repo, prev, ref, opts=diffopts)
Dirkjan Ochtman
patch: turn patch.diff() into a generator...
r7308 difflines = ''.join(chunks).splitlines()
divy@chelsio.com
notify: fix diffstat printing...
r6979
Boris Feld
configitems: register the 'notify.diffstat' config
r33739 if self.ui.configbool('notify', 'diffstat'):
Joerg Sonnenberger
notify: add maxdiffstat option to truncate long file lists...
r37795 maxdiffstat = int(self.ui.config('notify', 'maxdiffstat'))
Matt Doar
Add support for diffstat in commit emails, and move diffstat from...
r3096 s = patch.diffstat(difflines)
Sean Dague
Prevent type exception on concatenation if diffstat returns None....
r4077 # s may be nil, don't include the header if it is
if s:
Joerg Sonnenberger
notify: add maxdiffstat option to truncate long file lists...
r37795 if maxdiffstat >= 0 and s.count("\n") > maxdiffstat + 1:
s = s.split("\n")
msg = _('\ndiffstat (truncated from %d to %d lines):\n\n')
self.ui.write(msg % (len(s) - 2, maxdiffstat))
self.ui.write("\n".join(s[:maxdiffstat] + s[-2:]))
else:
self.ui.write(_('\ndiffstat:\n\n%s') % s)
Dirkjan Ochtman
notify: use contexts more pervasively
r7726
Benoît Allard
notify: print diffstat even if maxline == 0
r6305 if maxdiff == 0:
return
Dirkjan Ochtman
notify: use contexts more pervasively
r7726 elif maxdiff > 0 and len(difflines) > maxdiff:
msg = _('\ndiffs (truncated from %d to %d lines):\n\n')
self.ui.write(msg % (len(difflines), maxdiff))
Vadim Gelfer
add email notification hook. hook written in python....
r2203 difflines = difflines[:maxdiff]
elif difflines:
Matt Mackall
fix notify with new ui buffering
r3739 self.ui.write(_('\ndiffs (%d lines):\n\n') % len(difflines))
Dirkjan Ochtman
notify: use contexts more pervasively
r7726
divy@chelsio.com
notify: fix diffstat printing...
r6979 self.ui.write("\n".join(difflines))
Bryan O'Sullivan
patch queue: notify.patch
r2201
Vadim Gelfer
localrepository.addchangegroup: add more source infos to hooks
r2230 def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
Vadim Gelfer
add email notification hook. hook written in python....
r2203 '''send email notifications to interested subscribers.
if used as changegroup hook, send one email for all changesets in
changegroup. else send one email per changeset.'''
Dirkjan Ochtman
notify: use contexts more pervasively
r7726
Vadim Gelfer
add email notification hook. hook written in python....
r2203 n = notifier(ui, repo, hooktype)
Boris Feld
notify: access the initial revision on an unfiltered repository (issue5821)...
r37812 ctx = repo.unfiltered()[node]
Dirkjan Ochtman
notify: use contexts more pervasively
r7726
Vadim Gelfer
notify: add debug output. do not fail if no config file....
r2329 if not n.subs:
Martin Geisler
do not attempt to translate ui.debug output
r9467 ui.debug('notify: no subscribers to repository %s\n' % n.root)
Vadim Gelfer
notify: add debug output. do not fail if no config file....
r2329 return
if n.skipsource(source):
Martin Geisler
do not attempt to translate ui.debug output
r9467 ui.debug('notify: changes have source "%s" - skipping\n' % source)
Vadim Gelfer
localrepository.addchangegroup: add more source infos to hooks
r2230 return
Dirkjan Ochtman
notify: use contexts more pervasively
r7726
Matt Mackall
fix notify with new ui buffering
r3739 ui.pushbuffer()
David Champion
notify: permit suppression of merge changeset notification...
r9516 data = ''
count = 0
Nikolaus Schueler
notify: change behavior of "changegroup" hook...
r15654 author = ''
Ingo Bressler
notify: send changesets on 'outgoing' hook, updated doc
r14617 if hooktype == 'changegroup' or hooktype == 'outgoing':
Boris Feld
notify: use changelog API to iterate over revision number (issue5821)...
r37811 for rev in repo.changelog.revs(start=ctx.rev()):
David Champion
notify: permit suppression of merge changeset notification...
r9516 if n.node(repo[rev]):
count += 1
Nikolaus Schueler
notify: change behavior of "changegroup" hook...
r15654 if not author:
author = repo[rev].user()
David Champion
notify: permit suppression of merge changeset notification...
r9516 else:
data += ui.popbuffer()
Brodie Rao
cleanup: eradicate long lines
r16683 ui.note(_('notify: suppressing notification for merge %d:%s\n')
% (rev, repo[rev].hex()[:12]))
David Champion
notify: permit suppression of merge changeset notification...
r9516 ui.pushbuffer()
if count:
n.diff(ctx, repo['tip'])
Boris Feld
notify: only notify for non-filtered revision...
r37813 elif ctx.rev() in repo:
David Champion
notify: permit suppression of merge changeset notification...
r9516 if not n.node(ctx):
ui.popbuffer()
ui.note(_('notify: suppressing notification for merge %d:%s\n') %
(ctx.rev(), ctx.hex()[:12]))
return
count += 1
Dirkjan Ochtman
notify: use contexts more pervasively
r7726 n.diff(ctx)
Bruce Cran
notify: fix fromauthor setting for 'incoming' hook type (issue4194)...
r26503 if not author:
author = ctx.user()
Dirkjan Ochtman
notify: use contexts more pervasively
r7726
David Champion
notify: permit suppression of merge changeset notification...
r9516 data += ui.popbuffer()
Nikolaus Schueler
notify: change behavior of "changegroup" hook...
r15654 fromauthor = ui.config('notify', 'fromauthor')
if author and fromauthor:
data = '\n'.join(['From: %s' % author, data])
David Champion
notify: permit suppression of merge changeset notification...
r9516 if count:
n.send(ctx, count, data)