diff --git a/.gitignore b/.gitignore
index ece25d7..c9f3787 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
*.tac
*.pyc
+twistd.pid
diff --git a/README.markdown b/README.markdown
new file mode 100644
index 0000000..04d2626
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,29 @@
+# commitbot
+
+Commitbot is an XMPP bot that notifies multi-user chat rooms (MUCs) of
+git repository commits.
+
+It uses the [GitHub](http://www.github.com) post-receive web hook to
+get push notifications of repository changes.
+
+## Dependencies
+
+* [Twisted](http://www.twistedmatrix.com) 8.1.x or later
+* [Wokkel](http://wokkel.ik.nu) 0.4 or later
+* [simplejson](http://pypi.python.org/pypi/simplejson)
+
+Note that on Ubuntu/Debian systems Twisted is split into various
+pieces. You will want:
+
+* python-twisted-words
+* python-twisted-names
+
+in addition to the normal Twisted package.
+
+## Usage
+
+Copy `commitbot.tac.example` to `commitbot.tac` changing the JID,
+password, room name, and room nickname to something appropriate. Then
+launch it with `twistd`.
+
+ twistd -y commitbot.tac
diff --git a/commitbot.py b/commitbot.py
index a21ab87..526834e 100644
--- a/commitbot.py
+++ b/commitbot.py
@@ -1,8 +1,15 @@
+from twisted.python import log
+from twisted.web import resource
from twisted.words.xish import domish
from wokkel.subprotocols import XMPPHandler
from wokkel.xmppim import AvailablePresence, Presence
+import simplejson as json
+
+
NS_MUC = 'http://jabber.org/protocol/muc'
+NS_XHTML_IM = 'http://jabber.org/protocols/xhtml-im'
+NS_XHTML_W3C = 'http://www.w3.org/1999/xhtml'
class CommitBot(XMPPHandler):
@@ -11,7 +18,6 @@ class CommitBot(XMPPHandler):
self.room = room
self.nick = nick
- self.joined = False
def connectionMade(self):
self.send(AvailablePresence())
@@ -22,7 +28,51 @@ class CommitBot(XMPPHandler):
pres = Presence()
pres['to'] = self.room + '/' + self.nick
pres.addElement((NS_MUC, 'x'))
+ self.send(pres)
-
-
+ def notify(self, data):
+ # build the messages
+ text = []
+ html = []
+ link = r"%s"
+ text.append('New commits in %s:\n' % data['repository']['url'])
+ html.append("New commits in " \
+ "%s:
" % \
+ (data['repository']['url'],
+ data['repository']['name']))
+
+ for c in data['commits']:
+ text.append('%s | %s | %s\n' % (c['message'],
+ c['author']['email'],
+ c['url']))
+ ltxt = link % (c['url'], c['id'], c['id'][:7])
+ html.append('%s | %s | %s
' % (c['message'],
+ c['author']['email'],
+ ltxt))
+ msg = domish.Element((None, 'message'))
+ msg['to'] = self.room
+ msg['from'] = self.room + '/' + self.nick
+ msg['type'] = 'groupchat'
+ msg.addElement('body', content=''.join(text))
+ wrap = msg.addElement((NS_XHTML_IM, 'html'))
+ body = wrap.addElement((NS_XHTML_W3C, 'body'))
+ body.addRawXml(''.join(html))
+
+ self.send(msg)
+
+
+class WebHook(resource.Resource):
+ isLeaf = True
+
+ def __init__(self, bot):
+ resource.Resource.__init__(self)
+ self.bot = bot
+
+ def render_GET(self, req):
+ return "commitbot ready to rock!"
+
+ def render_POST(self, req):
+ data = json.loads(req.args['payload'][0])
+ self.bot.notify(data)
+ return ""
diff --git a/commitbot.tac.example b/commitbot.tac.example
index 5b5c51e..a00c538 100644
--- a/commitbot.tac.example
+++ b/commitbot.tac.example
@@ -1,17 +1,23 @@
# -*- mode: python -*-
-from twisted.application import service
+from twisted.application import service, internet
+from twisted.web import server
from twisted.words.protocols.jabber import jid
from wokkel.client import XMPPClient
-from commitbot import CommitBot
+from commitbot import CommitBot, WebHook
application = service.Application('commitbot')
-client = XMPPClient(jid.internJID('user@host'), 'password')
-client.logTraffic = False
-bot = CommitBot('room@chat.example.com', 'commits')
+client = XMPPClient(jid.internJID('user@example.com'), 'password')
+client.logTraffic = True
+
+bot = CommitBot('room@chat.example.com', 'gitbot')
bot.setHandlerParent(client)
client.setServiceParent(application)
+
+site = server.Site(WebHook(bot))
+server = internet.TCPServer(8888, site)
+server.setServiceParent(application)