Skip to content

Instantly share code, notes, and snippets.

@akaihola
Created December 12, 2010 11:27
Show Gist options
  • Save akaihola/737989 to your computer and use it in GitHub Desktop.
Save akaihola/737989 to your computer and use it in GitHub Desktop.
Trac plugin for embedding RT tickets into the timeline
This Trac plugin integrates tickets from an external RT
(RequestTracker) into the timeline.
This plugin requires the RT LogSearch extension from
https://gist.github.com/737979 installed on the RT side.
#!/usr/bin/env python
from setuptools import find_packages, setup
setup(
name='RTTicketTimeline',
description='A Trac plugin to embed ticket history from an external RT instance in the timeline',
version='0.1',
author='Antti Kaihola',
author_email='[email protected]',
license='BSD',
url='https://gist.github.com/737989',
packages=find_packages(),
entry_points = """
[trac.plugins]
rttickettimeline.web_ui = rttickettimeline.web_ui
""",
)
import cookielib
from datetime import datetime
import time
import urllib
import urllib2
from genshi.builder import tag
from trac.config import Option
from trac.core import Component, implements
from trac.timeline.api import ITimelineEventProvider
from trac.web.chrome import INavigationContributor
URI_TEMPLATE = ('%(root_url)s/REST/1.0/search/transaction/'
'?from=%(from)s&to=%(to)s&queue=%(queue)s')
cj = cookielib.LWPCookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj), urllib2.HTTPHandler(debuglevel=1))
#opener = urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1))
def get_transactions(root_url, username, password, queue, start, stop):
data = {'user': username, 'pass': password}
url = URI_TEMPLATE % {'root_url': root_url,
'from': start.strftime('%Y-%m-%d'),
'to': stop.strftime('%Y-%m-%d'),
'queue': queue}
login = urllib2.Request(url, urllib.urlencode(data))
response = opener.open(login)
for line in response:
try:
date, time, number, description = line.strip().split(' ', 3)
except ValueError:
continue
dt = datetime.strptime(date+time, '%Y-%m-%d%H:%M:%S')
yield dt, int(number[1:]), description.decode('UTF-8')
response.close()
class RTTicketTimelinePlugin(Component):
implements(ITimelineEventProvider, INavigationContributor)
queue = Option('rttickettimeline', 'queue', '', 'Name of the RT queue')
rt_url = Option('rttickettimeline', 'root_url', '', 'Root URL of the RT instance')
username = Option('rttickettimeline', 'username', '', 'Login username for the RT instance')
password = Option('rttickettimeline', 'password', '', 'Login password for the RT instance')
# Navigation Contributor
def get_active_navigation_item(self, req):
return 'rttickets'
def get_navigation_items(self, req):
ctx = {'root_url': self.rt_url, 'queue': self.queue}
url = ('%(root_url)s/Search/Results.html'
"?Query=Queue%%3D'%(queue)s'"
'&OrderBy=Status|Priority|TimeLeft'
'&Order=ASC|DESC|ASC' % ctx)
yield 'mainnav', 'rttickets', tag.a('RT Tickets', href=url)
# Timeline Event Provider
def get_timeline_filters(self, req):
yield ('rtticket', 'RT tickets')
def get_timeline_events(self, req, start, stop, filters):
transactions = get_transactions(
self.rt_url, self.username, self.password, self.queue, start, stop)
for timestamp, ticket_number, description in transactions:
words = description.split()
if words[-2] == 'by':
description = ' '.join(words[:-2])
author = words[-1]
if author == 'RT_System':
continue
else:
author = 'unknown'
yield (u'Update to #%d' % ticket_number,
time.mktime(timestamp.timetuple()),
author,
description)
def render_timeline_event(self, context, field, event):
title, timestamp, author, message = event
if field == 'title':
return title
elif field == 'description':
return message
elif field == 'url':
ticket_number = title.split('#')[-1]
return '%s/Ticket/Display.html?id=%s' % (self.rt_url, ticket_number)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment