X-Git-Url: https://git.ctpug.org.za/?p=bzrirker.git;a=blobdiff_plain;f=irkerhook.py;h=e9aabc8477726d850f9779cb0f6844333f62c995;hp=208c0d87911df2831d7f5bb78c4fee527566c430;hb=HEAD;hpb=6a73fedeef5fea9b643fa5f7a47f4b161c6cf5de diff --git a/irkerhook.py b/irkerhook.py index 208c0d8..e9aabc8 100644 --- a/irkerhook.py +++ b/irkerhook.py @@ -3,114 +3,146 @@ # Copyright 2012 Neil Muller # GPL 2+ - see COPYING for details -from bzrlib import ( - errors, - revision as _mod_revision, - ) -from bzrlib.config import ( - ListOption, - Option, - bool_from_store, - int_from_store, - ) +from bzrlib.config import Option +import socket +import sys +import json + +IRKER_PORT = 6659 class IrkerSender(object): """An irker message sender.""" - def __init__(self, branch, revision_id, config, local_branch=None, - op='commit'): + def __init__(self, branch, revision_id, config): self.config = config self.branch = branch - self.repository = branch.repository - if (local_branch is not None and - local_branch.repository.has_revision(revision_id)): - self.repository = local_branch.repository self._revision_id = revision_id self.revision = None self.revno = None - self.op = op def _setup_revision_and_revno(self): - self.revision = self.repository.get_revision(self._revision_id) + self.revision = self.branch.repository.get_revision(self._revision_id) self.revno = self.branch.revision_id_to_revno(self._revision_id) def _format(self): + """Munge the commit info into an irc message""" + delta = self.branch.repository.get_revision_delta(self._revision_id) + files = [] + [files.append(f) for (f, _, _) in delta.added] + [files.append(f) for (f, _, _) in delta.removed] + [files.append(f) for (_, f, _, _, _, _) in delta.renamed] + [files.append(f) for (f, _, _, _, _) in delta.modified] + fields = { + 'project': self.project(), 'committer': self.revision.committer, - 'message': self.revision.get_summary(), - 'revision': '%d' % self.revno, - 'url': self.url() + 'repo': self.branch.nick, + 'rev': '%d' % self.revno, + 'files': ' '.join(files), + 'logmsg': self.revision.get_summary(), } - text = '' - #for name, value in fields.items(): - # text = text.replace('$%s' % name, value) + if len(fields['files']) > 250: + # Dangerously long looking list of files, so truncate it + fields['files'] = fields['files'][:250] + fields.update(self.colours()) + text = ('%(bold)s%(project)s:%(reset)s ' + '%(green)s%(committer)s%(reset)s ' + '%(repo)s * %(bold)s%(rev)s%(reset)s / ' + ' %(bold)s%(files)s%(reset)s: %(logmsg)s ' % fields) return text - def body(self): - from bzrlib import log - - rev1 = rev2 = self.revno - if rev1 == 0: - rev1 = None - rev2 = None - - # use 'replace' so that we don't abort if trying to write out - # in e.g. the default C locale. - - # Following bzr-email, we use StringIO.StringIO to minimise possible - # unicode issues. - from StringIO import StringIO - outf = StringIO() - - lf = log.log_formatter('line', - show_ids=True, - to_file=outf - ) - - if len(self.revision.parent_ids) <= 1: - # This is not a merge, so we can special case the display of one - # revision, and not have to encur the show_log overhead. - lr = log.LogRevision(self.revision, self.revno, 0, None) - lf.log_revision(lr) - else: - # let the show_log code figure out what revisions need to be - # displayed, as this is a merge - log.show_log(self.branch, - lf, - start_revision=rev1, - end_revision=rev2, - verbose=True - ) - - return outf.getvalue() - - def url(self): - """What URL to display in the subject of the mail""" - url = self.config.get('irker_url') - if url is None: - url = self.config.get('public_branch') - if url is None: - url = self.branch.base - return url + def colours(self): + """Utility function to handle the colours""" + colour_style = self.config.get('irker_colours') + colours = { + 'bold': '', + 'green': '', + 'blue': '', + 'red': '', + 'yellow': '', + 'brown': '', + 'magenta': '', + 'cyan': '', + 'reset': '', + } + # Vaues taken from irker's irkerhook.py + if colour_style == 'ANSI': + colours = { + 'bold': '\x1b[1m', + 'green': '\x1b[1;32m', + 'blue': '\x1b[1;34m', + 'red': '\x1b[1;31m', + 'yellow': '\x1b[1;33m', + 'brown': '\x1b[33m', + 'magenta': '\x1b[35m', + 'cyan': '\x1b[36m', + 'reset': '\x1b[0m', + } + elif colour_style == 'mIRC': + colours = { + 'bold': '\x02', + 'green': '\x0303', + 'blue': '\x0302', + 'red': '\x0305', + 'yellow': '\x0307', + 'brown': '\x0305', + 'magenta': '\x0306', + 'cyan': '\x0310', + 'reset': '\x0F', + } + return colours + + def project(self): + project = self.config.get('irker_project') + if project is None: + project = 'No Project name set' + return project def send(self): """Send the info to irkerd. """ self.branch.lock_read() - self.repository.lock_read() + self.branch.repository.lock_read() + server = self.config.get('irker_server') + if not server: + server = 'localhost' + port = int(self.config.get('irker_port')) + if not port: + port = IRKER_PORT try: # Do this after we have locked, to make things faster. self._setup_revision_and_revno() + channels = self.config.get('irker_channels') + if channels: + channels = channels.split(',') + # If we're too long, we might not get any notification, so + # we truncate the msg to max 450 chars, and hope that's + # going to be within the 510 irc limit + msg = unicode(self._format())[:450] + message = json.dumps({"to": channels, "privmsg": msg}) + if channels: + # We assume tcp, since I'm lazy, so we just grab that bit + # of irker's code + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((server, port)) + sock.sendall(message + "\n") + except socket.error, e: + sys.stderr.write("%s\n" % e) + finally: + sock.close() finally: - self.repository.unlock() + self.branch.repository.unlock() self.branch.unlock() -opt_irker_url = Option('irker_url', - help='URL to mention for branch in messages.') opt_irker_channels = Option('irker_channels', help='Channel(s) to post commit messages to.') opt_irker_colours = Option('irker_colours', help='Colour option for irker.') opt_irker_project = Option('irker_project', help='Project name to use.') +opt_irker_server = Option('irker_server', + help='host for the irkerd server (default localhost).') +opt_irker_port = Option('irker_port', + help='port for the irkerd server (default %d)' % IRKER_PORT)