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)