Anton Shestakov <av6@dwimlabs.net>, Sun, 16 Dec 2018 11:15:33 +0800
plugin: fallback values for phab status and desc don't need to be so verbose
plugin.py
Permissions: -rw-r--r--
# Copyright (c) 2007, 2009 Brendan Cully # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright notice, # this list of conditions, and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions, and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the author of this software nor the name of # contributors to this software may be used to endorse or promote products # derived from this software without specific prior written consent. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from supybot import utils, plugins, ircutils, callbacks from supybot.commands import * def revparse(irc, msg, args, state): state.errorInvalid('revision', args[0], 'Contains ":".') state.args.append(args.pop(0)) addConverter('revision', revparse) def phabrevparse(irc, msg, args, state): if args[0].startswith('D'): callConverter('positiveInt', irc, msg, args, state) addConverter('phabrev', phabrevparse) def __init__(self, path): with open(os.devnull) as null: p = subprocess.Popen([self.path] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=null, env={'HGPLAIN': '1', 'HGENCODING': 'UTF-8'}) out, err = p.communicate() return (out.decode('utf-8'), err.decode('utf-8')) class Mercurial(callbacks.PluginRegexp): """Goodies for #mercurial.""" callBefore = ['URL', 'Web'] regexps = ['snarfDifferential', 'snarfDifferentialURL'] super(Mercurial, self).__init__(irc) self.path = self.registryValue('path') def hghelp(self, irc, msg, args, cmd): Runs hg help with the given args.""" lines = text.splitlines() if not line or line.startswith('aliases:'): if line.startswith(('options', 'enabled extensions:')): if out and ' extension - ' in out[0]: out[0] = ircutils.bold(out[0]) out[1] = ircutils.bold(out[1]) out, err = self.hg.run(['help', cmd]) irc.reply(err.splitlines()[0]) irc.replies(fmt(out), joiner=' ') hghelp = wrap(hghelp, ['text']) def _changelog(self, irc, repo, rev): tmpl = '{rev}:{node|short}\n{date|age}\n{author|person}\n{desc}' '-R', repo, 'log', '-r', rev, '-l', '1', '--template', tmpl, '-v' return irc.reply(err.splitlines()[0]) return irc.reply('no changesets found') lines = [line.strip() for line in out.splitlines()] node, date, user = lines[:3] node = ircutils.bold(node) user = ircutils.mircColor(user, fg='green') lines = ['%s %s %s' % (node, user, date)] + lines baseurl, err = self.hg.run(['-R', repo, 'paths', 'default']) url = "%s/rev/%s" % (baseurl.strip("\n/"), rev) irc.replies(lines[:2] + [url], joiner=' - ') def cmd(self, irc, msg, args, rev): Returns the changelog message and the URL for the given revision.""" self._changelog(irc, self.registryValue(key), rev) return wrap(cmd, ['revision']) main = _changelogcmd('repos.hg') hgcommitted = _changelogcmd('repos.hg-committed') hgall = _changelogcmd('repos.hg-all') hgwebsite = _changelogcmd('repos.hg-website') evolve = _changelogcmd('repos.evolve') def glossary(self, irc, msg, args, term): Returns glossary definition (from hg help glossary) for the term.""" raw, err = self.hg.run(['help', 'glossary']) for line in raw.splitlines(): if not found and line.lower().startswith(' ' + term.lower()): elif found and not (line.startswith(' ') or not line): if found and not done and line: irc.replies(answer[1:], joiner=' ') irc.reply('no match found') glossary = wrap(glossary, ['text']) def _differential(self, irc, phabrev, gotURL=False): baseurl = self.registryValue('phaburl') url = '{}/D{}'.format(baseurl.rstrip('/'), phabrev) page = utils.web.getUrl(url).decode('utf-8') match = re.search(r'<div class="phui-header-subheader">.*?</span>(?P<status>[^<]+?)</span>', page) status = utils.web.htmlToText(match.group('status')) match = re.search(r'<span class="phui-header-header">.*?</span>(?P<desc>[^<]+?)</span>', page) desc = utils.web.htmlToText(match.group('desc')) url = 'D{}'.format(phabrev) item = 'Revision {} {}, {}'.format(url, status, desc) def differential(self, irc, msg, args, phabrev): Returns URL, description and status of revisions on differential.""" self._differential(irc, phabrev) differential = wrap(differential, ['phabrev']) def snarfDifferential(self, irc, msg, match): r'(^|[^/])\bD(?P<phabrev>\d+)\b' if not irc.isChannel(channel): phabrev = match.group('phabrev') self._differential(irc, phabrev) def snarfDifferentialURL(self, irc, msg, match): r'\b(?P<url>https?://\S+/)D(?P<phabrev>\d+)\b' if not irc.isChannel(channel): if url.rstrip('/') != self.registryValue('phaburl').rstrip('/'): phabrev = match.group('phabrev') self._differential(irc, phabrev, gotURL=True)