Author: matevz
Date: Thu Aug 8 13:19:01 2013
New Revision: 1511771
URL: http://svn.apache.org/r1511771
Log:
#596 - pagination on /dashboard confused
Added:
bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py
Modified:
bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/query.py
bloodhound/trunk/bloodhound_multiproduct/multiproduct/env.py
bloodhound/trunk/bloodhound_multiproduct/multiproduct/hooks.py
bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/query.py
bloodhound/trunk/bloodhound_multiproduct/setup.py
bloodhound/trunk/bloodhound_multiproduct/tests/product-query-link-tests.txt
bloodhound/trunk/bloodhound_multiproduct/tests/wikisyntax.py
bloodhound/trunk/bloodhound_theme/bhtheme/theme.py
bloodhound/trunk/trac/trac/ticket/tests/query.py
Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/query.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/query.py?rev=1511771&r1=1511770&r2=1511771&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/query.py
(original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/query.py Thu Aug
8 13:19:01 2013
@@ -42,7 +42,6 @@ from bhdashboard.util import WidgetBase,
trac_tags
from multiproduct.env import ProductEnvironment
-from multiproduct.ticket.query import ProductQueryModule
class TicketQueryWidget(WidgetBase):
"""Display tickets matching a TracQuery using a grid
@@ -94,12 +93,11 @@ class TicketQueryWidget(WidgetBase):
more_link_href = req.href('query', args)
args.update({'page' : page, 'max': maxrows})
- qrymdl = self.env[QueryModule
- if isinstance(self.env, ProductEnvironment)
- else ProductQueryModule]
+ qrymdl = self.env[QueryModule]
if qrymdl is None :
raise TracError('Query module not available (disabled?)')
- data = qrymdl.process_request(fakereq)[1]
+
+ data = qrymdl.process_request(fakereq, self.env)[1]
except TracError, exc:
if data is not None:
exc.title = data.get('title', 'TracQuery')
Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/env.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/env.py?rev=1511771&r1=1511770&r2=1511771&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/env.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/env.py Thu Aug 8
13:19:01 2013
@@ -892,6 +892,10 @@ class ProductEnvironment(Component, Comp
# Multi-product API extensions
@classmethod
+ def lookup_global_env(cls, env):
+ return env.parent if isinstance(env, ProductEnvironment) else env
+
+ @classmethod
def lookup_env(cls, env, prefix=None, name=None):
"""Instantiate environment according to product prefix or name
Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/hooks.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/hooks.py?rev=1511771&r1=1511770&r2=1511771&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/hooks.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/hooks.py Thu Aug 8
13:19:01 2013
@@ -20,6 +20,8 @@
import multiproduct.env
import multiproduct.dbcursor
import multiproduct.versioncontrol
+import multiproduct.ticket.query
+import multiproduct.ticket.batch
import re
@@ -31,7 +33,7 @@ from trac.web.main import RequestWithSes
PRODUCT_RE = re.compile(r'^/products(?:/(?P<pid>[^/]*)(?P<pathinfo>.*))?')
REDIRECT_DEFAULT_RE = \
- re.compile(r'^/(?P<section>milestone|roadmap|query|report|newticket|'
+ re.compile(r'^/(?P<section>milestone|roadmap|report|newticket|'
r'ticket|qct|timeline|diff|batchmodify|search|'
r'(raw-|zip-)?attachment/(ticket|milestone))(?P<pathinfo>.*)')
Added: bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py?rev=1511771&view=auto
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py
(added)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py Thu
Aug 8 13:19:01 2013
@@ -0,0 +1,40 @@
+from trac.ticket.batch import BatchModifyModule
+from trac.util.translation import _
+from trac.web.chrome import add_script_data
+from multiproduct.env import ProductEnvironment
+
+
+class ProductBatchModifyModule(BatchModifyModule):
+ def add_template_data(self, req, data, tickets):
+ if isinstance(self.env, ProductEnvironment):
+ super(ProductBatchModifyModule, self).add_template_data(
+ req, data, tickets)
+ return
+
+ data['batch_modify'] = True
+ data['query_href'] = req.session['query_href'] or req.href.query()
+
+ tickets_by_product = {}
+ for t in tickets:
+ tickets_by_product.setdefault(t['product'], []).append(t)
+
+ data['action_controls'] = []
+ global_env = ProductEnvironment.lookup_global_env(self.env)
+ tmpenv = self.env
+ for k,v in tickets_by_product.iteritems():
+ self.env = ProductEnvironment(global_env, k)
+ data['action_controls'] += self._get_action_controls(req, v)
+ self.env = tmpenv
+ batch_list_modes = [
+ {'name': _("add"), 'value': "+"},
+ {'name': _("remove"), 'value': "-"},
+ {'name': _("add / remove"), 'value': "+-"},
+ {'name': _("set to"), 'value': "="},
+ ]
+ add_script_data(req, batch_list_modes=batch_list_modes,
+ batch_list_properties=self._get_list_fields())
+
+import trac.ticket.batch
+trac.ticket.batch.BatchModifyModule = ProductBatchModifyModule
+trac.ticket.BatchModifyModule = ProductBatchModifyModule
+
Modified: bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/query.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/query.py?rev=1511771&r1=1511770&r2=1511771&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/query.py
(original)
+++ bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/query.py Thu
Aug 8 13:19:01 2013
@@ -20,6 +20,8 @@
from __future__ import with_statement
+import re
+
from itertools import groupby
from math import ceil
from datetime import datetime, timedelta
@@ -52,6 +54,9 @@ class ProductQuery(Query):
"""
def _count(self, sql, args):
+ if isinstance(self.env, ProductEnvironment):
+ return super(ProductQuery, self)._count(sql, args)
+
cnt = self.env.db_direct_query("SELECT COUNT(*) FROM (%s) AS x"
% sql, args)[0][0]
# "AS x" is needed for MySQL ("Subqueries in the FROM Clause")
@@ -79,6 +84,10 @@ class ProductQuery(Query):
:since 1.0: the `db` parameter is no longer needed and will be removed
in version 1.1.1
"""
+ if isinstance(self.env, ProductEnvironment):
+ return super(ProductQuery, self).execute(req, db, cached_ids,
authname,
+ tzinfo, href, locale)
+
if req is not None:
href = req.href
with self.env.db_direct_query as db:
@@ -142,184 +151,68 @@ class ProductQuery(Query):
cursor.close()
return results
+import trac.ticket.query
+trac.ticket.query.Query = ProductQuery
+trac.ticket.Query = ProductQuery
-class ProductQueryModule(QueryModule):
- def process_request(self, req):
- req.perm.assert_permission('TICKET_VIEW')
-
- constraints = self._get_constraints(req)
- args = req.args
- if not constraints and not 'order' in req.args:
- # If no constraints are given in the URL, use the default ones.
- if req.authname and req.authname != 'anonymous':
- qstring = self.default_query
- user = req.authname
- else:
- email = req.session.get('email')
- name = req.session.get('name')
- qstring = self.default_anonymous_query
- user = email or name or None
-
- self.log.debug('QueryModule: Using default query: %s',
str(qstring))
- if qstring.startswith('?'):
- arg_list = parse_arg_list(qstring[1:])
- args = arg_list_to_args(arg_list)
- constraints = self._get_constraints(arg_list=arg_list)
- else:
- query = ProductQuery.from_string(self.env, qstring)
- args = {'order': query.order, 'group': query.group,
- 'col': query.cols, 'max': query.max}
- if query.desc:
- args['desc'] = '1'
- if query.groupdesc:
- args['groupdesc'] = '1'
- constraints = query.constraints
-
- # Substitute $USER, or ensure no field constraints that depend
- # on $USER are used if we have no username.
- for clause in constraints:
- for field, vals in clause.items():
- for (i, val) in enumerate(vals):
- if user:
- vals[i] = val.replace('$USER', user)
- elif val.endswith('$USER'):
- del clause[field]
- break
-
- cols = args.get('col')
- if isinstance(cols, basestring):
- cols = [cols]
- # Since we don't show 'id' as an option to the user,
- # we need to re-insert it here.
- if cols and 'id' not in cols:
- cols.insert(0, 'id')
- rows = args.get('row', [])
- if isinstance(rows, basestring):
- rows = [rows]
- format = req.args.get('format')
- max = args.get('max')
- if max is None and format in ('csv', 'tab'):
- max = 0 # unlimited unless specified explicitly
- query = ProductQuery(self.env, req.args.get('report'),
- constraints, cols, args.get('order'),
- 'desc' in args, args.get('group'),
- 'groupdesc' in args, 'verbose' in args,
- rows,
- args.get('page'),
- max)
-
- if 'update' in req.args:
- # Reset session vars
- for var in ('query_constraints', 'query_time', 'query_tickets'):
- if var in req.session:
- del req.session[var]
- req.redirect(query.get_href(req.href))
-
- # Add registered converters
- for conversion in Mimeview(self.env).get_supported_conversions(
- 'trac.ticket.Query'):
- add_link(req, 'alternate',
- query.get_href(req.href, format=conversion[0]),
- conversion[1], conversion[4], conversion[0])
-
- if format:
- filename = 'query' if format != 'rss' else None
- Mimeview(self.env).send_converted(req, 'trac.ticket.Query', query,
- format, filename=filename)
-
- return self.display_html(req, query)
-
- def display_html(self, req, query):
- # The most recent query is stored in the user session;
- orig_list = None
- orig_time = datetime.now(utc)
- query_time = int(req.session.get('query_time', 0))
- query_time = datetime.fromtimestamp(query_time, utc)
- query_constraints = unicode(query.constraints)
- try:
- if query_constraints != req.session.get('query_constraints') \
- or query_time < orig_time - timedelta(hours=1):
- tickets = query.execute(req)
- # New or outdated query, (re-)initialize session vars
- req.session['query_constraints'] = query_constraints
- req.session['query_tickets'] = ' '.join([str(t['id'])
- for t in tickets])
- else:
- orig_list = [int(id) for id
- in req.session.get('query_tickets', '').split()]
- tickets = query.execute(req, cached_ids=orig_list)
- orig_time = query_time
- except QueryValueError, e:
- tickets = []
- for error in e.errors:
- add_warning(req, error)
-
- context = web_context(req, 'query')
- owner_field = [f for f in query.fields if f['name'] == 'owner']
- if owner_field:
- TicketSystem(self.env).eventually_restrict_owner(owner_field[0])
- data = query.template_data(context, tickets, orig_list, orig_time, req)
-
- req.session['query_href'] = query.get_href(context.href)
- req.session['query_time'] = to_timestamp(orig_time)
- req.session['query_tickets'] = ' '.join([str(t['id'])
- for t in tickets])
- title = _('Custom Query')
-
- # Only interact with the report module if it is actually enabled.
- #
- # Note that with saved custom queries, there will be some convergence
- # between the report module and the query module.
- from trac.ticket.report import ReportModule
- if 'REPORT_VIEW' in req.perm and \
- self.env.is_component_enabled(ReportModule):
- data['report_href'] = req.href.report()
- add_ctxtnav(req, _('Available Reports'), req.href.report())
- add_ctxtnav(req, _('Custom Query'), req.href.query())
- if query.id:
- for title, description in self.env.db_query("""
- SELECT title, description FROM report WHERE id=%s
- """, (query.id,)):
- data['report_resource'] = Resource('report', query.id)
- data['description'] = description
- else:
- data['report_href'] = None
- # Only interact with the batch modify module it it is enabled
- # TODO: fix this for multiproduct
- """
- from trac.ticket.batch import BatchModifyModule
- if 'TICKET_BATCH_MODIFY' in req.perm and \
- self.env.is_component_enabled(BatchModifyModule):
- self.env[BatchModifyModule].add_template_data(req, data, tickets)
- """
-
- data.setdefault('report', None)
- data.setdefault('description', None)
- data['title'] = title
-
- data['all_columns'] = query.get_all_columns()
- # Don't allow the user to remove the id column
- data['all_columns'].remove('id')
- data['all_textareas'] = query.get_all_textareas()
-
- properties = dict((name, dict((key, field[key])
- for key in ('type', 'label', 'options',
- 'optgroups')
- if key in field))
- for name, field in data['fields'].iteritems())
- add_script_data(req, properties=properties, modes=data['modes'])
-
- add_stylesheet(req, 'common/css/report.css')
- Chrome(self.env).add_jquery_ui(req)
- add_script(req, 'common/js/query.js')
+class ProductQueryModule(QueryModule):
+ def process_request(self, req, env=None):
+ tmpenv = self.env
+ if isinstance(self.env, ProductEnvironment) and env is not None:
+ self.env = env
+ result = super(ProductQueryModule, self).process_request(req)
+ self.env = tmpenv
+ return result
- return 'query.html', data, None
+trac.ticket.query.QueryModule = ProductQueryModule
+trac.ticket.QueryModule = ProductQueryModule
class ProductTicketQueryMacro(TicketQueryMacro):
"""TracQuery macro retrieving results across product boundaries.
"""
+ @staticmethod
+ def parse_args(content):
+ """Parse macro arguments and translate them to a query string."""
+ clauses = [{}]
+ argv = []
+ kwargs = {}
+ for arg in TicketQueryMacro._comma_splitter.split(content):
+ arg = arg.replace(r'\,', ',')
+ m = re.match(r'\s*[^=]+=', arg)
+ if m:
+ kw = arg[:m.end() - 1].strip()
+ value = arg[m.end():]
+ if kw in ('order', 'max', 'format', 'col', 'product'):
+ kwargs[kw] = value
+ else:
+ clauses[-1][kw] = value
+ elif arg.strip() == 'or':
+ clauses.append({})
+ else:
+ argv.append(arg)
+ clauses = filter(None, clauses)
+
+ if len(argv) > 0 and not 'format' in kwargs: # 0.10 compatibility hack
+ kwargs['format'] = argv[0]
+ if 'order' not in kwargs:
+ kwargs['order'] = 'id'
+ if 'max' not in kwargs:
+ kwargs['max'] = '0' # unlimited by default
+
+ format = kwargs.pop('format', 'list').strip().lower()
+ if format in ('list', 'compact'): # we need 'status' and 'summary'
+ if 'col' in kwargs:
+ kwargs['col'] = 'status|summary|' + kwargs['col']
+ else:
+ kwargs['col'] = 'status|summary'
+
+ query_string = '&or&'.join('&'.join('%s=%s' % item
+ for item in clause.iteritems())
+ for clause in clauses)
+ return query_string, kwargs, format
+
def expand_macro(self, formatter, name, content):
req = formatter.req
query_string, kwargs, format = self.parse_args(content)
@@ -327,7 +220,9 @@ class ProductTicketQueryMacro(TicketQuer
query_string += '&'
query_string += '&'.join('%s=%s' % item
for item in kwargs.iteritems())
- query = ProductQuery.from_string(self.env, query_string)
+
+ env = ProductEnvironment.lookup_global_env(self.env)
+ query = ProductQuery.from_string(env, query_string)
if format == 'count':
cnt = query.count(req)
@@ -342,7 +237,7 @@ class ProductTicketQueryMacro(TicketQuer
add_stylesheet(req, 'common/css/report.css')
- return Chrome(self.env).render_template(
+ return Chrome(env).render_template(
req, 'query_results.html', data, None, fragment=True)
if format == 'progress':
@@ -354,7 +249,7 @@ class ProductTicketQueryMacro(TicketQuer
add_stylesheet(req, 'common/css/roadmap.css')
def query_href(extra_args, group_value = None):
- q = Query.from_string(self.env, query_string)
+ q = ProductQuery.from_string(env, query_string)
if q.group:
extra_args[q.group] = group_value
q.group = None
@@ -363,9 +258,9 @@ class ProductTicketQueryMacro(TicketQuer
if not q.constraints:
q.constraints.append(extra_args)
return q.get_href(formatter.context)
- chrome = Chrome(self.env)
- tickets = apply_ticket_permissions(self.env, req, tickets)
- stats_provider = RoadmapModule(self.env).stats_provider
+ chrome = Chrome(env)
+ tickets = apply_ticket_permissions(env, req, tickets)
+ stats_provider = RoadmapModule(env).stats_provider
by = query.group
if not by:
stat = get_ticket_stats(stats_provider, tickets)
@@ -393,7 +288,7 @@ class ProductTicketQueryMacro(TicketQuer
'legend': False,
}
- groups = grouped_stats_data(self.env, stats_provider, tickets, by,
+ groups = grouped_stats_data(env, stats_provider, tickets, by,
per_group_stats_data)
data = {
'groups': groups, 'grouped_by': by,
@@ -438,7 +333,7 @@ class ProductTicketQueryMacro(TicketQuer
def ticket_groups():
groups = []
for v, g in groupby(tickets, lambda t: t[query.group]):
- q = Query.from_string(self.env, query_string)
+ q = ProductQuery.from_string(env, query_string)
# produce the hint for the group
q.group = q.groupdesc = None
order = q.order
Modified: bloodhound/trunk/bloodhound_multiproduct/setup.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/setup.py?rev=1511771&r1=1511770&r2=1511771&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/setup.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/setup.py Thu Aug 8 13:19:01 2013
@@ -17,10 +17,22 @@
# under the License.
"""setup for multi product plugin"""
-import sys
+import sys, codecs
from pkg_resources import parse_version
from setuptools import setup
+
+# Force UTF-8 for stdout/err if --utf8 option is specified.
+# For some reason python doesn't obey LANG/LC_CTYPE settings
+# if output is not a terminal (e.g. pipes don't work).
+if __name__ == '__main__':
+ for ac,av in enumerate(sys.argv):
+ if av == '--utf8':
+ sys.stdout = codecs.getwriter('utf8')(sys.stdout)
+ sys.stderr = codecs.getwriter('utf8')(sys.stderr)
+ del sys.argv[ac]
+ break
+
setup(
name = 'BloodhoundMultiProduct',
version = '0.7.0',
Modified:
bloodhound/trunk/bloodhound_multiproduct/tests/product-query-link-tests.txt
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/tests/product-query-link-tests.txt?rev=1511771&r1=1511770&r2=1511771&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/tests/product-query-link-tests.txt
(original)
+++ bloodhound/trunk/bloodhound_multiproduct/tests/product-query-link-tests.txt
Thu Aug 8 13:19:01 2013
@@ -52,7 +52,7 @@
============================== %(tc_title_prefix)s - ProductTicketQuery macro:
no results, list form
Reopened tickets: [[ProductTicketQuery(status=reopened)]]
-Reopened tickets: [[ProductTicketQuery(status=reopened,
product=%(setup_product_name)s)]]
+Reopened tickets: [[ProductTicketQuery(status=reopened,
product=%(setup_product)s)]]
------------------------------
<p>
Reopened tickets: <span class="query_no_results">No results</span>
@@ -64,19 +64,19 @@ Reopened tickets: <span class="query_no_
============================== %(tc_title_prefix)s - ProductTicketQuery macro:
no results, count 0
Reopened tickets: [[ProductTicketQuery(status=reopened, format=count)]]
-Reopened tickets: [[ProductTicketQuery(status=reopened, format=count,
product=%(setup_product_name)s)]]
+Reopened tickets: [[ProductTicketQuery(status=reopened, format=count,
product=%(setup_product)s)]]
------------------------------
<p>
Reopened tickets: <span class="query_count" title="0 tickets for which
status=reopened&max=0&order=id">0</span>
</p>
<p>
-Reopened tickets: <span class="query_count" title="0 tickets for which
status=reopened&product=%(setup_product_name)s&max=0&order=id">0</span>
+Reopened tickets: <span class="query_count" title="0 tickets for which
status=reopened&max=0&product=%(setup_product)s&order=id">0</span>
</p>
------------------------------
============================== %(tc_title_prefix)s - ProductTicketQuery macro:
no results, compact form
Reopened tickets: [[ProductTicketQuery(status=reopened, format=compact)]]
-Reopened tickets: [[ProductTicketQuery(status=reopened, format=compact,
product=%(setup_product_name)s)]]
+Reopened tickets: [[ProductTicketQuery(status=reopened, format=compact,
product=%(setup_product)s)]]
------------------------------
<p>
Reopened tickets: <span class="query_no_results">No results</span>
@@ -88,7 +88,7 @@ Reopened tickets: <span class="query_no_
============================== %(tc_title_prefix)s - ProductTicketQuery macro:
one result, list form
New tickets: [[ProductTicketQuery(status=new)]]
-New tickets: [[ProductTicketQuery(status=new, product=%(setup_product_name)s)]]
+New tickets: [[ProductTicketQuery(status=new, product=%(setup_product)s)]]
------------------------------
<p>
New tickets: </p><div><dl class="wiki compact"><dt><a class="new"
href="%(path_prefix)s/ticket/1" title="This is the summary">#1</a></dt><dd>This
is the summary</dd></dl></div><p>
@@ -100,19 +100,19 @@ New tickets: </p><div><dl class="wiki co
============================== %(tc_title_prefix)s - ProductTicketQuery macro:
one result, count 1
New tickets: [[ProductTicketQuery(status=new, format=count)]]
-New tickets: [[ProductTicketQuery(status=new, format=count,
product=%(setup_product_name)s)]]
+New tickets: [[ProductTicketQuery(status=new, format=count,
product=%(setup_product)s)]]
------------------------------
<p>
New tickets: <span class="query_count" title="1 tickets for which
status=new&max=0&order=id">1</span>
</p>
<p>
-New tickets: <span class="query_count" title="1 tickets for which
status=new&product=%(setup_product_name)s&max=0&order=id">1</span>
+New tickets: <span class="query_count" title="1 tickets for which
status=new&max=0&product=%(setup_product)s&order=id">1</span>
</p>
------------------------------
============================== %(tc_title_prefix)s - ProductTicketQuery macro:
one result, compact form
New tickets: [[ProductTicketQuery(status=new, format=compact)]]
-New tickets: [[ProductTicketQuery(status=new, format=compact,
product=%(setup_product_name)s)]]
+New tickets: [[ProductTicketQuery(status=new, format=compact,
product=%(setup_product)s)]]
------------------------------
<p>
New tickets: <span><a class="new" href="%(path_prefix)s/ticket/1" title="This
is the summary">#1</a></span>
Modified: bloodhound/trunk/bloodhound_multiproduct/tests/wikisyntax.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_multiproduct/tests/wikisyntax.py?rev=1511771&r1=1511770&r2=1511771&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_multiproduct/tests/wikisyntax.py (original)
+++ bloodhound/trunk/bloodhound_multiproduct/tests/wikisyntax.py Thu Aug 8
13:19:01 2013
@@ -65,7 +65,7 @@ def ticket_setup(tc):
'status': 'new'})
# FIXME : UGLY ! Should not be explicit for product environments
- ticket['product'] = (tc.env.product.name
+ ticket['product'] = (tc.env.product.prefix
if isinstance(tc.env, ProductEnvironment)
else '')
Modified: bloodhound/trunk/bloodhound_theme/bhtheme/theme.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_theme/bhtheme/theme.py?rev=1511771&r1=1511770&r2=1511771&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_theme/bhtheme/theme.py (original)
+++ bloodhound/trunk/bloodhound_theme/bhtheme/theme.py Thu Aug 8 13:19:01 2013
@@ -430,7 +430,8 @@ class BloodhoundTheme(ThemeBase):
def _add_products_general_breadcrumb(self, req, template, data,
content_type, is_active):
- data['resourcepath_template'] = 'bh_path_general.html'
+ if isinstance(req.perm.env, ProductEnvironment):
+ data['resourcepath_template'] = 'bh_path_general.html'
# INavigationContributor methods
Modified: bloodhound/trunk/trac/trac/ticket/tests/query.py
URL:
http://svn.apache.org/viewvc/bloodhound/trunk/trac/trac/ticket/tests/query.py?rev=1511771&r1=1511770&r2=1511771&view=diff
==============================================================================
--- bloodhound/trunk/trac/trac/ticket/tests/query.py (original)
+++ bloodhound/trunk/trac/trac/ticket/tests/query.py Thu Aug 8 13:19:01 2013
@@ -110,7 +110,7 @@ ORDER BY COALESCE(priority.value,'')=''
query = Query(self.env, order='version')
sql, args = query.get_sql()
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS
type,t.status AS status,t.priority AS priority,t.version AS version,t.time AS
time,t.changetime AS changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.version AS
version,t.time AS time,t.changetime AS changetime,priority.value AS
priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
LEFT OUTER JOIN version ON (version.name=version)
@@ -122,7 +122,7 @@ ORDER BY COALESCE(t.version,'')='',COALE
query = Query(self.env, order='version', desc=1)
sql, args = query.get_sql()
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS
type,t.status AS status,t.priority AS priority,t.version AS version,t.time AS
time,t.changetime AS changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.version AS
version,t.time AS time,t.changetime AS changetime,priority.value AS
priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
LEFT OUTER JOIN version ON (version.name=version)
@@ -134,7 +134,7 @@ ORDER BY COALESCE(t.version,'')='' DESC,
query = Query.from_string(self.env, 'milestone=milestone1', order='id')
sql, args = query.get_sql()
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS
type,t.status AS status,t.priority AS priority,t.component AS component,t.time
AS time,t.changetime AS changetime,t.milestone AS milestone,priority.value AS
priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.component AS
component,t.time AS time,t.changetime AS changetime,t.milestone AS
milestone,priority.value AS priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
WHERE ((COALESCE(t.milestone,'')=%s))
@@ -146,7 +146,7 @@ ORDER BY COALESCE(t.id,0)=0,t.id""")
query = Query(self.env, order='id', group='milestone')
sql, args = query.get_sql()
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS
type,t.status AS status,t.priority AS priority,t.component AS
component,t.milestone AS milestone,t.time AS time,t.changetime AS
changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.component AS
component,t.milestone AS milestone,t.time AS time,t.changetime AS
changetime,priority.value AS priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
LEFT OUTER JOIN milestone ON (milestone.name=milestone)
@@ -158,7 +158,7 @@ ORDER BY COALESCE(t.milestone,'')='',COA
query = Query(self.env, order='id', group='milestone', groupdesc=1)
sql, args = query.get_sql()
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS
type,t.status AS status,t.priority AS priority,t.component AS
component,t.milestone AS milestone,t.time AS time,t.changetime AS
changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.component AS
component,t.milestone AS milestone,t.time AS time,t.changetime AS
changetime,priority.value AS priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
LEFT OUTER JOIN milestone ON (milestone.name=milestone)
@@ -170,7 +170,7 @@ ORDER BY COALESCE(t.milestone,'')='' DES
query = Query(self.env, group='priority')
sql, args = query.get_sql()
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS
type,t.status AS status,t.milestone AS milestone,t.component AS
component,t.priority AS priority,t.time AS time,t.changetime AS
changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.owner AS
owner,t.type AS type,t.status AS status,t.milestone AS milestone,t.component AS
component,t.priority AS priority,t.time AS time,t.changetime AS
changetime,priority.value AS priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
ORDER BY COALESCE(priority.value,'')='',%(cast_priority)s,t.id""" % {
@@ -182,7 +182,7 @@ ORDER BY COALESCE(priority.value,'')='',
query = Query.from_string(self.env, 'milestone!=milestone1',
order='id')
sql, args = query.get_sql()
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.milestone AS milestone,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.time AS
time,t.changetime AS changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.milestone AS
milestone,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS
priority,t.time AS time,t.changetime AS changetime,priority.value AS
priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
WHERE ((COALESCE(t.milestone,'')!=%s))
@@ -357,7 +357,7 @@ ORDER BY COALESCE(t.id,0)=0,t.id""")
query = Query.from_string(self.env, 'created=2008-08-01..2008-09-01',
order='id')
sql, args = query.get_sql(self.req)
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.time AS time,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.changetime AS
changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.time AS
time,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS
priority,t.changetime AS changetime,priority.value AS priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
WHERE (((%(cast_time)s>=%%s AND %(cast_time)s<%%s)))
@@ -370,7 +370,7 @@ ORDER BY COALESCE(t.id,0)=0,t.id""" % {
query = Query.from_string(self.env, 'created!=2008-08-01..2008-09-01',
order='id')
sql, args = query.get_sql(self.req)
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.time AS time,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.changetime AS
changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.time AS
time,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS
priority,t.changetime AS changetime,priority.value AS priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
WHERE ((NOT (%(cast_time)s>=%%s AND %(cast_time)s<%%s)))
@@ -383,7 +383,7 @@ ORDER BY COALESCE(t.id,0)=0,t.id""" % {
query = Query.from_string(self.env, 'created=2008-08-01..', order='id')
sql, args = query.get_sql(self.req)
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.time AS time,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.changetime AS
changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.time AS
time,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS
priority,t.changetime AS changetime,priority.value AS priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
WHERE ((%(cast_time)s>=%%s))
@@ -396,7 +396,7 @@ ORDER BY COALESCE(t.id,0)=0,t.id""" % {
query = Query.from_string(self.env, 'created=..2008-09-01', order='id')
sql, args = query.get_sql(self.req)
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.time AS time,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.changetime AS
changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.time AS
time,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS
priority,t.changetime AS changetime,priority.value AS priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
WHERE ((%(cast_time)s<%%s))
@@ -409,7 +409,7 @@ ORDER BY COALESCE(t.id,0)=0,t.id""" % {
query = Query.from_string(self.env, 'modified=2008-08-01..2008-09-01',
order='id')
sql, args = query.get_sql(self.req)
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.changetime AS changetime,t.owner
AS owner,t.type AS type,t.status AS status,t.priority AS priority,t.time AS
time,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.changetime AS
changetime,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS
priority,t.time AS time,priority.value AS priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
WHERE (((%(cast_changetime)s>=%%s AND %(cast_changetime)s<%%s)))
@@ -423,7 +423,7 @@ ORDER BY COALESCE(t.id,0)=0,t.id""" % {
order='id')
sql, args = query.get_sql()
self.assertEqualSQL(sql,
-"""SELECT t.id AS id,t.summary AS summary,t.keywords AS keywords,t.owner AS
owner,t.type AS type,t.status AS status,t.priority AS priority,t.time AS
time,t.changetime AS changetime,priority.value AS priority_value
+"""SELECT t.product AS product,t.id AS id,t.summary AS summary,t.keywords AS
keywords,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS
priority,t.time AS time,t.changetime AS changetime,priority.value AS
priority_value
FROM ticket AS t
LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND
priority.name=priority)
WHERE (((COALESCE(t.keywords,'') %(like)s AND COALESCE(t.keywords,'') NOT
%(like)s AND COALESCE(t.keywords,'') %(like)s)))