- Diff
- Saturday, November 11th, 2006 at 3:35:37pm MST
- Index: trac/ticket/query.py
- ===================================================================
- --- trac/ticket/query.py (revision 4209)
- +++ trac/ticket/query.py (working copy)
- @@ -20,6 +20,7 @@
- from StringIO import StringIO
- from trac.core import *
- +from trac.config import ListOption
- from trac.db import get_column_names
- from trac.mimeview.api import Mimeview, IContentConverter
- from trac.perm import IPermissionRequestor
- @@ -42,7 +43,7 @@
- class Query(object):
- def __init__(self, env, constraints=None, order=None, desc=0, group=None,
- - groupdesc = 0, verbose=0):
- + groupdesc = 0, verbose=0, columns=None):
- self.env = env
- self.constraints = constraints or {}
- self.order = order
- @@ -51,10 +52,12 @@
- self.groupdesc = groupdesc
- self.verbose = verbose
- self.fields = TicketSystem(self.env).get_ticket_fields()
- - self.cols = [] # lazily initialized
- + self.cols = columns # lazily initialized if empty
- - if self.order != 'id' \
- - and self.order not in [f['name'] for f in self.fields]:
- + self.valid_cols = ['id', 'changetime', 'time'] + \
- + [f['name'] for f in self.fields]
- +
- + if self.order not in self.valid_cols:
- # order by priority by default
- self.order = 'priority'
- @@ -94,6 +97,8 @@
- kw[field] = processed_values[0]
- elif field in kw_bools:
- kw[field] = True
- + elif field == 'columns':
- + kw[field] = processed_values[0].split(',')
- else:
- constraints[field] = processed_values
- except UnicodeError:
- @@ -108,7 +113,14 @@
- # FIXME: the user should be able to configure which columns should
- # be displayed
- cols = ['id']
- - cols += [f['name'] for f in self.fields if f['type'] != 'textarea']
- + cols += [f['name'] for f in self.fields if f['type'] != 'textarea'
- + and f['name'] not in cols]
- + default_columns = QueryModule(self.env).default_columns
- + for col in default_columns:
- + if col not in cols:
- + cols.append(col)
- + # Filter out invalid column names from config or URL
- + cols = [c for c in cols if c in self.valid_cols]
- for col in ('reporter', 'keywords', 'cc'):
- if col in cols:
- cols.remove(col)
- @@ -139,6 +151,8 @@
- # Constrained columns appear before other columns
- elif col1 in constrained_fields or col2 in constrained_fields:
- return col1 in constrained_fields and -1 or 1
- + elif col1 in default_columns or col2 in default_columns:
- + return col1 in default_columns and -1 or 1
- return 0
- cols.sort(sort_columns)
- @@ -168,7 +182,7 @@
- for row in cursor:
- id = int(row[0])
- result = {'id': id, 'href': req.href.ticket(id)}
- - for i in range(1, len(columns)):
- + for i in xrange(1, len(columns)):
- name, val = columns[i], row[i]
- if name == self.group:
- val = val or 'None'
- @@ -369,6 +383,8 @@
- cols = self.get_columns()
- labels = dict([(f['name'], f['label']) for f in self.fields])
- + labels['changetime'] = 'Modified'
- + labels['time'] = 'Created'
- headers = [{
- 'name': col, 'label': labels.get(col, 'Ticket'),
- 'href': self.get_href(req, order=col, desc=(col == self.order and
- @@ -429,6 +445,9 @@
- implements(IRequestHandler, INavigationContributor, IWikiSyntaxProvider,
- IContentConverter)
- + _default_columns = ListOption('ticket-query', 'default_columns', 'id',
- + keep_empty=False)
- +
- # IContentConverter methods
- def get_supported_conversions(self):
- yield ('rss', 'RSS Feed', 'xml',
- @@ -480,10 +499,13 @@
- if email or name:
- constraints['cc'] = ('~%s' % email or name,)
- + columns = [c.strip() for c in req.args.get('columns', '').split(',')
- + if c.strip()]
- query = Query(self.env, constraints, req.args.get('order'),
- req.args.has_key('desc'), req.args.get('group'),
- req.args.has_key('groupdesc'),
- - req.args.has_key('verbose'))
- + req.args.has_key('verbose'),
- + self.expand_aliases(columns))
- if req.args.has_key('update'):
- # Reset session vars
- @@ -506,6 +528,24 @@
- return self.display_html(req, query)
- + def expand_aliases(self, cols, aliases=None):
- + if aliases is None:
- + section = self.config['ticket-query-column-aliases']
- + aliases = {}
- + for key in section:
- + aliases[key] = section.getlist(key, keep_empty=False)
- + expanded = []
- + for c in cols:
- + if c in aliases:
- + expanded.extend(self.expand_aliases(aliases[c], aliases))
- + else:
- + expanded.append(c)
- + return expanded
- +
- + def default_columns(self):
- + return self.expand_aliases(self._default_columns)
- + default_columns = property(default_columns)
- +
- # Internal methods
- def _get_constraints(self, req):
- Index: templates/query_div.html
- ===================================================================
- --- templates/query_div.html (revision 4209)
- +++ templates/query_div.html (working copy)
- @@ -48,6 +48,7 @@
- <td py:when="idx == 0" class="id"><a href="$result.href" title="View ticket">#$result.id</a></td>
- <td py:otherwise="" class="$header.name" py:choose="">
- <a py:when="header.name == 'summary'" href="$result.href" title="View ticket">$result.summary</a>
- + <span py:when="header.name in ('time', 'changetime')">${format_datetime(result[header.name])}</span>
- <span py:otherwise="">${result[header.name]}</span>
- </td>
- </py:for>
advertising
Update the Post
Either update this post and resubmit it with changes, or make a new post.
You may also comment on this post.
Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.