Created
December 12, 2010 11:27
-
-
Save akaihola/737989 to your computer and use it in GitHub Desktop.
Trac plugin for embedding RT tickets into the timeline
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 | |
""", | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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