From 7cc47ab92bb9a38d31821ab1847442396af19287 Mon Sep 17 00:00:00 2001 From: Laurent Bachelier Date: Wed, 3 Oct 2012 21:54:57 +0200 Subject: [PATCH] Add support for external pre-filtering With manpage documentation including example script. Also add the full e-mail to the available metadata (only git for now). Signed-off-by: Eric S. Raymond --- irkerhook.py | 26 +++++++++++++++++++++----- irkerhook.xml | 27 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/irkerhook.py b/irkerhook.py index ee9b671..4619310 100755 --- a/irkerhook.py +++ b/irkerhook.py @@ -51,6 +51,7 @@ class Commit: self.commit = commit self.branch = None self.rev = None + self.mail = None self.author = None self.files = None self.logmsg = None @@ -93,6 +94,7 @@ class GenericExtractor: self.template = None self.urlprefix = None self.host = socket.getfqdn() + self.filtercmd = None # Color highlighting is disabled by default. self.color = None self.bold = self.green = self.blue = "" @@ -190,6 +192,7 @@ class GitExtractor(GenericExtractor): self.template = '%(bold)s%(project)s:%(reset)s %(green)s%(author)s%(reset)s %(repo)s:%(yellow)s%(branch)s%(reset)s * %(bold)s%(rev)s%(reset)s / %(bold)s%(files)s%(reset)s: %(logmsg)s %(brown)s%(url)s%(reset)s' self.color = do("git config --get irker.color") self.urlprefix = do("git config --get irker.urlprefix") or "gitweb" + self.filtercmd = do("git config --get irker.filtercmd") # These are git-specific self.refname = do("git symbolic-ref HEAD 2>/dev/null") self.revformat = do("git config --get irker.revformat") @@ -235,11 +238,12 @@ class GitExtractor(GenericExtractor): # other VCSes a different choice may be appropriate. metainfo = do("git log -1 '--pretty=format:%an <%ae>|%s' " + shellquote(commit.commit)) (commit.author, commit.logmsg) = metainfo.split("|") + commit.mail = commit.author.split()[-1].strip("<>") # This discards the part of the author's address after @. # Might be be nice to ship the full email address, if not # for spammers' address harvesters - getting this wrong # would make the freenode #commits channel into harvester heaven. - commit.author = commit.author.replace("<", "").split("@")[0].split()[-1] + commit.author = commit.mail.split("@")[0] return commit class SvnExtractor(GenericExtractor): @@ -359,6 +363,12 @@ extractors = [GitExtractor, HgExtractor, SvnExtractor] def ship(extractor, commit, debug): "Ship a notification for the specified commit." metadata = extractor.commit_factory(commit) + + # Run through an external filter if required. + channels = extractor.channels.split(",") + if extractor.filtercmd: + channels = filterc(extractor.filtercmd, channels, metadata) or [] + # Message reduction. The assumption here is that IRC can't handle # lines more than 510 characters long. If we exceed that length, we # try knocking out the file list, on the theory that for notification @@ -371,15 +381,14 @@ def ship(extractor, commit, debug): privmsg = str(metadata) # Anti-spamming guard. - channel_list = extractor.channels.split(",") if extractor.maxchannels != 0: - channel_list = channel_list[:extractor.maxchannels] + channels = channels[:extractor.maxchannels] # Ready to ship. - message = json.dumps({"to":channel_list, "privmsg":privmsg}) + message = json.dumps({"to": channels, "privmsg": privmsg}) if debug: print message - else: + elif channels: try: if extractor.tcp: try: @@ -397,6 +406,13 @@ def ship(extractor, commit, debug): except socket.error, e: sys.stderr.write("%s\n" % e) +def filterc(cmd, channels, commit): + channels, update = json.loads(do('%s %s %s' % (cmd, + shellquote(json.dumps(channels)), + shellquote(json.dumps(commit.__dict__))))) + commit.__dict__.update(update) + return channels + if __name__ == "__main__": notify = True repository = os.getcwd() diff --git a/irkerhook.xml b/irkerhook.xml index e10d5b8..a44c4f2 100644 --- a/irkerhook.xml +++ b/irkerhook.xml @@ -296,6 +296,33 @@ exists. +Filtering + +It is possible to filter commits before sending them to irkerd. + +You have to specify the option, which will be the command irkerhook.py will run. This command should accept two arguments: the first one being the commit metadata, the second one being the channel list. The command should then return a tuple, with the new channel list then an optional list of commit metadata updates. + +Below is an example filter: + + +#!/usr/bin/env python +import sys, json +channels = json.loads(sys.argv[1]) +commit = json.loads(sys.argv[2]) +update = {} +# we have two bobs in the project +if commit.get("mail", "") == "bob@foo": + update["author"] = "bobm" +if commit.get("mail", "") == "bob@bar": + update["author"] = "bobp" +# ignore some commits +if 'automated commit' in commit['logmsg']: + channels = [] +print json.dumps([channels, update]) + + + + OPTIONS -- 2.26.2