Dependency Graph for Ticket #$ticket
+$headline
$depgraph
Index: depgraph/depgraph.py
===================================================================
--- depgraph/depgraph.py (Revision 4751)
+++ depgraph/depgraph.py (Arbeitskopie)
@@ -91,6 +91,34 @@
return result
+ def _depgraph_list(self, req, tickets):
+ """
+ Produces a dependency graph including all tickets from the given list
+ of ticket ids, including all blockers, even if they are not in the list.
+ """
+ result = ""
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+
+ for ticket_id in tickets:
+ sql = "SELECT id, priority, summary FROM ticket WHERE id=%s;" % ticket_id
+ cursor.execute(sql)
+ ticket = cursor.fetchall()[0]
+ bgcolor, border = get_color(str(ticket[1]).decode('ascii','ignore'))
+ result += "\"" + str(ticket[0]) + "\" [ URL=\"" \
+ + req.href.ticket(int(ticket[0])) \
+ + "\" fontcolor=\"#bb0000\" fillcolor=\"" + bgcolor \
+ + "\" color=\"" + border \
+ + "\" tooltip=\"" \
+ + ticket[2].encode('ascii', 'xmlcharrefreplace') + "\" ]\n"
+ # Use blocked_by() from mastertickets.model.TicketLinks
+ blockers = TicketLinks(self.env, int(ticket[0])).blocked_by
+ for blocker in blockers:
+# result += "\"%s\" -> \"%s\"" % (str(ticket[0]), str(blocker))
+ result += "\"%s\" -> \"%s\"" % (str(blocker), str(ticket[0]))
+
+ return result
+
def _depgraph(self, req, ticket, depth):
self.log.debug('called depgraph(%s, %s)' % (str(ticket), str(depth)))
if ticket in self._seen_tickets:
@@ -159,6 +187,8 @@
if len(options) == 0 or (len(options) > 0 and options[0] == ''):
result += self._depgraph_all(formatter.req)
+ elif (len(options) > 2 and options[0] == 'list'):
+ result += self._depgraph_list(formatter.req, options[1:])
else:
result += self._depgraph(formatter.req, int(options[0]), 0)
Index: depgraph/web_ui.py
===================================================================
--- depgraph/web_ui.py (Revision 4751)
+++ depgraph/web_ui.py (Arbeitskopie)
@@ -39,7 +39,6 @@
from trac.web.api import IRequestFilter, IRequestHandler
from trac.web.chrome import ITemplateProvider, add_ctxtnav, add_stylesheet, add_script
from trac.wiki.formatter import Formatter
-#from trac.ticket.model import Ticket
from trac.util.html import html, Markup
from depgraph import DepGraphMacro
@@ -57,12 +56,19 @@
if req.path_info.startswith('/ticket'):
ticket_id = req.path_info[8:]
add_ctxtnav(req, "Dependency Graph", req.href.depgraph(ticket_id), "Dependency Graph")
+ if req.path_info.startswith('/query'):
+ ticket_ids = 'list'
+ for ticket in data['tickets']:
+ ticket_ids += ',' + str(ticket['id'])
+ #query = 'query&' + data['query'].to_string().replace('\n&\n', '&')[7:]
+ add_ctxtnav(req, "Dependency Graph", req.href.depgraph(ticket_ids), "Dependency Graph")
+
return template, data, content_type
# IRequestHandler methods
def match_request(self, req):
- match = re.match(r'/depgraph/([0-9]+)$', req.path_info)
+ match = re.match(r'/depgraph/([0-9]+|list,.+)$', req.path_info)
if match:
req.args['id'] = match.group(1)
return True
@@ -70,30 +76,39 @@
def process_request(self, req):
req.perm.assert_permission('TICKET_VIEW')
- ticket = int(req.args.get('id'))
- db = self.env.get_db_cnx()
- cursor = db.cursor()
- cursor.execute("SELECT 1 FROM ticket WHERE id=%s" %ticket)
- row = cursor.fetchone()
- if not row:
- raise TracError('Cannot build dependency graph for non-existent ticket %d.' % ticket)
+ if req.args.get('id')[0:4] != 'list':
+ ticket = int(req.args.get('id'))
+ sql = ("SELECT 1 FROM ticket WHERE id=%s" %ticket)
+
+ db = self.env.get_db_cnx()
+ cursor = db.cursor()
+ cursor.execute(sql)
+ row = cursor.fetchone()
+ if not row:
+ raise TracError('Cannot build dependency graph for non-existent ticket %d.' % ticket)
-# req.hdf['title'] = "Ticket %s dependency graph" %ticket
+ depth = -1
+ for key in req.args.keys():
+ if key == 'depth':
+ depth = req.args[key]
- depth = -1
- for key in req.args.keys():
- if key == 'depth':
- depth = req.args[key]
+ options = '%s,%s' %(ticket, depth)
+ add_ctxtnav(req, 'Back to Ticket #%s'%ticket, req.href.ticket(ticket))
+ title = 'Ticket #%s Dependency Graph' %ticket
+ headline = 'Dependency Graph for Ticket #%s' %ticket
+ else:
+ options = req.args.get('id')
+ title = 'Ticket query Dependency Graph'
+ headline = 'Dependency Graph for Query'
data = {}
context = Context.from_request(req, '')
formatter = Formatter(self.env, context)
- graph = DepGraphMacro(self.env).expand_macro(formatter, 'DepGraph', \
- ('%s,%s' %(ticket, depth)))
- data['ticket'] = "%s" %ticket
+ graph = DepGraphMacro(self.env).expand_macro(formatter, 'DepGraph', options)
+ data['title'] = title
+ data['headline'] = headline
data['depgraph'] = Markup(graph)
- add_ctxtnav(req, 'Back to Ticket #%s'%ticket, req.href.ticket(ticket))
return 'depgraph.html', data, None
Index: depgraph/templates/depgraph.html
===================================================================
--- depgraph/templates/depgraph.html (Revision 4751)
+++ depgraph/templates/depgraph.html (Arbeitskopie)
@@ -11,11 +11,11 @@
xmlns:xi="http://www.w3.org/2001/XInclude">
$depgraph