该插件实现的功能是,当一个添加/修改/删除一个bug时,就通过jabber通知到相关感兴趣的人。该插件依赖xmpppy模块。
代码如下:
#--*-- coding: cp936 --*-- from datetime import datetime from trac.core import * from trac.ticket.api import ITicketChangeListener from trac.util.datefmt import to_timestamp, utc from trac.ticket.web_ui import TicketModule from trac.util.text import CRLF, wrap, to_unicode import trac.config import xmpp ''' 依赖于xmpppy模块 需要在trac.ini文件里做一些配置 [XmppNotify] user = "你的jabber帐号" 如[email protected] passwd = "密码" server = "IP" jabber服务器的IP port = "端口号" ''' class XmppNotify(Component): implements(ITicketChangeListener) jidparams={} COLS = 75 def __init__(self): self.config = self.env.config self.db = self.env.get_db_cnx() #从 trac.ini 获取相应信息 #获取帐号,密码 self.jidparams['jid'] = self.config.get('xmppNotify', 'user', '') self.jidparams['password'] = self.config.get('xmppNotify', 'paswd', '') #获取jabber服务器的IP, 端口 self.Server = self.config.get('xmppNotify', 'server', '') self.Port = self.config.getint('xmppNotify', 'port', 5222) self.jid = xmpp.protocol.JID(self.jidparams['jid']) self.cl=xmpp.Client(self.jid.getDomain(),debug=[]) #连接jabber服务器 self.cl.connect(server=(self.Server, self.Port)) #认证帐号,密码 self.cl.auth(self.jid.getNode(), self.jidparams['password']) #上线 self.cl.sendInitPresence() ; #获取好友列表,注意这个列表是包括自己在内的, #所以要把自己从这个列表里去除 self.roster = self.cl.getRoster() ; self.roster.Request() ; self.userlist = self.roster.getItems() self.userlist.remove( self.jidparams['jid'] ) #一个ticket被创建 def ticket_created(self, ticket): msg = self.getTicketMsg(ticket) self.send(msg) #一个ticket被修改 def ticket_changed(self, ticket, comment, author, old_values): msg = self.getTicketMsg(ticket, False, ticket.time_changed) self.send( msg ) #一个ticket被删除 def ticket_deleted(self, ticket): msg = self.getTicketMsg(ticket, False) self.send(msg) #给所有的好友发送一个消息 def send(self, msg): for item in self.userlist: self.cl.send(xmpp.Message(item, msg)) def getTicketMsg(self, ticket, newticket=True, modtime=None): ''' 根据一个 ticket 获取它的相关信息,返回一个字符串 ''' link = self.env.abs_href.ticket(ticket.id) changes_body = '' changes_descr = '' change_data = {} data = {} if not newticket and modtime : # Ticket change from trac.ticket.web_ui import TicketModule for change in TicketModule(self.env).grouped_changelog_entries( ticket, self.db, when=modtime): if not change['permanent']: # attachment with same time... continue change_data.update({ 'author': change['author'], 'comment': wrap(change['comment'], self.COLS, ' ', ' ', CRLF) }) link += '#comment:%s' % str(change.get('cnum', '')) for field, values in change['fields'].iteritems(): old = values['old'] new = values['new'] newv = '' if field == 'description': new_descr = wrap(new, self.COLS, ' ', ' ', CRLF) old_descr = wrap(old, self.COLS, '> ', '> ', CRLF) old_descr = old_descr.replace(2*CRLF, CRLF + '>' + / CRLF) cdescr = CRLF cdescr += 'Old description:' + 2*CRLF + old_descr + / 2*CRLF cdescr += 'New description:' + 2*CRLF + new_descr + / CRLF changes_descr = cdescr elif field == 'summary': summary = "%s (was: %s)" % (new, old) elif field == 'cc': (addcc, delcc) = self.diff_cc(old, new) chgcc = '' if delcc: chgcc += wrap(" * cc: %s (removed)" % ', '.join(delcc), self.COLS, ' ', ' ', CRLF) + CRLF if addcc: chgcc += wrap(" * cc: %s (added)" % ', '.join(addcc), self.COLS, ' ', ' ', CRLF) + CRLF if chgcc: changes_body += chgcc self.prev_cc += old and self.parse_cc(old) or [] else: newv = new l = 7 + len(field) chg = wrap('%s => %s' % (old, new), self.COLS - l, '', l * ' ', CRLF) changes_body += ' * %s: %s%s' % (field, chg, CRLF) if newv: change_data[field] = {'oldvalue': old, 'newvalue': new} hdr = '#%s: %s' % (ticket.id, wrap(ticket['summary'], self.COLS, linesep=CRLF)) msg = '%s /r/n %s /r/n %s /r/n %s /r/n %s /r/n %s' % (hdr, link, ticket.values, changes_body, changes_descr, change_data) return msg '''data.update({ 'ticket_body_hdr': hdr, 'ticket': ticket.values, 'changes_body': changes_body, 'changes_descr': changes_descr, 'change': change_data })'''
该插件比较简单,就没有做安装包,把上面的代码复制到一个py文件里,把这个文件放到trac实例的plugins目录下,然后启用这个插件;还要配置一下tac.ini文件就可以了:
[XmppNotify]
user = "你的jabber帐号" 如[email protected]
passwd = "密码"
server = "IP" jabber服务器的IP
port = "端口号"