Part of Slepp's ProjectsPastebinTURLImagebinFilebin
Feedback -- English French German Japanese
Create Upload Newest Tools Donate
Sign In | Create Account

Diff
Saturday, November 11th, 2006 at 3:35:37pm MST 

  1. Index: trac/ticket/query.py
  2. ===================================================================
  3. --- trac/ticket/query.py        (revision 4209)
  4. +++ trac/ticket/query.py        (working copy)
  5. @@ -20,6 +20,7 @@
  6.  from StringIO import StringIO
  7.  
  8.  from trac.core import *
  9. +from trac.config import ListOption
  10.  from trac.db import get_column_names
  11.  from trac.mimeview.api import Mimeview, IContentConverter
  12.  from trac.perm import IPermissionRequestor
  13. @@ -42,7 +43,7 @@
  14.  class Query(object):
  15.  
  16.      def __init__(self, env, constraints=None, order=None, desc=0, group=None,
  17. -                 groupdesc = 0, verbose=0):
  18. +                 groupdesc = 0, verbose=0, columns=None):
  19.          self.env = env
  20.          self.constraints = constraints or {}
  21.          self.order = order
  22. @@ -51,10 +52,12 @@
  23.          self.groupdesc = groupdesc
  24.          self.verbose = verbose
  25.          self.fields = TicketSystem(self.env).get_ticket_fields()
  26. -        self.cols = [] # lazily initialized
  27. +        self.cols = columns # lazily initialized if empty
  28.  
  29. -        if self.order != 'id' \
  30. -                and self.order not in [f['name'] for f in self.fields]:
  31. +        self.valid_cols = ['id', 'changetime', 'time'] + \
  32. +                          [f['name'] for f in self.fields]
  33. +
  34. +        if self.order not in self.valid_cols:
  35.              # order by priority by default
  36.              self.order = 'priority'
  37.  
  38. @@ -94,6 +97,8 @@
  39.                      kw[field] = processed_values[0]
  40.                  elif field in kw_bools:
  41.                      kw[field] = True
  42. +                elif field == 'columns':
  43. +                    kw[field] = processed_values[0].split(',')
  44.                  else:
  45.                      constraints[field] = processed_values
  46.              except UnicodeError:
  47. @@ -108,7 +113,14 @@
  48.          # FIXME: the user should be able to configure which columns should
  49.          # be displayed
  50.          cols = ['id']
  51. -        cols += [f['name'] for f in self.fields if f['type'] != 'textarea']
  52. +        cols += [f['name'] for f in self.fields if f['type'] != 'textarea'
  53. +                 and f['name'] not in cols]
  54. +        default_columns = QueryModule(self.env).default_columns
  55. +        for col in default_columns:
  56. +            if col not in cols:
  57. +                cols.append(col)
  58. +        # Filter out invalid column names from config or URL
  59. +        cols = [c for c in cols if c in self.valid_cols]
  60.          for col in ('reporter', 'keywords', 'cc'):
  61.              if col in cols:
  62.                  cols.remove(col)
  63. @@ -139,6 +151,8 @@
  64.              # Constrained columns appear before other columns
  65.              elif col1 in constrained_fields or col2 in constrained_fields:
  66.                  return col1 in constrained_fields and -1 or 1
  67. +            elif col1 in default_columns or col2 in default_columns:
  68. +                return col1 in default_columns and -1 or 1
  69.              return 0
  70.          cols.sort(sort_columns)
  71.  
  72. @@ -168,7 +182,7 @@
  73.          for row in cursor:
  74.              id = int(row[0])
  75.              result = {'id': id, 'href': req.href.ticket(id)}
  76. -            for i in range(1, len(columns)):
  77. +            for i in xrange(1, len(columns)):
  78.                  name, val = columns[i], row[i]
  79.                  if name == self.group:
  80.                      val = val or 'None'
  81. @@ -369,6 +383,8 @@
  82.  
  83.          cols = self.get_columns()
  84.          labels = dict([(f['name'], f['label']) for f in self.fields])
  85. +        labels['changetime'] = 'Modified'
  86. +        labels['time'] = 'Created'
  87.          headers = [{
  88.              'name': col, 'label': labels.get(col, 'Ticket'),
  89.              'href': self.get_href(req, order=col, desc=(col == self.order and
  90. @@ -429,6 +445,9 @@
  91.      implements(IRequestHandler, INavigationContributor, IWikiSyntaxProvider,
  92.                 IContentConverter)
  93.  
  94. +    _default_columns = ListOption('ticket-query', 'default_columns', 'id',
  95. +                                  keep_empty=False)
  96. +
  97.      # IContentConverter methods
  98.      def get_supported_conversions(self):
  99.          yield ('rss', 'RSS Feed', 'xml',
  100. @@ -480,10 +499,13 @@
  101.                  if email or name:
  102.                      constraints['cc'] = ('~%s' % email or name,)
  103.  
  104. +        columns = [c.strip() for c in req.args.get('columns', '').split(',')
  105. +                   if c.strip()]
  106.          query = Query(self.env, constraints, req.args.get('order'),
  107.                        req.args.has_key('desc'), req.args.get('group'),
  108.                        req.args.has_key('groupdesc'),
  109. -                      req.args.has_key('verbose'))
  110. +                      req.args.has_key('verbose'),
  111. +                      self.expand_aliases(columns))
  112.  
  113.          if req.args.has_key('update'):
  114.              # Reset session vars
  115. @@ -506,6 +528,24 @@
  116.  
  117.          return self.display_html(req, query)
  118.  
  119. +    def expand_aliases(self, cols, aliases=None):
  120. +        if aliases is None:
  121. +            section = self.config['ticket-query-column-aliases']
  122. +            aliases = {}
  123. +            for key in section:
  124. +                aliases[key] = section.getlist(key, keep_empty=False)
  125. +        expanded = []
  126. +        for c in cols:
  127. +            if c in aliases:
  128. +                expanded.extend(self.expand_aliases(aliases[c], aliases))
  129. +            else:
  130. +                expanded.append(c)
  131. +        return expanded
  132. +
  133. +    def default_columns(self):
  134. +        return self.expand_aliases(self._default_columns)
  135. +    default_columns = property(default_columns)
  136. +
  137.      # Internal methods
  138.  
  139.      def _get_constraints(self, req):
  140. Index: templates/query_div.html
  141. ===================================================================
  142. --- templates/query_div.html    (revision 4209)
  143. +++ templates/query_div.html    (working copy)
  144. @@ -48,6 +48,7 @@
  145.                <td py:when="idx == 0" class="id"><a href="$result.href" title="View ticket">#$result.id</a></td>
  146.                <td py:otherwise="" class="$header.name" py:choose="">
  147.                  <a py:when="header.name == 'summary'" href="$result.href" title="View ticket">$result.summary</a>
  148. +                <span py:when="header.name in ('time', 'changetime')">${format_datetime(result[header.name])}</span>
  149.                  <span py:otherwise="">${result[header.name]}</span>
  150.                </td>
  151.              </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.

update paste below
details of the post (optional)

Note: Only the paste content is required, though the following information can be useful to others.

Save name / title?

(space separated, optional)



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.

worth-right