Mercurial > p > roundup > code
comparison detectors/irker.py @ 4695:132650f4700a
#2550782: Added a new irker detector to send notifications on IRC when an issue is created or messages are added.
| author | Ezio Melotti <ezio.melotti@gmail.com> |
|---|---|
| date | Fri, 14 Dec 2012 18:22:27 +0200 |
| parents | |
| children | 64b05e24dbd8 |
comparison
equal
deleted
inserted
replaced
| 4694:118457ca2e07 | 4695:132650f4700a |
|---|---|
| 1 # This detector sends notification on IRC through an irker daemon | |
| 2 # (http://www.catb.org/esr/irker/) when issues are created or messages | |
| 3 # are added. | |
| 4 # | |
| 5 # Written by Ezio Melotti | |
| 6 # | |
| 7 # Requires a running irkerd daemon to work. See the irker documentation | |
| 8 # for more information about installing, configuring, and running irker. | |
| 9 # | |
| 10 # Add the IRC channel(s) that should receive notifications in | |
| 11 # detectors/config.ini as a comma-separated list, using this format: | |
| 12 # | |
| 13 # [irker] | |
| 14 # channels = irc://chat.freenode.net/channelname | |
| 15 # | |
| 16 | |
| 17 import re | |
| 18 import json | |
| 19 import socket | |
| 20 | |
| 21 IRKER_HOST = 'localhost' | |
| 22 IRKER_PORT = 6659 | |
| 23 | |
| 24 max_content = 120 | |
| 25 | |
| 26 TEMPLATE = ('%(green)s%(author)s%(reset)s ' | |
| 27 '%(bluish)s#%(nodeid)s%(reset)s/%(title)s%(bold)s:%(bold)s ' | |
| 28 '%(log)s %(url)s') | |
| 29 | |
| 30 | |
| 31 def sendmsg(msg): | |
| 32 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
| 33 try: | |
| 34 sock.connect((IRKER_HOST, IRKER_PORT)) | |
| 35 sock.sendall(msg + "\n") | |
| 36 finally: | |
| 37 sock.close() | |
| 38 | |
| 39 | |
| 40 def notify_irker(db, cl, nodeid, oldvalues): | |
| 41 messages = set(cl.get(nodeid, 'messages')) | |
| 42 if oldvalues: | |
| 43 messages -= set(oldvalues.get('messages', ())) | |
| 44 if not messages: | |
| 45 return | |
| 46 messages = list(messages) | |
| 47 | |
| 48 if oldvalues: | |
| 49 oldstatus = oldvalues['status'] | |
| 50 else: | |
| 51 oldstatus = None | |
| 52 newstatus = db.issue.get(nodeid, 'status') | |
| 53 if oldstatus != newstatus: | |
| 54 if oldvalues: | |
| 55 status = db.status.get(newstatus, 'name') | |
| 56 else: | |
| 57 status = 'new' | |
| 58 log = '[' + status + '] ' | |
| 59 else: | |
| 60 log = '' | |
| 61 for msg in messages: | |
| 62 log += db.msg.get(msg, 'content') | |
| 63 if len(log) > max_content: | |
| 64 log = log[:max_content-3] + '...' | |
| 65 log = re.sub('\s+', ' ', log) | |
| 66 | |
| 67 # include irc colors | |
| 68 params = { | |
| 69 'bold': '\x02', | |
| 70 'green': '\x0303', | |
| 71 'blue': '\x0302', | |
| 72 'bluish': '\x0310', | |
| 73 'yellow': '\x0307', | |
| 74 'brown': '\x0305', | |
| 75 'reset': '\x0F' | |
| 76 } | |
| 77 # extend with values used in the template | |
| 78 params['author'] = db.user.get(db.getuid(), 'username') | |
| 79 params['nodeid'] = nodeid | |
| 80 params['title'] = db.issue.get(nodeid, 'title') | |
| 81 params['log'] = log | |
| 82 params['url'] = '%sissue%s' % (db.config.TRACKER_WEB, nodeid) | |
| 83 | |
| 84 # create the message and use the list of channels defined in | |
| 85 # detectors/config.ini | |
| 86 msg = json.dumps({ | |
| 87 'to': db.config.detectors.IRKER_CHANNELS.split(','), | |
| 88 'privmsg': TEMPLATE % params, | |
| 89 }) | |
| 90 | |
| 91 try: | |
| 92 sendmsg(msg) | |
| 93 except Exception as e: | |
| 94 # Ignore any errors in sending the irker; | |
| 95 # if the server is down, that's just bad luck | |
| 96 # XXX might want to do some logging here | |
| 97 print '* Sending message to irker failed', str(e) | |
| 98 | |
| 99 def init(db): | |
| 100 db.issue.react('create', notify_irker) | |
| 101 db.issue.react('set', notify_irker) |
