Add an external filtering facility.
authorEric S. Raymond <esr@thyrsus.com>
Thu, 4 Oct 2012 07:11:39 +0000 (03:11 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 4 Oct 2012 07:11:39 +0000 (03:11 -0400)
Not quite the same as laurentb's design; this one passes all the
commit and extractor data as a single JSON object, and expect to get
back same.

Makefile
NEWS
filter-example.py [new file with mode: 0755]
hacking.txt
irkerhook.py
irkerhook.xml

index eb0be3897cb24dc89dd61b7e29432fbaa0330dcf..8f12391d2721b3880fcdb23e678843a47173ebda 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ loc:
        @echo -n "LLOC: "; grep -vE '(^ *#|^ *$$)' irkerd irkerhook.py | wc -l
 
 SOURCES = README COPYING NEWS install.txt security.txt hacking.txt \
-       irkerd irkerhook.py Makefile irkerd.xml irkerhook.xml
+       irkerd irkerhook.py filter-example.py Makefile irkerd.xml irkerhook.xml
 EXTRA_DIST = irker-logo.png org.catb.irkerd.plist
 
 version:
diff --git a/NEWS b/NEWS
index 114b81135619f73352519798bce957f92d925e46..04864be7d754200d5ca102d8f5ca26eb7eb39f7f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
                        irker history 
 
+1.7 @
+  Optional metadata filtering with a user-specified command.
+
 1.6 @ 2012-10-04
   This is a stable release.
   In 1.5 trying to appease pylint broke the Mercurial hook.
diff --git a/filter-example.py b/filter-example.py
new file mode 100755 (executable)
index 0000000..12908b4
--- /dev/null
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+# This is a trivial example of a metadata filter.
+# All it does is change the name of the commit's author.
+# It could do other things, including modifying the
+# channels list
+# 
+import sys, json
+metadata = json.loads(sys.argv[1])
+
+metadata['author'] = "The Great and Powerful Oz"
+
+print json.dumps(metadata)
+# end
index b9c397d2021403e93917f282b0f12adf0bc5ed70..20e999020a265ed21a23f509bba6c9f5b1a14f50 100644 (file)
@@ -57,7 +57,8 @@ Peter Scott <pjscott@iastate.edu> contributed the original greenlet
 support.
 
 Laurent Bachelier <laurent@bachelier.name> fixed the Makefile so it 
-wouldn't break stuff and added the external filtering option.
+wouldn't break stuff and wrote the first version of the external 
+filtering option.
 
 dak180 (name withheld by request) wrote the OS X launchd plist.
 
index 202e1b2cf0d5a4481db9ee650b7bea5b9934b766..b1b2981403e544253d1fd41bfa6e4e40aed29d27 100755 (executable)
@@ -368,6 +368,16 @@ def ship(extractor, commit, debug):
     "Ship a notification for the specified commit."
     metadata = extractor.commit_factory(commit)
 
+    # This is where we apply filtering
+    if extractor.filtercmd:
+        data = do('%s %s' % (shellquote(extractor.filtercmd),
+                             shellquote(json.dumps(metadata.__dict__))))
+        try:
+            metadata.__dict__.update(json.loads(data))
+        except ValueError:
+            sys.stderr.write("irkerhook.py: could not decode JSON: %s\n" % data)
+            raise SystemExit, 1
+
     # 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
@@ -379,8 +389,10 @@ def ship(extractor, commit, debug):
         metadata.files = ""
         privmsg = str(metadata)
 
-    # Anti-spamming guard.
-    channels = extractor.channels.split(",")
+    # Anti-spamming guard.  It's deliberate that we get maxchannels not from
+    # the user-filtered metadata but from the extractor data - means repo
+    # administrators can lock in that setting.
+    channels = metadata.channels.split(",")
     if extractor.maxchannels != 0:
         channels = channels[:extractor.maxchannels]
 
index e10d5b838b5b576f7f96fb24b844d4920f2a63c2..0862dfb141e4a02b2e24914b2eca012ae6e01e76 100644 (file)
@@ -296,6 +296,36 @@ exists.</para>
 
 </refsect2>
 
+<refsect2 id="filter"><title>Filtering</title>
+
+<para>It is possible to filter commits before sending them to
+<application>irkerd</application>.</para>
+
+<para>You have to specify the <option>filtercmd</option> option, which
+will be the command <application>irkerhook.py</application> will
+run. This command should accept one arguments, which is a JSON
+representation of commit and extractor metadata (including the
+channels variable). The command should emit to standard output a JSON
+representation of (possibly altered) metadata.</para>
+
+<para>Below is an example filter:</para>
+
+<programlisting>
+#!/usr/bin/env python
+# This is a trivial example of a metadata filter.
+# All it does is change the name of the commit's author.
+# 
+import sys, json
+metadata = json.loads(sys.argv[1])
+
+metadata['author'] = "The Great and Powerful Oz"
+
+print json.dumps(metadata)
+# end
+</programlisting>
+
+</refsect2>
+
 </refsect1>
 
 <refsect1 id='options'><title>OPTIONS</title>