svn commit: r1460314 - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_dashboard/bhdashboard/widgets/ bloodhound_search/ bloodhound_search/bhsearch/templates/ bloodhound_theme/b
Author: jure Date: Sun Mar 24 11:28:08 2013 New Revision: 1460314 URL: http://svn.apache.org/r1460314 Log: Sync merge from trunk Modified: incubator/bloodhound/branches/bep_0003_multiproduct/ (props changed) incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/widgets/timeline.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/templates/bhsearch.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/htdocs/bloodhound.css incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bloodhound_theme.html Propchange: incubator/bloodhound/branches/bep_0003_multiproduct/ -- Merged /incubator/bloodhound/trunk:r1458693-1460312 Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/widgets/timeline.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/widgets/timeline.py?rev=1460314r1=1460313r2=1460314view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/widgets/timeline.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/widgets/timeline.py Sun Mar 24 11:28:08 2013 @@ -37,6 +37,8 @@ from trac.resource import Resource, reso from trac.timeline.web_ui import TimelineModule from trac.ticket.api import TicketSystem from trac.ticket.model import Ticket +from trac.ticket.web_ui import TicketModule +from trac.util.datefmt import utc from trac.util.translation import _ from trac.web.chrome import add_stylesheet @@ -145,6 +147,15 @@ class TimelineWidget(WidgetBase): 'max', 'realm', 'id') start, days, user, precision, filters, count, realm, rid = \ self.bind_params(name, options, *params) +if context.resource.realm == 'ticket': +if days is None: +# calculate a long enough time daysback +ticket = Ticket(self.env, context.resource.id) +ticketage = datetime.now(utc) - ticket.time_created +days = ticketage.days + 1 +if count is None: +# ignore short count for ticket feeds +count = 0 if count is None: count = self.default_count @@ -225,6 +236,12 @@ class FilteredTimeline: process_request = TimelineModule.__dict__['process_request'] _provider_failure = TimelineModule.__dict__['_provider_failure'] _event_data = TimelineModule.__dict__['_event_data'] +max_daysback = TimelineModule.max_daysback + +@property +def max_daysback(self): +return (-1 if self.context.resource.realm == 'ticket' + else self.max_daysback) @property def event_providers(self): @@ -261,7 +278,17 @@ class TimelineFilterAdapter: # ITimelineEventProvider methods -#def get_timeline_filters(self, req): +def get_timeline_filters(self, req): +gen = self.provider.get_timeline_filters(req) +if (self.context.resource.realm == 'ticket' and +isinstance(self.provider, TicketModule) and +'TICKET_VIEW' in req.perm): +# ensure ticket_details appears once if this is a query on a ticket +gen = list(gen) +if not [g for g in gen if g[0] == 'ticket_details']: +gen.append(('ticket_details', _(Ticket updates), False)) +return gen + #def render_timeline_event(self, context, field, event): def get_timeline_events(self, req, start, stop, filters): Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/templates/bhsearch.html URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/templates/bhsearch.html?rev=1460314r1=1460313r2=1460314view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/templates/bhsearch.html (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/templates/bhsearch.html Sun Mar 24 11:28:08 2013 @@ -126,7 +126,7 @@ tr class=${'odd' if idx % 2 else 'even'} prio${result.priority_value}${ ' added' if 'added' in result else ''}${ ' changed' if 'changed' in result else ''}${ -' removed' if 'removed' in result else ''} searchable +' removed' if 'removed' in result else
svn commit: r1460318 - /incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/admin/web_ui.py
Author: jure Date: Sun Mar 24 11:47:45 2013 New Revision: 1460318 URL: http://svn.apache.org/r1460318 Log: #430, forbid access to plugin admin panel in product context, patch t430_r1457691_product_plugin_admin.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/admin/web_ui.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/admin/web_ui.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/admin/web_ui.py?rev=1460318r1=1460317r2=1460318view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/admin/web_ui.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/admin/web_ui.py Sun Mar 24 11:47:45 2013 @@ -439,10 +439,12 @@ class PluginAdminPanel(Component): # IAdminPanelProvider methods def get_admin_panels(self, req): -if 'TRAC_ADMIN' in req.perm: +if 'TRAC_ADMIN' in req.perm and not getattr(self.env, 'parent', None): yield ('general', _('General'), 'plugin', _('Plugins')) def render_admin_panel(self, req, cat, page, path_info): +if getattr(self.env, 'parent', None): +raise PermissionError() req.perm.require('TRAC_ADMIN') if req.method == 'POST':
svn commit: r1460332 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/perm.py multiproduct/product_admin.py tests/admin/product_admin.py tests/env.py tes
Author: jure Date: Sun Mar 24 12:24:30 2013 New Revision: 1460332 URL: http://svn.apache.org/r1460332 Log: #430, admin panels for PRODUCT_ADMIN based on white list, patch t430_r1457691_product_admin_whitelist.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/admin/product_admin.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/perm.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/perm.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/perm.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/perm.py?rev=1460332r1=1460331r2=1460332view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/perm.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/perm.py Sun Mar 24 12:24:30 2013 @@ -1,3 +1,4 @@ +from functools import wraps # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file @@ -21,7 +22,11 @@ __all__ = 'ProductPermissionPolicy', from trac.core import Component, implements -from trac.perm import IPermissionPolicy, PermissionSystem +from trac.perm import IPermissionPolicy, PermissionSystem, PermissionError + +#-- +# Permission components +#-- class MultiproductPermissionPolicy(Component): Apply product policy in product environments to deal with TRAC_ADMIN, @@ -47,3 +52,153 @@ class MultiproductPermissionPolicy(Compo return True if action in permsys.get_actions() and \ action != 'TRAC_ADMIN' \ else None + + +#-- +# Impersonation helpers +#-- + +class SudoPermissionContext(object): +Allows a permitted user (by default `PRODUCT_ADMIN`) to execute +a command as if temporarily granted with `TRAC_ADMIN` or other specific +permission. There is also support to revoke some actions unconditionally. + +These objects will act as context managers wrapping the permissions cache +of the target request object. Entering the same context more than once +is not supported and will result in unexpected behavior. + +def __init__(self, req, require=None, grant=None, revoke=None): +grant = frozenset(grant if grant is not None else ('TRAC_ADMIN',)) +revoke = frozenset(revoke or []) +if grant revoke: +raise ValueError('Impossible to grant and revoke (%s)' % + ', '.join(sorted(grant revoke))) + +self.grant = grant +self.revoke = revoke +if req: +self._expand_perms(req.perm.env) +else: +self._expanded = False +self._perm = None +self.req = req +self.require_actions = frozenset(('PRODUCT_ADMIN',) if require is None + else ([require] + if isinstance(require, basestring) + else require)) + +@property +def perm(self): +return self._perm + +@perm.setter +def perm(self, perm): +if perm and not self._expanded: +self._expand_perms(perm.env) +self._perm = perm + +def __getattr__(self, attrnm): +# Actually PermissionCache.__slots__ but this will be faster +if attrnm in ('env', 'username', '_resource', '_cache'): +try: +return getattr(self.perm, attrnm) +except AttributeError: +pass +raise AttributeError('%s' object has no attribute '%s' % + (self.__class__.__name__, attrnm)) + +def __enter__(self): +if self.req is None: +# e.g. instances returned by __call__ +raise ValueError('Context manager not bound to request object') +req = self.req +for action in self.require_actions: +req.perm.require(action) +self.perm = req.perm +req.perm = self +return self + +def __exit__(self, exc_type, exc_value, tb): +self.req.perm = self.perm +self.perm = None + +# Internal methods + +@property +def is_active(self): +Determine whether this context is active + +return self.req and self.perm + +def _expand_perms(self
svn commit: r1460335 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py
Author: jure Date: Sun Mar 24 12:28:38 2013 New Revision: 1460335 URL: http://svn.apache.org/r1460335 Log: #430, default product admin panel white list, patch t430_r1458841_product_admin_defaults.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py?rev=1460335r1=1460334r2=1460335view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py Sun Mar 24 12:28:38 2013 @@ -261,3 +261,17 @@ class ProductAdminModule(Component): return cat_allow is not False and panel_allow is not False \ and (cat_allow, panel_allow) != (None, None) \ and (cat_id, panel_id) != ('general', 'plugin') # double-check ! + + +class DefaultProductAdminWhitelist(Component): +implements(IProductAdminAclContributor) + +# IProductAdminAclContributor methods +def enable_product_admin_panels(self): +yield 'general', 'basics' +yield 'general', 'perm' +yield 'accounts', 'notification' +# FIXME: Include users admin panel ? +#yield 'accounts', 'users' +yield 'ticket', '*' +yield 'versioncontrol', 'repository'
svn commit: r1460340 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py
Author: jure Date: Sun Mar 24 12:38:38 2013 New Revision: 1460340 URL: http://svn.apache.org/r1460340 Log: #475, product admin console commands (list, admin), patch t475_r1457691_product_trac_admin.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py?rev=1460340r1=1460339r2=1460340view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py Sun Mar 24 12:38:38 2013 @@ -18,7 +18,8 @@ Admin panels for product management -from trac.admin.api import IAdminPanelProvider +from trac.admin.api import IAdminCommandProvider, AdminCommandError,\ +AdminCommandManager from trac.admin.web_ui import AdminModule from trac.core import * from trac.config import * @@ -26,6 +27,7 @@ from trac.perm import PermissionSystem from trac.resource import ResourceNotFound from trac.ticket.admin import TicketAdminPanel, _save_config from trac.util import lazy +from trac.util.text import print_table from trac.util.translation import _, N_, gettext from trac.web.api import HTTPNotFound, IRequestFilter, IRequestHandler from trac.web.chrome import Chrome, add_notice, add_warning @@ -44,7 +46,10 @@ class ProductAdminPanel(TicketAdminPanel _label = ('Product','Products') def get_admin_commands(self): -return None +if not isinstance(self.env, ProductEnvironment): +yield ('product list', '', + 'Show available products', + None, self._do_product_list) def get_admin_panels(self, req): if isinstance(req.perm.env, ProductEnvironment): @@ -133,6 +138,13 @@ class ProductAdminPanel(TicketAdminPanel data['owners'] = None return 'admin_products.html', data +def _do_product_list(self): +if not isinstance(self.env, ProductEnvironment): +print_table([(p.prefix, p.owner, p.name) + for p in Product.select(self.env)], +[_('Prefix'), _('Owner'), _('Name')]) + + #-- # Advanced administration in product context #-- @@ -158,7 +170,7 @@ class ProductAdminModule(Component): Leverage administration panels in product context based on the combination of white list and black list. -implements(IRequestFilter, IRequestHandler) +implements(IAdminCommandProvider, IRequestFilter, IRequestHandler) acl_contributors = ExtensionPoint(IProductAdminAclContributor) @@ -208,6 +220,39 @@ class ProductAdminModule(Component): ','.join(warnings)) return acl +# IAdminCommandProvider methods +def get_admin_commands(self): +if not isinstance(self.env, ProductEnvironment): +yield ('product admin', 'PREFIX admin command', + 'Execute admin (sub-)command upon product resources', + self._complete_product_admin, self._do_product_admin) + +def get_products(self): +return [p.prefix for p in Product.select(self.env)] + +def product_admincmd_mgr(self, prefix): +try: +product_env = ProductEnvironment.lookup_env(self.env, prefix) +except LookupError: +raise AdminCommandError('Unknown product %s' % (prefix,)) +else: +return AdminCommandManager(product_env) + +def _complete_product_admin(self, args): +if len(args) == 1: +return self.get_products() +else: +mgr = self.product_admincmd_mgr(args[0]) +return mgr.complete_command(args[1:]) + +def _do_product_admin(self, prefix, *args): +mgr = self.product_admincmd_mgr(prefix) +if args and args[0] in ('deploy', 'help', 'hotcopy', 'initenv', +'upgrade'): +raise AdminCommandError('%s command not supported for products' % +(args[0],)) +mgr.execute_command(*args) + # IRequestFilter methods def pre_process_request(self, req, handler): Intercept admin requests in product context if `TRAC_ADMIN`
svn commit: r1458692 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct: hooks.py util.py versioncontrol.py
Author: jure Date: Wed Mar 20 09:00:25 2013 New Revision: 1458692 URL: http://svn.apache.org/r1458692 Log: Productize repositories, monkey patch trac.versioncontrol.api.DbRepositoryProvider and trac.versioncontrol.api.RepositoryManager, towards #470 Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/versioncontrol.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py?rev=1458692r1=1458691r2=1458692view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py Wed Mar 20 09:00:25 2013 @@ -15,9 +15,11 @@ # specific language governing permissions and limitations # under the License. -# these two imports monkey patch required classes +# these import monkey patch classes required to enable +# multi product support import multiproduct.env import multiproduct.dbcursor +import multiproduct.versioncontrol import re Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py?rev=1458692r1=1458691r2=1458692view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py Wed Mar 20 09:00:25 2013 @@ -22,6 +22,38 @@ from genshi.builder import tag from trac.util.text import unquote_label from trac.wiki.formatter import LinkFormatter +from trac.core import Component, ComponentMeta + +# +# Component replacement base +# + +class ReplacementComponentMeta(ComponentMeta): +Component replacement meta class +def __new__(mcs, name, bases, d): +base_class = bases[0] +if base_class != Component: +# undo what has been done by ComponentMeta.__new___ for the +# replacement component base class + +# remove implemented interfaces from registry for the base class +for itf in base_class._implements: +ComponentMeta._registry[itf] = filter(lambda c: c != base_class, + ComponentMeta._registry[itf]) + +# remove base class from components list +ComponentMeta._components = filter(lambda c: c != base_class, + ComponentMeta._components) + +base_class._implements = [] +base_class.abstract = True + +return ComponentMeta.__new__(mcs, name, bases, d) + +class ReplacementComponent(Component): +Base class for components that replace existing trac +implementations +__metaclass__ = ReplacementComponentMeta #-- # Custom wiki formatters Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/versioncontrol.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/versioncontrol.py?rev=1458692view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/versioncontrol.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/versioncontrol.py Wed Mar 20 09:00:25 2013 @@ -0,0 +1,80 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language
svn commit: r1458841 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/ticket/query.py
Author: jure Date: Wed Mar 20 14:12:22 2013 New Revision: 1458841 URL: http://svn.apache.org/r1458841 Log: #325, added missing imports Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/ticket/query.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/ticket/query.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/ticket/query.py?rev=1458841r1=1458840r2=1458841view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/ticket/query.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/ticket/query.py Wed Mar 20 14:12:22 2013 @@ -23,25 +23,25 @@ from __future__ import with_statement from itertools import groupby from math import ceil from datetime import datetime, timedelta -import re from genshi.builder import tag +from trac.core import TracError from trac.db import get_column_names from trac.mimeview.api import Mimeview from trac.ticket.api import TicketSystem -from trac.ticket.query import Query, QueryModule, TicketQueryMacro -from trac.util import Ranges, as_bool +from trac.ticket.query import Query, QueryModule, TicketQueryMacro, QueryValueError from trac.util.datefmt import from_utimestamp, utc, to_timestamp from trac.util.text import shorten_line from trac.util.translation import _, tag_ +from trac.web import parse_arg_list, arg_list_to_args from trac.web.chrome import Chrome, add_stylesheet, add_link, web_context, \ -add_script_data, add_script +add_script_data, add_script, add_ctxtnav, add_warning +from trac.resource import Resource from multiproduct.dbcursor import GLOBAL_PRODUCT from multiproduct.env import lookup_product_env, resolve_product_href, \ -Product, ProductEnvironment -from multiproduct.hooks import ProductizedHref +ProductEnvironment class ProductQuery(Query):
svn commit: r1458170 - in /incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac: core.py tests/core.py
Author: jure Date: Tue Mar 19 07:53:31 2013 New Revision: 1458170 URL: http://svn.apache.org/r1458170 Log: #438, component managers in extension points, patch t438_r1457691_cpmngr_xtpt.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/core.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/core.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/core.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/core.py?rev=1458170r1=1458169r2=1458170view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/core.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/core.py Tue Mar 19 07:53:31 2013 @@ -208,7 +208,10 @@ class ComponentManager(object): if not self.is_enabled(cls): return None component = self.components.get(cls) -if not component: + +# Leave other manager components out of extension point lists +# see bh:comment:5:ticket:438 and ticket:11121 +if not component and not issubclass(cls, ComponentManager) : if cls not in ComponentMeta._components: raise TracError('Component %s not registered' % cls.__name__) try: Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/core.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/core.py?rev=1458170r1=1458169r2=1458170view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/core.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/core.py Tue Mar 19 07:53:31 2013 @@ -300,6 +300,71 @@ class ComponentTestCase(unittest.TestCas self.assertEquals('x', tests.next().test()) self.assertRaises(StopIteration, tests.next) +def test_component_manager_component_isolation(self): + +Verify that a component manager that is also a component will only +be listed in extension points for components instantiated in +its scope. + +See bh:comment:5:ticket:438 and #11121 + +from trac.core import ComponentManager +class ManagerComponent(ComponentManager, Component): +tests = ExtensionPoint(ITest) +def __init__(self, foo, bar): +ComponentManager.__init__(self) +self.foo, self.bar = foo, bar + +class YetAnotherManagerComponent(ComponentManager, Component): +implements(ITest) +def __init__(self, foo, bar): +ComponentManager.__init__(self) +self.foo, self.bar = foo, bar + +# ITest methods +def test(self): +return self.foo + self.bar + +class ComponentA(Component): +tests = ExtensionPoint(ITest) + +class Extender(Component): +implements(ITest) +def test(self): +return 'x' + +mgr = ManagerComponent('Test', 42) +yamc = YetAnotherManagerComponent('y', 'z') + +assert yamc[ManagerComponent] is None +assert mgr[YetAnotherManagerComponent] is None +assert yamc[ComponentManager] is None +assert self.compmgr[YetAnotherManagerComponent] is None +assert mgr[ComponentManager] is None +assert self.compmgr[ManagerComponent] is None + +self.assertTrue(any(c.__class__ is YetAnotherManagerComponent +for c in ComponentA(yamc).tests)) +self.assertFalse(any(c.__class__ is YetAnotherManagerComponent + for c in ComponentA(self.compmgr).tests)) +self.assertFalse(any(c.__class__ is YetAnotherManagerComponent + for c in ComponentA(mgr).tests)) +self.assertFalse(any(c.__class__ is ManagerComponent + for c in ComponentA(yamc).tests)) +self.assertFalse(any(c.__class__ is YetAnotherManagerComponent + for c in mgr.tests)) + +results = [test.test() for test in ComponentA(yamc).tests] +self.assertEquals(['x', 'yz'], sorted(results)) + +results = [test.test() for test in ComponentA(self.compmgr).tests] +self.assertEquals(['x'], sorted(results)) + +results = [test.test() for test in ComponentA(mgr).tests] +self.assertEquals(['x'], sorted(results)) +results = [test.test() for test in mgr.tests] +self.assertEquals(['x'], sorted(results)) + def test_instantiation_doesnt_enable(self): Make sure that a component disabled by the ComponentManager is not @@ -315,7 +380,6 @@ class ComponentTestCase
svn commit: r1458172 - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_dashboard/bhdashboard/ bloodhound_multiproduct/tests/ bloodhound_search/ bloodhound_search/bhsearch/ blood
Author: jure Date: Tue Mar 19 07:55:49 2013 New Revision: 1458172 URL: http://svn.apache.org/r1458172 Log: Sync merge from trunk Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/changeset_search.py - copied unchanged from r1458170, incubator/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/changeset_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/changeset_search.py - copied unchanged from r1458170, incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/search_resources/changeset_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_accountsnotification.html - copied unchanged from r1458170, incubator/bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_accountsnotification.html Modified: incubator/bloodhound/branches/bep_0003_multiproduct/ (props changed) incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/milestone_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/ticket_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/index_with_whoosh.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/whoosh_backend.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/htdocs/bloodhound.css incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/htdocs/js/theme.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_about.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_milestone_view.html incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/ (props changed) incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/attachment.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/attachment.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/model.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/tests/model.py Propchange: incubator/bloodhound/branches/bep_0003_multiproduct/ -- Merged /incubator/bloodhound/trunk:r1456924-1458170 Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py?rev=1458172r1=1458171r2=1458172view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py Tue Mar 19 07:55:49 2013 @@ -205,14 +205,16 @@ class ModelBase(object): sdata.update(self._meta) sql = UPDATE %(table_name)s SET %(values)s WHERE %(where)s % sdata -old_data = self._old_data.copy() + +old_values = dict((k, v) for k, v in self._old_data.iteritems() + if self._data.get(k) != v) with self._env.db_transaction as db: db(sql, setvalues + values) self._update_relations(db) self._old_data.update(self._data) TicketSystem(self._env).reset_ticket_fields() -ResourceSystem(self._env).resource_changed(self, old_data) +ResourceSystem(self._env).resource_changed(self, old_values) @classmethod Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py?rev=1458172r1=1458171r2=1458172view=diff
svn commit: r1457686 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/api.py multiproduct/config.py multiproduct/env.py multiproduct/perm.py setup.py tes
Author: jure Date: Mon Mar 18 09:46:02 2013 New Revision: 1457686 URL: http://svn.apache.org/r1457686 Log: #438, implement and enforce product permission policy, patch t438_r1456016_product_perms.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/perm.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/config.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/setup.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/perm.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1457686r1=1457685r2=1457686view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Mon Mar 18 09:46:02 2013 @@ -353,7 +353,12 @@ class MultiProductSystem(Component): def get_permission_actions(self): acts = ['PRODUCT_CREATE', 'PRODUCT_DELETE', 'PRODUCT_MODIFY', 'PRODUCT_VIEW'] -return acts + [('PRODUCT_ADMIN', acts)] + [('ROADMAP_ADMIN', acts)] +if not isinstance(self.env, ProductEnvironment): +return acts + [('PRODUCT_ADMIN', acts)] + [('ROADMAP_ADMIN', acts)] +else: +# In product context PRODUCT_ADMIN will be provided by product env +# to ensure it will always be handy +return acts # ITicketFieldProvider methods def get_select_fields(self): Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/config.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/config.py?rev=1457686r1=1457685r2=1457686view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/config.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/config.py Mon Mar 18 09:46:02 2013 @@ -22,12 +22,13 @@ __all__ = 'Configuration', 'Section' import os.path -from trac.config import Configuration, ConfigurationError, Option, Section, \ -_use_default +from trac.config import Configuration, ConfigurationError, Option, \ +OrderedExtensionsOption, Section, _use_default from trac.resource import ResourceNotFound from trac.util.text import to_unicode from multiproduct.model import ProductSetting +from multiproduct.perm import MultiproductPermissionPolicy class Configuration(Configuration): Product-aware settings repository equivalent to instances of @@ -315,3 +316,21 @@ class Section(Section): path = os.path.join(env.path, 'conf', path) return os.path.normcase(os.path.realpath(path)) +# +# Option override classes +# + +class ProductPermissionPolicyOption(OrderedExtensionsOption): +Prepend an instance of `multiproduct.perm.MultiproductPermissionPolicy` + +def __get__(self, instance, owner): +# FIXME: Better handling of recursive imports +from multiproduct.env import ProductEnvironment + +if instance is None: +return self +components = OrderedExtensionsOption.__get__(self, instance, owner) +env = getattr(instance, 'env', None) +return [MultiproductPermissionPolicy(env)] + components \ + if isinstance(env, ProductEnvironment) \ + else components Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1457686r1=1457685r2=1457686view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Mon Mar 18 09:46:02 2013 @@ -16,16 +16,17 @@ # under the License. Bloodhound product environment and related APIs -from multiproduct.hooks import MultiProductEnvironmentFactory import os.path from urlparse import urlsplit from sqlite3
svn commit: r1457691 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py
Author: jure Date: Mon Mar 18 09:58:11 2013 New Revision: 1457691 URL: http://svn.apache.org/r1457691 Log: #404, do not copy TRAC_ADMIN permission from global scope on product addition, patch t404_r1456016_revert_r1449636.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1457691r1=1457690r2=1457691view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Mon Mar 18 09:58:11 2013 @@ -322,15 +322,6 @@ class MultiProductSystem(Component): (table[0], ','.join(cols), ','.join(['%s' for c in cols])), rows) -# in addition copy global admin permissions (they are -# not part of the default permission table) -rows = db(SELECT username FROM permission WHERE action='TRAC_ADMIN' - AND product='') -rows = [(r[0], 'TRAC_ADMIN', product.prefix) for r in rows] -cols = ('username', 'action', 'product') -db.executemany(INSERT INTO permission (%s) VALUES (%s) % - (','.join(cols), ','.join(['%s' for c in cols])), rows) - def resource_changed(self, resource, old_values, context): return
svn commit: r1456802 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py
Author: jure Date: Fri Mar 15 08:44:31 2013 New Revision: 1456802 URL: http://svn.apache.org/r1456802 Log: #440, python 2.6 compatibility regression, patch t440_r1456016_py26_compat.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py?rev=1456802r1=1456801r2=1456802view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py Fri Mar 15 08:44:31 2013 @@ -17,9 +17,14 @@ # under the License. Tests for multiproduct/model.py -import unittest -import tempfile import shutil +import sys +import tempfile + +if sys.version_info (2, 7): +import unittest2 as unittest +else: +import unittest from sqlite3 import OperationalError
svn commit: r1456865 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/cache.py multiproduct/env.py tests/env.py
Author: jure Date: Fri Mar 15 10:28:53 2013 New Revision: 1456865 URL: http://svn.apache.org/r1456865 Log: #440, product environments as parametric singletons, patch t440_1456016_product_env_singleton.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/cache.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/cache.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/cache.py?rev=1456865r1=1456864r2=1456865view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/cache.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/cache.py Fri Mar 15 10:28:53 2013 @@ -3,6 +3,10 @@ # Developed by Raymond Hettinger # (http://code.activestate.com/recipes/498245-lru-and-lfu-cache-decorators/) # +# March 13, 2013 updated by Olemis Lang +#Added keymap arg to build custom keys out of actual args +# March 14, 2013 updated by Olemis Lang +#Keep cache consistency on user function failure import collections import functools @@ -15,7 +19,7 @@ class Counter(dict): def __missing__(self, key): return 0 -def lru_cache(maxsize=100): +def lru_cache(maxsize=100, keymap=None): '''Least-recently-used cache decorator. Arguments to the cached function must be hashable. @@ -23,6 +27,8 @@ def lru_cache(maxsize=100): Clear the cache with f.clear(). http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used +:param keymap:build custom keys out of actual arguments. + Its signature will be lambda (args, kwds, kwd_mark) ''' maxqueue = maxsize * 10 def decorating_function(user_function, @@ -40,20 +46,32 @@ def lru_cache(maxsize=100): @functools.wraps(user_function) def wrapper(*args, **kwds): # cache key records both positional and keyword args -key = args -if kwds: -key += (kwd_mark,) + tuple(sorted(kwds.items())) - -# record recent use of this key -queue_append(key) -refcount[key] += 1 +if keymap is None: +key = args +if kwds: +key += (kwd_mark,) + tuple(sorted(kwds.items())) +else: +key = keymap(args, kwds, kwd_mark) # get cache entry or compute if not found try: result = cache[key] wrapper.hits += 1 + +# record recent use of this key +queue_append(key) +refcount[key] += 1 except KeyError: -result = user_function(*args, **kwds) +# Explicit exception handling for readability +try: +result = user_function(*args, **kwds) +except: +raise +else: +# record recent use of this key +queue_append(key) +refcount[key] += 1 + cache[key] = result wrapper.misses += 1 @@ -91,7 +109,7 @@ def lru_cache(maxsize=100): return decorating_function -def lfu_cache(maxsize=100): +def lfu_cache(maxsize=100, keymap=None): '''Least-frequenty-used cache decorator. Arguments to the cached function must be hashable. @@ -99,6 +117,8 @@ def lfu_cache(maxsize=100): Clear the cache with f.clear(). http://en.wikipedia.org/wiki/Least_Frequently_Used +:param keymap:build custom keys out of actual arguments. + Its signature will be lambda (args, kwds, kwd_mark) ''' def decorating_function(user_function): cache = {} # mapping of args to results @@ -107,9 +127,12 @@ def lfu_cache(maxsize=100): @functools.wraps(user_function) def wrapper(*args, **kwds): -key = args -if kwds: -key += (kwd_mark,) + tuple(sorted(kwds.items())) +if keymap is None: +key = args +if kwds: +key += (kwd_mark,) + tuple(sorted(kwds.items())) +else: +key = keymap(args, kwds, kwd_mark) use_count[key] += 1 # get cache entry or compute if not found @@ -140,3 +163,12 @@ def lfu_cache(maxsize=100): return wrapper return decorating_function +#-- +# Helper functions +#-- + +def
svn commit: r1456434 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct: api.py product_admin.py util.py web_ui.py
Author: jure Date: Thu Mar 14 13:50:59 2013 New Revision: 1456434 URL: http://svn.apache.org/r1456434 Log: Removed ProductDelegate, leverage IResourceChangeListener to populate schema on product addition Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/product_admin.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/web_ui.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1456434r1=1456433r2=1456434view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Thu Mar 14 13:50:59 2013 @@ -38,6 +38,7 @@ from trac.web.main import FakePerm, Fake from trac.wiki.api import IWikiSyntaxProvider from trac.wiki.formatter import LinkFormatter from trac.wiki.parser import WikiParser +from trac.resource import IResourceChangeListener from multiproduct.model import Product, ProductResourceMap, ProductSetting from multiproduct.util import EmbeddedLinkFormatter, IDENTIFIER @@ -71,7 +72,8 @@ class MultiProductSystem(Component): implements(IEnvironmentSetupParticipant, ITemplateProvider, IPermissionRequestor, ITicketFieldProvider, IResourceManager, - ISupportMultiProductEnvironment, IWikiSyntaxProvider) + ISupportMultiProductEnvironment, IWikiSyntaxProvider, + IResourceChangeListener) product_base_url = Option('multiproduct', 'product_base_url', '', A pattern used to generate the base URL of product environments, @@ -96,12 +98,17 @@ class MultiProductSystem(Component): for mcls in (Product, ProductResourceMap)] # Tables which should be migrated (extended with 'product' column) -MIGRATE_TABLES = ['enum', 'component', 'milestone', 'version', +MIGRATE_TABLES = ['component', + 'milestone', + 'version', + 'enum', 'permission', 'wiki', 'report', ] +PRODUCT_POPULATE_TABLES = list(set(MIGRATE_TABLES) - set(['wiki'])) + def get_version(self): Finds the current version of the bloodhound database schema rows = self.env.db_direct_query( @@ -195,13 +202,8 @@ class MultiProductSystem(Component): [t for t in table_defs if t.name == table.name][0].columns] if c != 'product'] self.log.info(Creating default product) -default_product = Product(self.env) -default_product.update_field_dict({'prefix': DEFAULT_PRODUCT, - 'name': 'Default', - 'description': 'Default product', - 'owner': '', - }) -default_product.insert() +db(INSERT INTO bloodhound_product (prefix, name, description, owner) \ + VALUES ('%s', '%s', '%s', '') % (DEFAULT_PRODUCT, 'Default', 'Default product')) self.log.info(Migrating tickets w/o product to default product) db(UPDATE ticket SET product='%s' @@ -290,6 +292,54 @@ class MultiProductSystem(Component): self.env.enable_multiproduct_schema(True) + +# IResourceChangeListener methods +def match_resource(self, resource): +return isinstance(resource, Product) + +def resource_created(self, resource, context): +import trac.db_default +from multiproduct.env import EnvironmentStub + +# Don't populate product database when running from within test +# environment stub as test cases really don't expect that ... +if isinstance(self.env, EnvironmentStub): +return + +product = resource +self.log.debug(Adding product info (%s) to tables: % product.prefix) +with self.env.db_direct_transaction as db: +# create the default entries for this Product from defaults +for table in trac.db_default.get_data(db): +if not table[0] in self.PRODUCT_POPULATE_TABLES: +continue
svn commit: r1455906 - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_search/bhsearch/ bloodhound_search/bhsearch/search_resources/ bloodhound_search/bhsearch/templates/ bloodh
Author: jure Date: Wed Mar 13 12:31:28 2013 New Revision: 1455906 URL: http://svn.apache.org/r1455906 Log: Sync merge from trunk Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html - copied unchanged from r1455900, incubator/bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_timeline.html - copied unchanged from r1455900, incubator/bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_timeline.html Modified: incubator/bloodhound/branches/bep_0003_multiproduct/ (props changed) incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE incubator/bloodhound/branches/bep_0003_multiproduct/NOTICE incubator/bloodhound/branches/bep_0003_multiproduct/RELEASE_NOTES incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/query_parser.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/ticket_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/templates/bhsearch.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/query_parser.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/web_ui.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/web_ui.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/whoosh_backend.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_ticket.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_ticket_box.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bloodhound_theme.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py Propchange: incubator/bloodhound/branches/bep_0003_multiproduct/ -- Merged /incubator/bloodhound/trunk:r1455438-1455900 Modified: incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE?rev=1455906r1=1455905r2=1455906view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE Wed Mar 13 12:31:28 2013 @@ -209,7 +209,7 @@ separate copyright notices and license t for the these subcomponents is subject to the terms and conditions of the following licenses. -For Trac, found in the trac/ directory: +For Trac, in the trac/ directory: Copyright (C) 2003-2013 Edgewall Software All rights reserved. @@ -243,7 +243,7 @@ For Trac, found in the trac/ directory: For Bootstrap, as provided by the files bloodhound_dashboard/bhdashboard/htdocs/css/bootstrap.css bloodhound_dashboard/bhdashboard/htdocs/css/bootstrap-responsive.css -and the bloodhound_dashboard/bhdashboard/htdocs/js/ directory: +and bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap.js: Copyright 2012 Twitter, Inc. @@ -262,9 +262,14 @@ and the bloodhound_dashboard/bhdashboard For jQuery, in the file trac/trac/htdocs/js/jquery.js -Copyright 2011 jQuery Foundation and other contributors -http://jquery.com/ - +Copyright 2013 jQuery Foundation and other contributors, +http://jqueryui.com/ + +This software consists of voluntary contributions made by many +individuals (AUTHORS.txt, http://jqueryui.com/about) For exact +contribution history, see the revision history and logs, available +at http://jquery-ui.googlecode.com/svn/ + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including @@ -272,10 +277,10 @@ trac/trac/htdocs/js/jquery.js distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
svn commit: r1456016 - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_dashboard/bhdashboard/ bloodhound_multiproduct/multiproduct/ bloodhound_multiproduct/tests/ trac/ trac/tra
Author: jure Date: Wed Mar 13 16:06:23 2013 New Revision: 1456016 URL: http://svn.apache.org/r1456016 Log: Sync merge from trunk Modified: incubator/bloodhound/branches/bep_0003_multiproduct/ (props changed) incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/model.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/ (props changed) incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/attachment.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/attachment.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/model.py Propchange: incubator/bloodhound/branches/bep_0003_multiproduct/ -- Merged /incubator/bloodhound/trunk:r1455901-1456015 Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py?rev=1456016r1=1456015r2=1456016view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py Wed Mar 13 16:06:23 2013 @@ -18,7 +18,7 @@ from trac.db import Table, Column from trac.core import TracError -from trac.resource import ResourceNotFound +from trac.resource import ResourceNotFound, ResourceSystem from trac.ticket.api import TicketSystem @@ -133,9 +133,11 @@ class ModelBase(object): with self._env.db_transaction as db: db(sql, values) self._exists = False -self._data = dict([(k, None) for k in self._data.keys()]) -self._old_data.update(self._data) TicketSystem(self._env).reset_ticket_fields() +ResourceSystem(self._env).resource_deleted(self) +self._data = dict([(k, None) for k in self._data.keys()]) +self._old_data.update(self._data) + def insert(self): Create new record in the database @@ -174,6 +176,7 @@ class ModelBase(object): self._exists = True self._old_data.update(self._data) TicketSystem(self._env).reset_ticket_fields() +ResourceSystem(self._env).resource_created(self) def _update_relations(self, db): Extra actions due to update @@ -202,11 +205,15 @@ class ModelBase(object): sdata.update(self._meta) sql = UPDATE %(table_name)s SET %(values)s WHERE %(where)s % sdata +old_data = self._old_data.copy() with self._env.db_transaction as db: db(sql, setvalues + values) self._update_relations(db) self._old_data.update(self._data) TicketSystem(self._env).reset_ticket_fields() + +ResourceSystem(self._env).resource_changed(self, old_data) + @classmethod def select(cls, env, db=None, where=None, limit=None): Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/model.py?rev=1456016r1=1456015r2=1456016view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/model.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/model.py Wed Mar 13 16:06:23 2013 @@ -58,9 +58,10 @@ class Product(ModelBase): sdata.update(self._meta) raise TracError('%(object_name)s %(new_table)s does not exist' % sdata) +original_prefix = self._data['prefix'] super(Product, self).delete() #find and update all resources that should move -where = {'product_id':self._data['prefix']} +where = {'product_id':original_prefix} for prm in ProductResourceMap.select(self._env, where=where): prm._data['product_id'] = resources_to prm.update() Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/model.py?rev=1456016r1
svn commit: r1455437 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py
Author: jure Date: Tue Mar 12 08:27:26 2013 New Revision: 1455437 URL: http://svn.apache.org/r1455437 Log: Add login and logout to global href white list Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py?rev=1455437r1=1455436r2=1455437view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py Tue Mar 12 08:27:26 2013 @@ -55,7 +55,7 @@ class ProductizedHref(Href): if args: # TODO: this should be done using regex or similar if args[0] == 'chrome' or \ - (args[0] == 'admin' and len(args) == 1) or \ + (len(args) == 1 and args[0] in ['admin', 'login', 'logout']) or \ args[0].startswith('js/') or \ args[0].startswith('css/') or\ args[0].startswith('img/') or\
svn commit: r1455438 - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_theme/bhtheme/ bloodhound_theme/bhtheme/templates/ trac/ trac/trac/ trac/trac/tests/ trac/trac/ticket/ tra
Author: jure Date: Tue Mar 12 08:29:15 2013 New Revision: 1455438 URL: http://svn.apache.org/r1455438 Log: Sync merge from trunk Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_prefs_language.html - copied unchanged from r1455437, incubator/bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_language.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_prefs_userinterface.html - copied unchanged from r1455437, incubator/bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_userinterface.html Modified: incubator/bloodhound/branches/bep_0003_multiproduct/ (props changed) incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_diff_view.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_history_view.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_diff.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/ (props changed) incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/attachment.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/resource.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/attachment.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/resource.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/api.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/model.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/tests/model.py Propchange: incubator/bloodhound/branches/bep_0003_multiproduct/ -- Merged /incubator/bloodhound/trunk:r1455109-1455437 Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_diff_view.html URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_diff_view.html?rev=1455438r1=1455437r2=1455438view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_diff_view.html (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_diff_view.html Tue Mar 12 08:29:15 2013 @@ -33,7 +33,7 @@ body div id=content class=${resource.realm} row - h1 py:choose= + h1 class=span12 py:choose= py:when test=old_versioni18n:msg params=old, new, nameChanges between a href=${old_url or url_of(resource, version=old_version)}Version $old_version/a and a href=${new_url or url_of(resource, version=new_version)}Version $new_version/a of Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_history_view.html URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_history_view.html?rev=1455438r1=1455437r2=1455438view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_history_view.html (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_history_view.html Tue Mar 12 08:29:15 2013 @@ -32,7 +32,9 @@ body div id=content class=ticket row - h1 i18n:msg=nameChange History for a href=${url or url_of(resource)}${name or name_of(resource)}/a/h1 + h1 class=span12 i18n:msg=name +Change History for a href=${url or url_of(resource)}${name or name_of(resource)}/a + /h1 br/ div class=span12 Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_diff.html URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_diff.html?rev=1455438r1=1455437r2=1455438view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_diff.html (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_diff.html Tue Mar 12 08:29:15 2013 @@ -25,7 +25,7 @@ xmlns:xi=http://www.w3.org/2001/XInclude; py:strip= py:match path=div[@id='content'] once=truediv py:attrs=select
svn commit: r1455454 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/api.py tests/product-ticket-link-tests.txt
Author: jure Date: Tue Mar 12 09:02:46 2013 New Revision: 1455454 URL: http://svn.apache.org/r1455454 Log: #390, handle unmatched nested wiki syntax, patch t390_r1453952_product_wikisyntax_nomatch.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-ticket-link-tests.txt Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1455454r1=1455453r2=1455454view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Tue Mar 12 09:02:46 2013 @@ -21,6 +21,7 @@ import copy from genshi.builder import tag, Element +from genshi.core import escape from pkg_resources import resource_filename from trac.config import Option, PathOption @@ -463,7 +464,14 @@ class MultiProductSystem(Component): if isinstance(link, Element) and 'title' in link.attrib else link) -return subformatter.match(sublink + extra) +link = subformatter.match(sublink + extra) +if link: +return link +else: +# Return outermost match unchanged like if it was !-escaped +for itype, match in fullmatch.groupdict().items(): +if match and not itype in formatter.wikiparser.helper_patterns: +return escape(match) PRODUCT_SYNTAX_DELIMITER = MultiProductSystem.short_syntax_delimiter Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-ticket-link-tests.txt URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-ticket-link-tests.txt?rev=1455454r1=1455453r2=1455454view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-ticket-link-tests.txt (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-ticket-link-tests.txt Tue Mar 12 09:02:46 2013 @@ -90,13 +90,17 @@ %(link_prefix)s#â´Â² %(link_prefix)s#1-âµ,42 %(link_prefix)s#1,³,5,7 +%(link_prefix_quote)s#1-âµ,42 +%(link_prefix_quote)s#1,³,5,7 %(link_prefix)s#T²â°â´Â¹ %(link_prefix)s#trac²â°â´Â¹ -- p %(link_prefix)s#â´Â² -a class=new ticket href=/ticket/1 title=%(link_title_prefix)sThis is the summary (new)#1/a-âµ,42 -a class=new ticket href=/ticket/1 title=%(link_title_prefix)sThis is the summary (new)#1/a,³,5,7 +a class=new ticket href=%(path_prefix)s/ticket/1 title=%(link_title_prefix)sThis is the summary (new)#1/a +a class=new ticket href=%(path_prefix)s/ticket/1 title=%(link_title_prefix)sThis is the summary (new)#1/a +a class=new ticket href=%(path_prefix)s/ticket/1 title=%(link_title_prefix)sThis is the summary (new)#1/a-âµ,42 +a class=new ticket href=%(path_prefix)s/ticket/1 title=%(link_title_prefix)sThis is the summary (new)#1/a,³,5,7 %(link_prefix)s#T²â°â´Â¹ %(link_prefix)s#trac²â°â´Â¹ /p
svn commit: r1455452 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/api.py tests/product-nomatch-link-tests.txt tests/product-ticket-jira-tests.txt tes
Author: jure Date: Tue Mar 12 09:01:24 2013 New Revision: 1455452 URL: http://svn.apache.org/r1455452 Log: #390, product extensions to ticket wiki syntax (short JIRA syntax), patch t390_r1453952_product_ticket_jira.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-nomatch-link-tests.txt incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-ticket-jira-tests.txt Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wikisyntax.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1455452r1=1455451r2=1455452view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Tue Mar 12 09:01:24 2013 @@ -338,16 +338,27 @@ class MultiProductSystem(Component): return bool(products) # IWikiSyntaxProvider methods -PRODUCT_SYNTAX_DELIMITER = u'-' -def get_wiki_syntax(self): -return [] +short_syntax_delimiter = u'-' +def get_wiki_syntax(self): +if self.env[ProductTicketModule] is not None: +yield (r(?!\S)!?(?Pjtp()(?!\d)\w+)-(?Pjtt\d+) + r(?Pjtf[?#]\S+)?, + lambda f, m, fm : +self._format_link(f, 'product', + '%s:ticket:%s' % +(fm.group('jtp'), + fm.group('jtt') + + (fm.group('jtf') or '')), + m, fm)) + def get_link_resolvers(self): yield ('global', self._format_link) yield ('product', self._format_link) # Internal methods + def _render_link(self, context, name, label, extra='', prefix=None): Render link to product page. @@ -455,7 +466,8 @@ class MultiProductSystem(Component): return subformatter.match(sublink + extra) -PRODUCT_SYNTAX_DELIMITER = MultiProductSystem.PRODUCT_SYNTAX_DELIMITER +PRODUCT_SYNTAX_DELIMITER = MultiProductSystem.short_syntax_delimiter from multiproduct.env import ProductEnvironment, lookup_product_env, \ resolve_product_href +from multiproduct.ticket.web_ui import ProductTicketModule Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-nomatch-link-tests.txt URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-nomatch-link-tests.txt?rev=1455452view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-nomatch-link-tests.txt (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-nomatch-link-tests.txt Tue Mar 12 09:01:24 2013 @@ -0,0 +1,48 @@ + + +JIRA compact syntax with leading digit + +== leading digit - JIRA syntax link resolver +0abc-1 +0abc-12 +0abc-abc +-- +p +0abc-1 +0abc-12 +0abc-abc +/p +-- +== leading digit - JIRA syntax link resolver + arguments +0abc-1?format=csv +0abc-1#comment:3 +-- +p +0abc-1?format=csv +0abc-1#comment:3 +/p +-- +== leading digit - JIRA syntax link shorthand form +0abc-1, 0abc-2 +0abc-12, 0abc-abc +-- +p +0abc-1, 0abc-2 +0abc-12, 0abc-abc +/p +-- +== leading digit - JIRA syntax escaping the above +!0abc-1 +-- +p +!0abc-1 +/p +-- +!0abc-1 +== leading digit - JIRA syntax with unicode digits +0abc-â´Â² +-- +p +0abc-â´Â² +/p +-- Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-ticket-jira-tests.txt URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-ticket-jira-tests.txt?rev=1455452view=auto
svn commit: r1455457 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/ tests/
Author: jure Date: Tue Mar 12 09:06:01 2013 New Revision: 1455457 URL: http://svn.apache.org/r1455457 Log: #390, compact product wiki syntax, patch t390_r1453952_product_wikisyntax_compact.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-attachment-link-tests.short.txt incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-comment-link-tests.short.txt incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-milestone-link-tests.short.txt incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-query-link-tests.short.txt incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-search-link-tests.short.txt incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-ticket-link-tests.short.txt Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-comment-link-tests.txt incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-query-link-tests.txt incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wikisyntax.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1455457r1=1455456r2=1455457view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Tue Mar 12 09:06:01 2013 @@ -31,12 +31,13 @@ from trac.env import IEnvironmentSetupPa from trac.perm import IPermissionRequestor, PermissionCache from trac.resource import IResourceManager from trac.ticket.api import ITicketFieldProvider -from trac.util.text import to_unicode +from trac.util.text import to_unicode, unquote_label from trac.util.translation import _, N_ from trac.web.chrome import ITemplateProvider from trac.web.main import FakePerm, FakeSession from trac.wiki.api import IWikiSyntaxProvider from trac.wiki.formatter import LinkFormatter +from trac.wiki.parser import WikiParser from multiproduct.model import Product, ProductResourceMap, ProductSetting from multiproduct.util import EmbeddedLinkFormatter @@ -340,11 +341,22 @@ class MultiProductSystem(Component): # IWikiSyntaxProvider methods -short_syntax_delimiter = u'-' +short_syntax_delimiter = u'~' def get_wiki_syntax(self): +yield (r'(?!\S)!?(?Ppid(?!\d)\w+)' + + ''.join('[%s]' % c for c in self.short_syntax_delimiter) + + r'(?Pptarget%s:(?:%s)|%s|%s(?:%s*%s)?)' % +(WikiParser.LINK_SCHEME, WikiParser.QUOTED_STRING, + WikiParser.QUOTED_STRING, WikiParser.SHREF_TARGET_FIRST, + WikiParser.SHREF_TARGET_MIDDLE, WikiParser.SHREF_TARGET_LAST), + lambda f, m, fm : +self._format_link(f, 'product', + '%s:%s' % (fm.group('pid'), + unquote_label(fm.group('ptarget'))), + fm.group(0), fm)) if self.env[ProductTicketModule] is not None: -yield (r(?!\S)!?(?Pjtp()(?!\d)\w+)-(?Pjtt\d+) +yield (r(?!\S)!?(?Pjtp(?!\d)\w+)-(?Pjtt\d+) r(?Pjtf[?#]\S+)?, lambda f, m, fm : self._format_link(f, 'product', Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-attachment-link-tests.short.txt URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-attachment-link-tests.short.txt?rev=1455457view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-attachment-link-tests.short.txt (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-attachment-link-tests.short.txt Tue Mar 12 09:06:01 2013 @@ -0,0 +1,52 @@ + + +Product attachment links + +== %(tc_title_prefix)s - attachment: link resolver (deprecated) +%(link_prefix)sattachment:wiki:WikiStart:file.txt (deprecated) +%(link_prefix)sattachment:ticket:123:file.txt (deprecated
svn commit: r1455475 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: ./ multiproduct/ multiproduct/ticket/ tests/ tests/wiki/
Author: jure Date: Tue Mar 12 10:25:30 2013 New Revision: 1455475 URL: http://svn.apache.org/r1455475 Log: #434, ticket query macro support, patch t434_r1453952_product_ticketquery.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/ticket/query.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/setup.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-query-link-tests.txt incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/product-query2-link-tests.txt incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/formatter.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wikisyntax.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1455475r1=1455474r2=1455475view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Tue Mar 12 10:25:30 2013 @@ -65,9 +65,12 @@ def translate_sql(env, sql): TRANSLATE_TABLES, PRODUCT_COLUMN, product_prefix) -if log: -log.debug('Original SQl: %s', sql) -return translator.translate(sql) if (translator is not None) else sql +if log: +log.debug('Original SQl: %s', sql) +realsql = translator.translate(sql) if (translator is not None) else sql +if log: +log.debug('SQL: %s', realsql) +return realsql class BloodhoundIterableCursor(trac.db.util.IterableCursor): __slots__ = trac.db.util.IterableCursor.__slots__ + ['_translator'] Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1455475r1=1455474r2=1455475view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Tue Mar 12 10:25:30 2013 @@ -1,4 +1,3 @@ - # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -805,24 +804,36 @@ class ProductEnvironment(Component, Comp # Multi-product API extensions @classmethod -def lookup_env(cls, env, prefix=None): -Instantiate environment according to product prefix +def lookup_env(cls, env, prefix=None, name=None): +Instantiate environment according to product prefix or name -@throws LookupError if no product matches prefix +@throws LookupError if no product matches neither prefix nor name if isinstance(env, ProductEnvironment): -if not prefix: -return env.parent -elif env.product.prefix == prefix: -return env -else: -return ProductEnvironment(env.parent, prefix) +global_env = env.parent else: -# `self` bound to global environment -if not prefix: -return env +global_env = env + +if not prefix and not name: +return global_env +elif isinstance(env, ProductEnvironment) and \ +env.product.prefix == prefix: +return env +if prefix: +try: +return ProductEnvironment(global_env, prefix) +except LookupError: +if not name: +raise +if name: +# Lookup product by name +products = Product.select(global_env, where={'name' : name}) +if products: +return ProductEnvironment(global_env, products[0]) else: -return ProductEnvironment(env, prefix) +raise LookupError(Missing product '%s' % (name,)) +else: +raise LookupError(Mising
svn commit: r1455477 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py
Author: jure Date: Tue Mar 12 10:51:46 2013 New Revision: 1455477 URL: http://svn.apache.org/r1455477 Log: Leverage product environment factory in lookup_env Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1455477r1=1455476r2=1455477view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Tue Mar 12 10:51:46 2013 @@ -16,6 +16,7 @@ # under the License. Bloodhound product environment and related APIs +from multiproduct.hooks import MultiProductEnvironmentFactory import os.path from urlparse import urlsplit @@ -821,7 +822,7 @@ class ProductEnvironment(Component, Comp return env if prefix: try: -return ProductEnvironment(global_env, prefix) +return ProductEnvironmentFactory(global_env, prefix) except LookupError: if not name: raise @@ -829,7 +830,7 @@ class ProductEnvironment(Component, Comp # Lookup product by name products = Product.select(global_env, where={'name' : name}) if products: -return ProductEnvironment(global_env, products[0]) +return MultiProductEnvironmentFactory(global_env, products[0]) else: raise LookupError(Missing product '%s' % (name,)) else:
svn commit: r1455576 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct: api.py hooks.py web_ui.py
Author: jure Date: Tue Mar 12 15:15:22 2013 New Revision: 1455576 URL: http://svn.apache.org/r1455576 Log: Renamed default product to '@', redirect most URL requests targeted to global environment to default product Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/web_ui.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1455576r1=1455575r2=1455576view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Tue Mar 12 15:15:22 2013 @@ -42,12 +42,14 @@ from trac.wiki.parser import WikiParser from multiproduct.model import Product, ProductResourceMap, ProductSetting from multiproduct.util import EmbeddedLinkFormatter, IDENTIFIER -__all__ = 'MultiProductSystem', 'PRODUCT_SYNTAX_DELIMITER' +__all__ = ['MultiProductSystem', 'PRODUCT_SYNTAX_DELIMITER', 'DEFAULT_PRODUCT'] DB_VERSION = 4 DB_SYSTEM_KEY = 'bloodhound_multi_product_version' PLUGIN_NAME = 'Bloodhound multi product' +DEFAULT_PRODUCT = '@' + class ISupportMultiProductEnvironment(Interface): Extension point interface for components that are aware of multi product environment and its specifics. @@ -100,7 +102,6 @@ class MultiProductSystem(Component): 'report', ] - def get_version(self): Finds the current version of the bloodhound database schema rows = self.env.db_direct_query( @@ -170,7 +171,6 @@ class MultiProductSystem(Component): from multiproduct.model import Product import trac.db_default -DEFAULT_PRODUCT = 'default' TICKET_TABLES = ['ticket_change', 'ticket_custom', 'attachment', ] @@ -230,9 +230,9 @@ class MultiProductSystem(Component): for table in self.MIGRATE_TABLES: temp_table_name, cols = create_temp_table(table) if table == 'wiki': -self.log.info(Populating table '%s', table) -db(INSERT INTO %s (%s, product) SELECT %s,'' FROM %s % - (table, cols, cols, temp_table_name)) +self.log.info(Migrating wiki to default product) +db(INSERT INTO %s (%s, product) SELECT %s,'%s' FROM %s % + (table, cols, cols, DEFAULT_PRODUCT, temp_table_name)) else: products = Product.select(self.env) for product in products: Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py?rev=1455576r1=1455575r2=1455576view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py Tue Mar 12 15:15:22 2013 @@ -52,6 +52,9 @@ class ProductizedHref(Href): 'logout', 'prefs', 'products', + 'verify_email', + 'reset_password', + 'register', ] STATIC_PREFIXES = ['js/', 'css/', Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/web_ui.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/web_ui.py?rev=1455576r1=1455575r2=1455576view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/web_ui.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/web_ui.py Tue Mar 12 15:15:22 2013 @@ -35,9 +35,10 @@ from trac.web.main import RequestDispatc from multiproduct.model import Product from multiproduct.util import ProductDelegate - +from multiproduct.api import
svn commit: r1455109 - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_dashboard/ bloodhound_multiproduct/ bloodhound_search/ bloodhound_search/bhsearch/ bloodhound_search/bhsea
Author: jure Date: Mon Mar 11 12:14:05 2013 New Revision: 1455109 URL: http://svn.apache.org/r1455109 Log: Sync merge from trunk Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/query_parser.py - copied unchanged from r1455108, incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/query_parser.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/ (props changed) incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE incubator/bloodhound/branches/bep_0003_multiproduct/RELEASE_NOTES incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/setup.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/setup.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/templates/bhsearch.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/whoosh_backend.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/whoosh_backend.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/htdocs/bloodhound.css incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_attachment.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_browser.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_dir_entries.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_dirlist_thead.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_path_links.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_preview_file.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_report_edit.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_repository_index.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_sortable_th.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_ticket.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_ticket_delete.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_edit.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_edit_form.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_view.html incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/setup.py Propchange: incubator/bloodhound/branches/bep_0003_multiproduct/ -- Merged /incubator/bloodhound/trunk:r1453380-1455108 Modified: incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE?rev=1455109r1=1455108r2=1455109view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE Mon Mar 11 12:14:05 2013 @@ -211,7 +211,7 @@ following licenses. For Trac, found in the trac/ directory: -Copyright (C) 2003-2012 Edgewall Software +Copyright (C) 2003-2013 Edgewall Software All rights reserved. Redistribution and use in source and binary forms, with or without @@ -259,8 +259,8 @@ and the bloodhound_dashboard/bhdashboard See the License for the specific language governing permissions and limitations under the License. -For JQuery, in the file -bloodhound_theme/bhtheme/htdocs/js/jquery-1.7.1.min.js +For jQuery, in the file +trac/trac/htdocs/js/jquery.js Copyright 2011 jQuery Foundation and other contributors http://jquery.com/ Modified: incubator/bloodhound/branches/bep_0003_multiproduct/RELEASE_NOTES URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/RELEASE_NOTES?rev=1455109r1=1455108r2=1455109view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/RELEASE_NOTES (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/RELEASE_NOTES Mon Mar 11 12:14:05 2013 @@ -1,9 +1,12 @@ 0.5 + * Implemented Bootstrap templates for the repository browser, log
svn commit: r1454383 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct: dbcursor.py env.py
Author: jure Date: Fri Mar 8 13:38:29 2013 New Revision: 1454383 URL: http://svn.apache.org/r1454383 Log: #407, make setup work again, properly setup environment Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1454383r1=1454382r2=1454383view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Fri Mar 8 13:38:29 2013 @@ -94,6 +94,10 @@ class BloodhoundIterableCursor(trac.db.u def get_env(cls): return cls._tls.env +@classmethod +def cache_reset(cls): +translate_sql.clear() + # replace trac.db.util.IterableCursor with BloodhoundIterableCursor trac.db.util.IterableCursor = BloodhoundIterableCursor Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1454383r1=1454382r2=1454383view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Fri Mar 8 13:38:29 2013 @@ -32,7 +32,7 @@ from trac.web.href import Href from multiproduct.api import MultiProductSystem, ISupportMultiProductEnvironment from multiproduct.config import Configuration -from multiproduct.dbcursor import ProductEnvContextManager, BloodhoundConnectionWrapper +from multiproduct.dbcursor import ProductEnvContextManager, BloodhoundConnectionWrapper, BloodhoundIterableCursor from multiproduct.model import Product import trac.env @@ -98,13 +98,13 @@ class Environment(trac.env.Environment): # invoke `IEnvironmentSetupParticipant.environment_created` for all # global setup participants if create: -for participant in self._global_setup_participants: +# when creating environment, run global setup participants if schema has been upgraded +# to multi-product. If not, run setup participants ... +for participant in self._global_setup_participants if self._multiproduct_schema_enabled \ + else self.setup_participants: with ComponentEnvironmentContext(self, participant): participant.environment_created() -if not self._multiproduct_schema_enabled: -self.log.warn(Running environment schema not upgraded to multi-product) - @property def db_query(self): return ProductEnvContextManager(super(Environment, self).db_query, self) \ @@ -123,6 +123,9 @@ class Environment(trac.env.Environment): def db_direct_transaction(self): return ProductEnvContextManager(super(Environment, self).db_transaction) +def _all_product_envs(self): +return [ProductEnvironmentFactory(self, product) for product in Product.select(self)] + def needs_upgrade(self): Return whether the environment needs to be upgraded. def needs_upgrade_in_env_list(env_list, participants): @@ -142,9 +145,12 @@ class Environment(trac.env.Environment): return True if needs_upgrade_in_env_list([self], self._global_setup_participants): return True -product_envs = [self] + [ProductEnvironmentFactory(self, product) for product in Product.select(self)] -if needs_upgrade_in_env_list(product_envs, self._product_setup_participants): -return True +# until schema is multi product aware, product environments can't (and shouldn't) be +# instantiated +if self._multiproduct_schema_enabled: +product_envs = [self] + self._all_product_envs() +if needs_upgrade_in_env_list(product_envs, self._product_setup_participants): +return True return False def upgrade(self, backup=False, backup_dest=None): @@ -174,7 +180,7 @@ class Environment(trac.env.Environment): return upgraders def upgraders_for_product_envs(): -product_envs = [self] + [ProductEnvironmentFactory(self, product) for product in Product.select(self
svn commit: r1453763 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py
Author: jure Date: Thu Mar 7 10:37:11 2013 New Revision: 1453763 URL: http://svn.apache.org/r1453763 Log: Introduce global LRU cache for translated SQLs Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1453763r1=1453762r2=1453763view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Thu Mar 7 10:37:11 2013 @@ -23,6 +23,8 @@ import sqlparse import sqlparse.tokens as Tokens import sqlparse.sql as Types +from multiproduct.util import lru_cache + __all__ = ['BloodhoundIterableCursor', 'BloodhoundConnectionWrapper', 'ProductEnvContextManager'] SKIP_TABLES = ['auth_cookie', @@ -49,36 +51,36 @@ class empty_translator(object): translator_not_set = empty_translator() +@lru_cache(maxsize=1000) +def translate_sql(env, sql): +translator = None +log = None +if env is not None: +# FIXME: This is the right way to do it but breaks translation +# if trac.db.api.DatabaseManager(self.env).debug_sql: +if (env.parent or env).config['trac'].get('debug_sql', False): +log = env.log +product_prefix = env.product.prefix if env.product else GLOBAL_PRODUCT +translator = BloodhoundProductSQLTranslate(SKIP_TABLES, + TRANSLATE_TABLES, + PRODUCT_COLUMN, + product_prefix) +if log: +log.debug('Original SQl: %s', sql) +return translator.translate(sql) if (translator is not None) else sql + class BloodhoundIterableCursor(trac.db.util.IterableCursor): __slots__ = trac.db.util.IterableCursor.__slots__ + ['_translator'] _tls = concurrency.ThreadLocal(env=None) def __init__(self, cursor, log=None): super(BloodhoundIterableCursor, self).__init__(cursor, log=log) -self._translator = translator_not_set - -def _translate_sql(self, sql): -if self._translator is translator_not_set: -self._translator = None -if self.env is not None: -# FIXME: This is the right way to do it but breaks translation -# if trac.db.api.DatabaseManager(self.env).debug_sql: -if (self.env.parent or self.env).config['trac'].get('debug_sql', False): -self.log = self.env.log -product_prefix = self.env.product.prefix if self.env.product else GLOBAL_PRODUCT -self._translator = BloodhoundProductSQLTranslate(SKIP_TABLES, - TRANSLATE_TABLES, - PRODUCT_COLUMN, - product_prefix) -if self.log: -self.log.debug('Original SQl: %s', sql) -return self._translator.translate(sql) if (self._translator is not None) else sql def execute(self, sql, args=None): -return super(BloodhoundIterableCursor, self).execute(self._translate_sql(sql), args=args) +return super(BloodhoundIterableCursor, self).execute(translate_sql(self.env, sql), args=args) def executemany(self, sql, args=None): -return super(BloodhoundIterableCursor, self).executemany(self._translate_sql(sql), args=args) +return super(BloodhoundIterableCursor, self).executemany(translate_sql(self.env, sql), args=args) @property def env(self):
svn commit: r1453952 - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_multiproduct/multiproduct/
Author: jure Date: Thu Mar 7 16:41:03 2013 New Revision: 1453952 URL: http://svn.apache.org/r1453952 Log: LRU LFU cache implementations added, appropriate files (license, notice,...) updated appropriately Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/cache.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/.rat-ignore incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE incubator/bloodhound/branches/bep_0003_multiproduct/NOTICE incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/.rat-ignore URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/.rat-ignore?rev=1453952r1=1453951r2=1453952view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/.rat-ignore (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/.rat-ignore Thu Mar 7 16:41:03 2013 @@ -5,6 +5,7 @@ **/TODO bloodhound_dashboard/bhdashboard/default-pages/ bloodhound_search/bhsearch/default-pages/ +bloodhound_multiproduct/multiproduct/cache.py doc/html-templates/js/jquery-1.8.2.js doc/wireframes/src/ installer/README.rst Modified: incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE?rev=1453952r1=1453951r2=1453952view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/LICENSE Thu Mar 7 16:41:03 2013 @@ -284,3 +284,55 @@ bloodhound_theme/bhtheme/htdocs/js/jquer OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +For LRU and LFU cache decorators, developed by Raymond Hettinger, in the file +bloodhound_multiproduct/multiproduct/cache.py: + +PSF LICENSE AGREEMENT + +This LICENSE AGREEMENT is between the Python Software Foundation +(âPSFâ), and the Individual or Organization (âLicenseeâ) accessing +and otherwise using Python 2.7.3 software in source or binary form +and its associated documentation. + +Subject to the terms and conditions of this License Agreement, PSF +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display +publicly, prepare derivative works, distribute, and otherwise use +Python 2.7.3 alone or in any derivative version, provided, +however, that PSFâs License Agreement and PSFâs notice of +copyright, i.e., âCopyright © 2001-2013 Python Software +Foundation; All Rights Reservedâ are retained in Python 2.7.3 +alone or in any derivative version prepared by Licensee. + +In the event Licensee prepares a derivative work that is based on +or incorporates Python 2.7.3 or any part thereof, and wants to +make the derivative work available to others as provided herein, +then Licensee hereby agrees to include in any such work a brief +summary of the changes made to Python 2.7.3. + +PSF is making Python 2.7.3 available to Licensee on an âAS ISâ +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR +FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.7.3 +WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. + +PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +2.7.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR +LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING +PYTHON 2.7.3, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE +POSSIBILITY THEREOF. + +This License Agreement will automatically terminate upon a +material breach of its terms and conditions. + +Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF +and Licensee. This License Agreement does not grant permission to +use PSF trademarks or trade name in a trademark sense to endorse +or promote products or services of Licensee, or any third party. + +By copying, installing or otherwise using Python 2.7.3, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. Modified: incubator/bloodhound/branches/bep_0003_multiproduct/NOTICE URL: http://svn.apache.org/viewvc
svn commit: r1453323 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_multiproduct/multiproduct/env.py bloodhound_multiproduct/multiproduct/hooks.py bloodhound_multiproduct/multip
Author: jure Date: Wed Mar 6 13:21:15 2013 New Revision: 1453323 URL: http://svn.apache.org/r1453323 Log: Product environment factory + simple LRU cache Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1453323r1=1453322r2=1453323view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Wed Mar 6 13:21:15 2013 @@ -135,7 +135,7 @@ class Environment(trac.env.Environment): return True if needs_upgrade_in_env_list([self], self._global_setup_participants): return True -product_envs = [self] + [ProductEnvironment(self, product) for product in Product.select(self)] +product_envs = [self] + [ProductEnvironmentFactory(self, product) for product in Product.select(self)] if needs_upgrade_in_env_list(product_envs, self._product_setup_participants): return True return False @@ -167,7 +167,7 @@ class Environment(trac.env.Environment): return upgraders def upgraders_for_product_envs(): -product_envs = [self] + [ProductEnvironment(self, product) for product in Product.select(self)] +product_envs = [self] + [ProductEnvironmentFactory(self, product) for product in Product.select(self)] return upgraders_for_env_list(product_envs, self._product_setup_participants) # first enumerate components that are multi product aware and require upgrade @@ -804,3 +804,10 @@ class ProductEnvironment(Component, Comp self._abs_href = Href(self.base_url) return self._abs_href +from multiproduct.util import lru_cache + +@lru_cache(maxsize=100) +def ProductEnvironmentFactory(global_env, product): +Product environment factory + +return ProductEnvironment(global_env, product) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py?rev=1453323r1=1453322r2=1453323view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py Wed Mar 6 13:21:15 2013 @@ -42,5 +42,5 @@ class MultiProductEnvironmentFactory(Env # happen from within trac.web.main.dispatch_request req = RequestWithSession(environ, None) global_env._abs_href = req.abs_href -env = multiproduct.env.ProductEnvironment(global_env, pid) +env = multiproduct.env.ProductEnvironmentFactory(global_env, pid) return env Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py?rev=1453323r1=1453322r2=1453323view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/util.py Wed Mar 6 13:21:15 2013 @@ -21,6 +21,9 @@ from trac import db_default from multiproduct.api import MultiProductSystem +import collections +import functools + class ProductDelegate(object): @staticmethod def add_product(env, product, keys, field_data): @@ -52,3 +55,24 @@ class ProductDelegate(object): db.executemany(INSERT INTO permission (%s) VALUES (%s) % (','.join(cols), ','.join(['%s' for c in cols])), rows) +def lru_cache(maxsize=100): +Simple LRU cache decorator, using `collections.OrderedDict` for +item store + +def wrap(f): +cache = collections.OrderedDict() +@functools.wraps(f) +def wrapped_func(*args, **kwargs): +key = args +if kwargs
svn commit: r1453351 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_multiproduct/multiproduct/hooks.py trac/trac/hooks.py trac/trac/web/main.py
Author: jure Date: Wed Mar 6 14:49:35 2013 New Revision: 1453351 URL: http://svn.apache.org/r1453351 Log: #357 follow up, added request factory for handling product scoped Hrefs ... Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/main.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py?rev=1453351r1=1453350r2=1453351view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py Wed Mar 6 14:49:35 2013 @@ -21,8 +21,9 @@ import multiproduct.dbcursor import re -from trac.hooks import EnvironmentFactoryBase +from trac.hooks import EnvironmentFactoryBase, RequestFactoryBase from trac.web.main import RequestWithSession +from trac.web.href import Href PRODUCT_RE = re.compile(r'^/products/(?Ppid[^/]*)(?Ppathinfo.*)') @@ -44,3 +45,33 @@ class MultiProductEnvironmentFactory(Env global_env._abs_href = req.abs_href env = multiproduct.env.ProductEnvironmentFactory(global_env, pid) return env + +class ProductizedHref(Href): +def __init__(self, global_href, base): +super(ProductizedHref, self).__init__(base) +self._global_href = global_href + +def __call__(self, *args, **kwargs): +if args: +# TODO: this should be done using regex or similar +if args[0] == 'chrome' or \ + args[0].startswith('js/') or \ + args[0].startswith('css/') or\ + args[0].startswith('img/') or\ + args[0].startswith('products'): +return self._global_href(*args, **kwargs) +return super(ProductizedHref, self).__call__(*args, **kwargs) + +class ProductRequestWithSession(RequestWithSession): +def __init__(self, env, environ, start_response): +super(ProductRequestWithSession, self).__init__(environ, start_response) +self.base_url = env.base_url +self.href = ProductizedHref(self.href, env.href.base) +self.abs_href = ProductizedHref(self.abs_href, env.abs_href.base) + +class ProductRequestFactory(RequestFactoryBase): +def create_request(self, env, environ, start_response): +if isinstance(env, multiproduct.env.ProductEnvironment): +return ProductRequestWithSession(env, environ, start_response) +else: +return RequestWithSession(environ, start_response) \ No newline at end of file Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py?rev=1453351r1=1453350r2=1453351view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py Wed Mar 6 14:49:35 2013 @@ -28,6 +28,10 @@ class EnvironmentFactoryBase(object): def open_environment(self, environ, env_path, global_env, use_cache=False): return None +class RequestFactoryBase(object): +def create_request(self, env, environ, start_response): +return None + def _get_plugins_dir(env_path): return os.path.normcase(os.path.realpath(os.path.join(env_path, 'plugins'))) @@ -73,3 +77,7 @@ def install_global_hooks(): def environment_factory(env): hook_path = env.config.get('trac', 'environment_factory', default=None) return _get_hook_class(env.path, hook_path, EnvironmentFactoryBase) if hook_path else None + +def request_factory(env): +hook_path = env.config.get('trac', 'request_factory', default=None) +return _get_hook_class(env.path, hook_path, RequestFactoryBase) if hook_path else None Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/main.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/main.py?rev=1453351r1=1453350r2=1453351view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/main.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/main.py Wed Mar 6 14:49:35 2013 @@ -434,6 +434,7 @@ def dispatch_request(environ, start_resp run_once = environ['wsgi.run_once'] env = env_error = None +global_env = None try
svn commit: r1453379 - /incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py
Author: jure Date: Wed Mar 6 15:20:04 2013 New Revision: 1453379 URL: http://svn.apache.org/r1453379 Log: #357 follow up, properly configure request factory during setup Modified: incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py?rev=1453379r1=1453378r2=1453379view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py Wed Mar 6 15:20:04 2013 @@ -77,7 +77,8 @@ BASE_CONFIG = {'components': {'bhtheme.* 'trac': {'mainnav': ','.join(['dashboard', 'wiki', 'browser', 'tickets', 'newticket', 'timeline', 'roadmap', 'search', 'admin']), -'environment_factory': '',}, +'environment_factory': '', +'request_factory': '',}, 'project': {'footer': ('Visit Apache Bloodhound atbr /' 'a href=%(site)s%(site)s/a' % {'site': BH_PROJECT_SITE,}),}, @@ -220,7 +221,12 @@ class BloodhoundSetup(object): os.path.normpath( os.path.join(options['sourcedir'], 'bloodhound_multiproduct/multiproduct/hooks.py'))) +request_factory_path = os.path.abspath( + os.path.normpath( + os.path.join(options['sourcedir'], + 'bloodhound_multiproduct/multiproduct/hooks.py'))) base_config['trac']['environment_factory'] = environment_factory_path +base_config['trac']['request_factory'] = request_factory_path self.writeconfig(baseini, [base_config, accounts_config])
svn commit: r1452769 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct: api.py dbcursor.py env.py
Author: jure Date: Tue Mar 5 12:43:16 2013 New Revision: 1452769 URL: http://svn.apache.org/r1452769 Log: #406, added 'system' table to translate list, invoke `environment_created` on both global product environment setup participants, remove automatic multi product upgrade from test EnvironmentStub Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1452769r1=1452768r2=1452769view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Tue Mar 5 12:43:16 2013 @@ -95,7 +95,7 @@ class MultiProductSystem(Component): def get_version(self): Finds the current version of the bloodhound database schema -rows = self.env.db_query( +rows = self.env.db_direct_query( SELECT value FROM system WHERE name = %s , (DB_SYSTEM_KEY,)) return int(rows[0][0]) if rows else -1 @@ -163,10 +163,11 @@ class MultiProductSystem(Component): TICKET_TABLES = ['ticket_change', 'ticket_custom', 'attachment', ] +SYSTEM_TABLES = ['system'] # extend trac default schema by adding product column and extending key with product table_defs = [copy.deepcopy(t) for t in trac.db_default.schema -if t.name in self.MIGRATE_TABLES + TICKET_TABLES] +if t.name in self.MIGRATE_TABLES + TICKET_TABLES + SYSTEM_TABLES] for t in table_defs: t.columns.append(Column('product')) if isinstance(t.key, list): @@ -257,6 +258,15 @@ class MultiProductSystem(Component): SET product=(SELECT wiki.product FROM wiki WHERE wiki.name=attachment.id) WHERE type='wiki') +# Update system tables +# Upgrade schema +self.log.info(Migrating system tables to a new schema) +for table in SYSTEM_TABLES: +temp_table_name, cols = create_temp_table(table) +db(INSERT INTO %s (%s, product) SELECT %s,'' FROM %s % + (table, cols, cols, temp_table_name)) +drop_temp_table(temp_table_name) + db_installed_version = self._update_db_version(db, 3) if db_installed_version 4: Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1452769r1=1452768r2=1452769view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Tue Mar 5 12:43:16 2013 @@ -25,14 +25,15 @@ import sqlparse.sql as Types __all__ = ['BloodhoundIterableCursor', 'BloodhoundConnectionWrapper', 'ProductEnvContextManager'] -SKIP_TABLES = ['system', 'auth_cookie', +SKIP_TABLES = ['auth_cookie', 'session', 'session_attribute', 'cache', 'repository', 'revision', 'node_change', 'bloodhound_product', 'bloodhound_productresourcemap', 'bloodhound_productconfig', 'sqlite_master' ] -TRANSLATE_TABLES = ['ticket', 'ticket_change', 'ticket_custom', +TRANSLATE_TABLES = ['system', +'ticket', 'ticket_change', 'ticket_custom', 'attachment', 'enum', 'component', 'milestone', 'version', 'permission', Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1452769r1=1452768r2=1452769view=diff == --- incubator/bloodhound/branches
svn commit: r1452776 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests: __init__.py versioncontrol/api.py
Author: jure Date: Tue Mar 5 12:51:33 2013 New Revision: 1452776 URL: http://svn.apache.org/r1452776 Log: #355, ignore sub package root on test discovert, patch t355_r1450181_trac_test_ignore_subpkg_root.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/versioncontrol/api.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py?rev=1452776r1=1452775r2=1452776view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py Tue Mar 5 12:51:33 2013 @@ -33,7 +33,7 @@ class TestLoader(unittest.TestLoader): sortTestMethodsUsing = cmp suiteClass = unittest.TestSuite -def discover_package(self, package_or_requirement, pattern='test*.py'): +def discover_package(self, package_or_requirement, pattern='test*.py', ignore_subpkg_root=True): Find and return all test modules from the specified package directory, recursing into subdirectories to find them. Only test files that match the pattern will be loaded. (Using shell style pattern @@ -56,10 +56,11 @@ class TestLoader(unittest.TestLoader): # Skip packages not having __init__.py continue loader = getattr(mdl, self.testLoaderAttribute, None) or loader -if mdlnm != package_or_requirement and hasattr(mdl, 'test_suite'): -tests.append(mdl.test_suite()) -else: -tests.append(loader.loadTestsFromModule(mdl)) +if not (isdir and ignore_subpkg_root): +if mdlnm != package_or_requirement and hasattr(mdl, 'test_suite'): +tests.append(mdl.test_suite()) +else: +tests.append(loader.loadTestsFromModule(mdl)) if isdir and resource_exists(mdlnm, '__init__.py'): for fnm in resource_listdir(mdlnm, ''): if resource_isdir(mdlnm, fnm): Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/versioncontrol/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/versioncontrol/api.py?rev=1452776r1=1452775r2=1452776view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/versioncontrol/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/versioncontrol/api.py Tue Mar 5 12:51:33 2013 @@ -54,42 +54,42 @@ class ProductResourceManagerTestCase(Res def test_resource_changeset(self): res = Resource('changeset', '42') self.assertEqual('Changeset 42', get_resource_description(self.env, res)) -self.assertEqual('/trac.cgi/product/tp1/changeset/42', +self.assertEqual('/trac.cgi/products/tp1/changeset/42', get_resource_url(self.env, res, self.env.href)) repo = Resource('repository', 'repo') res = Resource('changeset', '42', parent=repo) self.assertEqual('Changeset 42 in repo', get_resource_description(self.env, res)) -self.assertEqual('/trac.cgi/product/tp1/changeset/42/repo', +self.assertEqual('/trac.cgi/products/tp1/changeset/42/repo', get_resource_url(self.env, res, self.env.href)) def test_resource_source(self): res = Resource('source', '/trunk/src') self.assertEqual('path /trunk/src', get_resource_description(self.env, res)) -self.assertEqual('/trac.cgi/product/tp1/browser/trunk/src', +self.assertEqual('/trac.cgi/products/tp1/browser/trunk/src', get_resource_url(self.env, res, self.env.href)) repo = Resource('repository', 'repo') res = Resource('source', '/trunk/src', parent=repo) self.assertEqual('path /trunk/src in repo', get_resource_description(self.env, res)) -self.assertEqual('/trac.cgi/product/tp1/browser/repo/trunk/src', +self.assertEqual('/trac.cgi/products/tp1/browser/repo/trunk/src', get_resource_url(self.env, res, self.env.href)) repo = Resource('repository', 'repo') res = Resource('source', '/trunk/src', version=42, parent=repo) self.assertEqual('path /trunk/src@42 in repo
svn commit: r1452779 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/wikisyntax.py
Author: jure Date: Tue Mar 5 12:54:36 2013 New Revision: 1452779 URL: http://svn.apache.org/r1452779 Log: #355, test cases for ticket wiki syntax, patch t355_r1452271_trac_test_ticket_wikisyntax.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/wikisyntax.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/wikisyntax.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/wikisyntax.py?rev=1452779view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/wikisyntax.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/wikisyntax.py Tue Mar 5 12:54:36 2013 @@ -0,0 +1,60 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for inherited Apache(TM) Bloodhound ticket wiki syntax +in product environments + +import os.path +import re +import unittest + +from trac.ticket.tests import wikisyntax + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase +from tests.wiki import formatter + +def test_suite(): +suite = unittest.TestSuite() +suite.addTest(formatter.test_suite(wikisyntax.TICKET_TEST_CASES, + wikisyntax.ticket_setup, + wikisyntax.__file__, + wikisyntax.ticket_teardown)) +suite.addTest(formatter.test_suite(wikisyntax.REPORT_TEST_CASES, + wikisyntax.report_setup, + wikisyntax.__file__)) +suite.addTest(formatter.test_suite(wikisyntax.MILESTONE_TEST_CASES, + wikisyntax.milestone_setup, + wikisyntax.__file__, + wikisyntax.milestone_teardown)) +suite.addTest(formatter.test_suite(wikisyntax.QUERY_TEST_CASES, + wikisyntax.ticket_setup, + wikisyntax.__file__, + wikisyntax.ticket_teardown)) +suite.addTest(formatter.test_suite(wikisyntax.QUERY2_TEST_CASES, + wikisyntax.query2_setup, + wikisyntax.__file__, + wikisyntax.query2_teardown)) +suite.addTest(formatter.test_suite(wikisyntax.COMMENT_TEST_CASES, + file=wikisyntax.__file__)) +return suite + + +if __name__ == '__main__': +unittest.main(defaultTest='test_suite') +
svn commit: r1452243 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct: api.py env.py
Author: jure Date: Mon Mar 4 10:36:14 2013 New Revision: 1452243 URL: http://svn.apache.org/r1452243 Log: #406, initial implementation of multi product database upgrade Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1452243r1=1452242r2=1452243view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Mon Mar 4 10:36:14 2013 @@ -25,7 +25,7 @@ import copy from pkg_resources import resource_filename from trac.config import Option, PathOption -from trac.core import Component, TracError, implements +from trac.core import Component, TracError, implements, Interface from trac.db import Table, Column, DatabaseManager, Index from trac.env import IEnvironmentSetupParticipant from trac.perm import IPermissionRequestor @@ -40,11 +40,28 @@ DB_VERSION = 4 DB_SYSTEM_KEY = 'bloodhound_multi_product_version' PLUGIN_NAME = 'Bloodhound multi product' +class ISupportMultiProductEnvironment(Interface): +Extension point interface for components that are aware of multi +product environment and its specifics. + +Component implementing this interface is handled in a special way in the +following scenarios: + +* if implementing `IEnvironmentSetupParticipant` interface, the component + will only be invoked once per global environment creation/upgrade. It is + up to the component to install/update it's environment specifics (schema, + possibly files, etc.) for all products. In contrast, components that don't + implement `ISupportMultiProductEnvironment` interface will be, during + install/update, invoked per product environment. + +pass + class MultiProductSystem(Component): Creates the database tables and template directories implements(IEnvironmentSetupParticipant, ITemplateProvider, -IPermissionRequestor, ITicketFieldProvider, IResourceManager) + IPermissionRequestor, ITicketFieldProvider, IResourceManager, + ISupportMultiProductEnvironment) product_base_url = Option('multiproduct', 'product_base_url', '', A pattern used to generate the base URL of product environments, Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1452243r1=1452242r2=1452243view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Mon Mar 4 10:36:14 2013 @@ -23,20 +23,31 @@ from urlparse import urlsplit from sqlite3 import OperationalError from trac.config import BoolOption, ConfigSection, Option -from trac.core import Component, ComponentManager, implements +from trac.core import Component, ComponentManager, implements, Interface, ExtensionPoint from trac.db.api import TransactionContextManager, QueryContextManager, DatabaseManager from trac.util import get_pkginfo, lazy from trac.util.compat import sha1 from trac.versioncontrol import RepositoryManager from trac.web.href import Href -from multiproduct.api import MultiProductSystem +from multiproduct.api import MultiProductSystem, ISupportMultiProductEnvironment from multiproduct.config import Configuration from multiproduct.dbcursor import ProductEnvContextManager, BloodhoundConnectionWrapper from multiproduct.model import Product import trac.env +class ComponentEnvironmentContext(object): +def __init__(self, env, component): +self._env = env +self._component = component +def __enter__(self): +self._old_env = self._component.env +self._env.component_activated(self._component) +return self +def __exit__(self, type, value, traceback): +self._old_env.component_activated(self._component) + class Environment(trac.env.Environment): Bloodhound environment manager @@ -46,12 +57,19 @@ class Environment(trac.env.Environment): to ProductEnvironment that features per-product view of the database (in the context of selected product). + +multi_product_support_components = ExtensionPoint
svn commit: r1451150 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests: admin/__init__.py db/__init__.py mimeview/__init__.py ticket/__init__.py versioncontrol/__
Author: jure Date: Thu Feb 28 09:18:39 2013 New Revision: 1451150 URL: http://svn.apache.org/r1451150 Log: #355, test discovery across multi product test packages, patch t355_r1450181_trac_test_subpkg.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/admin/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/versioncontrol/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/__init__.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/admin/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/admin/__init__.py?rev=1451150r1=1451149r2=1451150view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/admin/__init__.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/admin/__init__.py Thu Feb 28 09:18:39 2013 @@ -18,3 +18,8 @@ Tests for Apache(TM) Bloodhound's administration in product environments +from tests import TestLoader + +def test_suite(): +return TestLoader().discover_package(__name__, pattern='*.py') + Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/__init__.py?rev=1451150r1=1451149r2=1451150view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/__init__.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/__init__.py Thu Feb 28 09:18:39 2013 @@ -16,3 +16,8 @@ # specific language governing permissions and limitations # under the License. +from tests import TestLoader + +def test_suite(): +return TestLoader().discover_package(__name__, pattern='*.py') + Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/__init__.py?rev=1451150r1=1451149r2=1451150view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/__init__.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/__init__.py Thu Feb 28 09:18:39 2013 @@ -18,3 +18,8 @@ Tests for Apache(TM) Bloodhound's MIME API in product environments +from tests import TestLoader + +def test_suite(): +return TestLoader().discover_package(__name__, pattern='*.py') + Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/__init__.py?rev=1451150r1=1451149r2=1451150view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/__init__.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/__init__.py Thu Feb 28 09:18:39 2013 @@ -18,3 +18,8 @@ Tests for Apache(TM) Bloodhound's tickets in product environments +from tests import TestLoader + +def test_suite(): +return TestLoader().discover_package(__name__, pattern='*.py') + Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/versioncontrol/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/versioncontrol/__init__.py?rev=1451150r1=1451149r2=1451150view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/versioncontrol/__init__.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/versioncontrol/__init__.py Thu Feb 28 09:18:39 2013 @@ -18,3 +18,8 @@ Tests for Apache
svn commit: r1450762 [1/3] - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_dashboard/ bloodhound_dashboard/bhdashboard/htdocs/css/ bloodhound_dashboard/bhdashboard/htdocs/img/
Author: jure Date: Wed Feb 27 12:52:42 2013 New Revision: 1450762 URL: http://svn.apache.org/r1450762 Log: Sync merge from trunk Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap.js - copied unchanged from r1450761, incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/setup.cfg - copied unchanged from r1450761, incubator/bloodhound/trunk/bloodhound_multiproduct/setup.cfg incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/base.py - copied unchanged from r1450761, incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/search_resources/base.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/setup.cfg - copied unchanged from r1450761, incubator/bloodhound/trunk/bloodhound_theme/setup.cfg Removed: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-affix.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-alert.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-button.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-carousel.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-collapse.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-dropdown.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-modal.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-popover.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-scrollspy.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-tab.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-tooltip.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-transition.js incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap-typeahead.js Modified: incubator/bloodhound/branches/bep_0003_multiproduct/ (props changed) incubator/bloodhound/branches/bep_0003_multiproduct/RELEASE_NOTES incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/css/bootstrap-responsive.css incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/css/bootstrap.css incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/htdocs/img/glyphicons-halflings.png incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/layouts/bootstrap.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/setup.cfg incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/setup.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/setup.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/base.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/milestone_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/ticket_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/wiki_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/base.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/index_with_whoosh.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/wiki_search.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/web_ui.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/whoosh_backend.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch
svn commit: r1450181 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests: env.py ticket/query.py
Author: jure Date: Tue Feb 26 14:18:51 2013 New Revision: 1450181 URL: http://svn.apache.org/r1450181 Log: #355, ticket query module test cases, patch t355_r1444754_trac_test_ticket_query.diff (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/query.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py?rev=1450181r1=1450180r2=1450181view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Tue Feb 26 14:18:51 2013 @@ -203,6 +203,7 @@ class MultiproductTestCase(unittest.Test from trac import db_default +env.log.debug('Loading default data') with env.db_transaction as db: for table, cols, vals in db_default.get_data(db): if table != 'system': @@ -210,6 +211,7 @@ class MultiproductTestCase(unittest.Test (table, ','.join(cols), ','.join(['%s' for c in cols])), vals) +env.log.debug('Loaded default data') def _mp_setup(self): Shortcut for quick product-aware environment setup. Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/query.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/query.py?rev=1450181view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/query.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/query.py Tue Feb 26 14:18:51 2013 @@ -0,0 +1,414 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's ticket queries in product environments + +import unittest + +from trac.ticket.query import Query +from trac.ticket.tests.query import QueryTestCase, QueryLinksTestCase + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase + +class ProductQueryTestCase(QueryTestCase, MultiproductTestCase): + +@property +def env(self): +env = getattr(self, '_env', None) +if env is None: +self.global_env = self._setup_test_env() +self._upgrade_mp(self.global_env) +self._setup_test_log(self.global_env) +self._load_product_from_data(self.global_env, self.default_product) +self._env = env = ProductEnvironment( +self.global_env, self.default_product) +self._load_default_data(env) +return env + +@env.setter +def env(self, value): +pass + +def tearDown(self): +self.global_env.reset_db() +self.global_env = self._env = None + +def test_all_grouped_by_milestone(self): +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.product AS product,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) +ORDER BY COALESCE(t.milestone,'')='',COALESCE(milestone.completed,0)=0,milestone.completed,COALESCE(milestone.due,0)=0,milestone.due,t.milestone,COALESCE(t.id,0)=0,t.id) +self.assertEqual([], args) +tickets = query.execute(self.req) + +def test_all_grouped_by_milestone_desc
svn commit: r1449737 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/env.py tests/wiki/formatter.py tests/wikisyntax.py
Author: jure Date: Mon Feb 25 14:59:52 2013 New Revision: 1449737 URL: http://svn.apache.org/r1449737 Log: #355, wiki syntex extensions test cases, patch t355_r1444754_trac_test_core_wikisyntax.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wikisyntax.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/formatter.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1449737r1=1449736r2=1449737view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Mon Feb 25 14:59:52 2013 @@ -193,48 +193,6 @@ class ProductEnvironment(Component, Comp implements(trac.env.ISystemInfoProvider) -def __getitem__(self, cls): -if issubclass(cls, trac.env.Environment): -return self.parent -elif cls is self.__class__: -return self -else: -return ComponentManager.__getitem__(self, cls) - -def __getattr__(self, attrnm): -Forward attribute access request to parent environment. - -Initially this will affect the following members of -`trac.env.Environment` class: - -system_info_providers, secure_cookies, project_admin_trac_url, -get_system_info, get_version, get_templates_dir, get_templates_dir, -get_log_dir, backup - -try: -if attrnm in ('parent', '_rules'): -raise AttributeError -return getattr(self.parent, attrnm) -except AttributeError: -raise AttributeError('%s' object has no attribute '%s' % -(self.__class__.__name__, attrnm)) - -def __repr__(self): -return %s %s at %s % (self.__class__.__name__, - repr(self.product.prefix), - hex(id(self))) - -@lazy -def path(self): -The subfolder `./products/product prefix` relative to the -top-level directory of the global environment will be the root of -product file system area. - -folder = os.path.join(self.parent.path, 'products', self.product.prefix) -if not os.path.exists(folder): -os.makedirs(folder) -return folder - @property def setup_participants(self): Setup participants list for product environments will always @@ -384,6 +342,48 @@ class ProductEnvironment(Component, Comp self.setup_config() +def __getitem__(self, cls): +if issubclass(cls, trac.env.Environment): +return self.parent +elif cls is self.__class__: +return self +else: +return ComponentManager.__getitem__(self, cls) + +def __getattr__(self, attrnm): +Forward attribute access request to parent environment. + +Initially this will affect the following members of +`trac.env.Environment` class: + +system_info_providers, secure_cookies, project_admin_trac_url, +get_system_info, get_version, get_templates_dir, get_templates_dir, +get_log_dir, backup + +try: +if attrnm in ('parent', '_rules'): +raise AttributeError +return getattr(self.parent, attrnm) +except AttributeError: +raise AttributeError('%s' object has no attribute '%s' % +(self.__class__.__name__, attrnm)) + +def __repr__(self): +return %s %s at %s % (self.__class__.__name__, + repr(self.product.prefix), + hex(id(self))) + +@lazy +def path(self): +The subfolder `./products/product prefix` relative to the +top-level directory of the global environment will be the root of +product file system area. + +folder = os.path.join(self.parent.path, 'products', self.product.prefix) +if not os.path.exists(folder): +os.makedirs(folder) +return folder + # ISystemInfoProvider methods # Same as parent environment's . Avoid duplicated code Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/formatter.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/formatter.py?rev=1449737r1=1449736r2=1449737view=diff
svn commit: r1449047 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/env.py tests/wiki/macros.py
Author: jure Date: Fri Feb 22 14:03:57 2013 New Revision: 1449047 URL: http://svn.apache.org/r1449047 Log: #355, wiki macros test cases, patch t355_r1446579_trac_test_wiki_macros.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/macros.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1449047r1=1449046r2=1449047view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Fri Feb 22 14:03:57 2013 @@ -193,6 +193,14 @@ class ProductEnvironment(Component, Comp implements(trac.env.ISystemInfoProvider) +def __getitem__(self, cls): +if issubclass(cls, trac.env.Environment): +return self.parent +elif cls is self.__class__: +return self +else: +return ComponentManager.__getitem__(self, cls) + def __getattr__(self, attrnm): Forward attribute access request to parent environment. @@ -211,6 +219,11 @@ class ProductEnvironment(Component, Comp raise AttributeError('%s' object has no attribute '%s' % (self.__class__.__name__, attrnm)) +def __repr__(self): +return %s %s at %s % (self.__class__.__name__, + repr(self.product.prefix), + hex(id(self))) + @lazy def path(self): The subfolder `./products/product prefix` relative to the @@ -394,7 +407,14 @@ class ProductEnvironment(Component, Comp `None`, the component only gets activated if it is located in the `plugins` directory of the environment. -if self.parent[cls] is None: +if cls is self.__class__: +# Prevent lookups in parent env ... will always fail +return True +# FIXME : Maybe checking for ComponentManager is too drastic +elif issubclass(cls, ComponentManager): +# Avoid clashes with overridden Environment's options +return False +elif self.parent[cls] is None: return False return self.is_component_enabled_local(cls) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/macros.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/macros.py?rev=1449047view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/macros.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/macros.py Fri Feb 22 14:03:57 2013 @@ -0,0 +1,75 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for inherited Apache(TM) Bloodhound's wiki macros +in product environments + +import os.path +import re +import unittest + +from trac.wiki.tests import macros + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase +from tests.wiki import formatter + +def test_suite(): +suite = unittest.TestSuite() +suite.addTest(formatter.test_suite( + macros.IMAGE_MACRO_TEST_CASES, + file=macros.__file__)) +suite.addTest(formatter.test_suite( + macros.TITLEINDEX1_MACRO_TEST_CASES, + file=macros.__file__)) +suite.addTest(formatter.test_suite( + macros.TITLEINDEX2_MACRO_TEST_CASES, + file=macros.__file__, + setup
svn commit: r1449050 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/wikisyntax.py
Author: jure Date: Fri Feb 22 14:06:52 2013 New Revision: 1449050 URL: http://svn.apache.org/r1449050 Log: #355, htdocs wiki syntax tests, patch t355_r1444754_trac_test_web_wikisyntax.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/wikisyntax.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/wikisyntax.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/wikisyntax.py?rev=1449050view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/wikisyntax.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/wikisyntax.py Fri Feb 22 14:06:52 2013 @@ -0,0 +1,38 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for inherited Apache(TM) Bloodhound htdocs wiki syntax +in product environments + +import os.path +import re +import unittest + +from trac.web.tests import wikisyntax + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase +from tests.wiki import formatter + +def test_suite(): +return formatter.test_suite(wikisyntax.TEST_CASES, file=wikisyntax.__file__) + + +if __name__ == '__main__': +unittest.main(defaultTest='test_suite') +
svn commit: r1448062 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py
Author: jure Date: Wed Feb 20 09:59:25 2013 New Revision: 1448062 URL: http://svn.apache.org/r1448062 Log: Stop leaking fds by not creating temporary tables when migrating data on schema upgrade Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1448062r1=1448061r2=1448062view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Wed Feb 20 09:59:25 2013 @@ -173,7 +173,7 @@ class MultiProductSystem(Component): for table in migrate_tables: cols = ','.join(table_columns[table]) self.log.info(Migrating table '%s' to a new schema, table) -db(CREATE TEMPORARY TABLE %s_temp AS SELECT %s FROM %s % +db(CREATE TABLE %s_temp AS SELECT %s FROM %s % (table, cols, table)) db(DROP TABLE %s % table) db_connector, _ = DatabaseManager(self.env)._get_connector()
svn commit: r1448190 - /incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py
Author: jure Date: Wed Feb 20 14:39:08 2013 New Revision: 1448190 URL: http://svn.apache.org/r1448190 Log: #356, enable product environment factory in setup Modified: incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py?rev=1448190r1=1448189r2=1448190view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py Wed Feb 20 14:39:08 2013 @@ -76,7 +76,8 @@ BASE_CONFIG = {'components': {'bhtheme.* 'theme': {'theme': 'bloodhound',}, 'trac': {'mainnav': ','.join(['dashboard', 'wiki', 'browser', 'tickets', 'newticket', 'timeline', - 'roadmap', 'search', 'admin']),}, + 'roadmap', 'search', 'admin']), +'environment_factory': '',}, 'project': {'footer': ('Visit Apache Bloodhound atbr /' 'a href=%(site)s%(site)s/a' % {'site': BH_PROJECT_SITE,}),}, @@ -214,7 +215,14 @@ class BloodhoundSetup(object): print (Warning: Environment already exists at %s. % new_env) self.writeconfig(tracini, [{'inherit': {'file': baseini},},]) -self.writeconfig(baseini, [BASE_CONFIG, accounts_config]) +base_config = dict(BASE_CONFIG) +environment_factory_path = os.path.abspath( + os.path.normpath( + os.path.join(options['sourcedir'], + 'bloodhound_multiproduct/multiproduct/hooks.py'))) +base_config['trac']['environment_factory'] = environment_factory_path + +self.writeconfig(baseini, [base_config, accounts_config]) if os.path.exists(digestfile): backupfile(digestfile) @@ -296,6 +304,9 @@ def handle_options(): # Base Trac Options parser.add_option('--project', dest='project', help='Set the top project name', default='main') +parser.add_option('--source_directory', dest='sourcedir', + help='Specify root source code directory', + default=os.path.normpath(os.path.join(os.getcwd(), '../'))), parser.add_option('--environments_directory', dest='envsdir', help='Set the directory to contain environments', default=os.path.join('bloodhound', 'environments'))
svn commit: r1447629 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py
Author: jure Date: Tue Feb 19 08:51:39 2013 New Revision: 1447629 URL: http://svn.apache.org/r1447629 Log: #355, clean-ups to make rational use of environment stub's logger and handler, patch t355_r1446579_cleanup_logging.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py?rev=1447629r1=1447628r2=1447629view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Tue Feb 19 08:51:39 2013 @@ -159,6 +159,21 @@ class MultiproductTestCase(unittest.Test env.log.info('%s test case: %s %s', '-' * 10, self.id(), '-' * 10) +# Clean-up logger instance and associated handler +# Otherwise large test suites will only result in ERROR eventually +# (at least in Unix systems) with messages +# +# TracError: Error reading '/path/to/file', make sure it is readable. +# error: /path/to/: Too many open files +self.addCleanup(self._teardown_test_log, env) + +def _teardown_test_log(self, env): +if env.log and hasattr(env, '_log_handler'): +env.log.removeHandler(env._log_handler) +env._log_handler.flush() +env._log_handler.close() +del env._log_handler + def _load_product_from_data(self, env, prefix): rEnsure test product with prefix is loaded
svn commit: r1447631 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web: ./ __init__.py session.py
Author: jure Date: Tue Feb 19 08:57:00 2013 New Revision: 1447631 URL: http://svn.apache.org/r1447631 Log: #355, test cases for web sessions, patch t355_r1446579_trac_test_web_session.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/session.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/__init__.py?rev=1447631view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/__init__.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/__init__.py Tue Feb 19 08:57:00 2013 @@ -0,0 +1,20 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound web API in product environments + Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/session.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/session.py?rev=1447631view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/session.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/web/session.py Tue Feb 19 08:57:00 2013 @@ -0,0 +1,58 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's ticket reports in product environments + +import unittest + +from trac.web.tests.session import SessionTestCase + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase + +class ProductSessionTestCase(SessionTestCase, MultiproductTestCase): + +@property +def env(self): +env = getattr(self, '_env', None) +if env is None: +self.global_env = self._setup_test_env() +self._upgrade_mp(self.global_env) +self._setup_test_log(self.global_env) +self._load_product_from_data(self.global_env, self.default_product) +self._env = env = ProductEnvironment( +self.global_env, self.default_product) +return env + +@env.setter +def env(self, value): +pass + +def tearDown(self): +self.global_env.reset_db() +self.global_env = self._env = None + + +def test_suite(): +return unittest.TestSuite([ +unittest.makeSuite(ProductSessionTestCase,'test'), +]) + +if __name__ == '__main__': +unittest.main(defaultTest='test_suite') +
svn commit: r1447742 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py
Author: jure Date: Tue Feb 19 14:53:22 2013 New Revision: 1447742 URL: http://svn.apache.org/r1447742 Log: Don't prefix custom (3rd party plugin) tables when running in global environment. Also fixes failing test cases after sync merge from trunk (r1447714) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1447742r1=1447741r2=1447742view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Tue Feb 19 14:53:22 2013 @@ -248,7 +248,7 @@ class BloodhoundProductSQLTranslate(obje return sql def _prefixed_table_entity_name(self, tablename): -return %s_%s % (self._product_prefix, tablename) +return %s_%s % (self._product_prefix, tablename) if self._product_prefix else tablename def _prefixed_table_view_sql(self, name, alias): return '(SELECT * FROM %s) AS %s' % (self._prefixed_table_entity_name(name),
svn commit: r1447257 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py
Author: jure Date: Mon Feb 18 13:51:05 2013 New Revision: 1447257 URL: http://svn.apache.org/r1447257 Log: #355, skip modules without __init__.py in test discovery, patch t355_r1446579_discovery_skip_no_init.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py?rev=1447257r1=1447256r2=1447257view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py Mon Feb 18 13:51:05 2013 @@ -50,7 +50,11 @@ class TestLoader(unittest.TestLoader): tests = [] while pending: mdlnm, loader, isdir = pending.popleft() -mdl = self._get_module_from_name(mdlnm) +try: +mdl = self._get_module_from_name(mdlnm) +except ImportError: +# Skip packages not having __init__.py +continue loader = getattr(mdl, self.testLoaderAttribute, None) or loader if mdlnm != package_or_requirement and hasattr(mdl, 'test_suite'): tests.append(mdl.test_suite())
svn commit: r1447258 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py
Author: jure Date: Mon Feb 18 13:53:53 2013 New Revision: 1447258 URL: http://svn.apache.org/r1447258 Log: #355, enhanced reuse of product environment logger, patch t355_r1446579_product_env_logging_inherit.diff applied (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1447258r1=1447257r2=1447258view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Mon Feb 18 13:53:53 2013 @@ -551,29 +551,40 @@ class ProductEnvironment(Component, Comp Initialize the logging sub-system. from trac.log import logger_handler_factory logtype = self.log_type +logfile = self.log_file +format = self.log_format + self.parent.log.debug(Log type '%s' for product '%s', logtype, self.product.prefix) + +# Force logger inheritance on identical configuration +if (logtype, logfile, format) == (self.parent.log_type, +self.parent.log_file, self.parent.log_format): +logtype = 'inherit' + if logtype == 'inherit': -logtype = self.parent.log_type -logfile = self.parent.log_file -format = self.parent.log_format +self.log = self.parent.log +self._log_handler = self.parent._log_handler +self.parent.log.warning(Inheriting parent logger for product '%s', +self.product.prefix) else: -logfile = self.log_file -format = self.log_format -if logtype == 'file' and not os.path.isabs(logfile): -logfile = os.path.join(self.get_log_dir(), logfile) -logid = 'Trac.%s.%s' % \ -(sha1(self.parent.path).hexdigest(), self.product.prefix) -if format: -format = format.replace('$(', '%(') \ - .replace('%(path)s', self.path) \ - .replace('%(basename)s', os.path.basename(self.path)) \ - .replace('%(project)s', self.project_name) -self.log, self._log_handler = logger_handler_factory( -logtype, logfile, self.log_level, logid, format=format) +if logtype == 'file' and not os.path.isabs(logfile): +logfile = os.path.join(self.get_log_dir(), logfile) +logid = 'Trac.%s.%s' % \ +(sha1(self.parent.path).hexdigest(), self.product.prefix) +if format: +format = format.replace('$(', '%(') \ + .replace('%(path)s', self.path) \ + .replace('%(basename)s', os.path.basename(self.path)) \ + .replace('%(project)s', self.project_name) +self.log, self._log_handler = logger_handler_factory( +logtype, logfile, self.log_level, logid, format=format) from trac import core, __version__ as VERSION -self.log.info('-' * 32 + ' environment startup [Trac %s] ' + '-' * 32, +self.log.info('-' * 32 + +' product %s environment startup [Trac %s] ' + +'-' * 32, + self.product.prefix, get_pkginfo(core).get('version', VERSION)) def needs_upgrade(self):
svn commit: r1447303 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests: env.py ticket/notification.py
Author: jure Date: Mon Feb 18 15:14:09 2013 New Revision: 1447303 URL: http://svn.apache.org/r1447303 Log: #355, test cases for ticket notifications, patch t355_r1444754_trac_test_ticket_notification.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/notification.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py?rev=1447303r1=1447302r2=1447303view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Mon Feb 18 15:14:09 2013 @@ -45,6 +45,13 @@ from multiproduct.api import MultiProduc from multiproduct.env import ProductEnvironment from multiproduct.model import Product +class ProductEnvironmentStub(ProductEnvironment): +rA product environment slightly tweaked for testing purposes + +def get_known_users(self, cnx=None): +return self.known_users + + # FIXME: Subclass TestCase explictly ? class MultiproductTestCase(unittest.TestCase): rMixin providing access to multi-product testing extensions. Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/notification.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/notification.py?rev=1447303view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/notification.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/notification.py Mon Feb 18 15:14:09 2013 @@ -0,0 +1,69 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's tickets notifications +in product environments + +import unittest + +from trac.tests.notification import SMTPThreadedServer +from trac.ticket.tests import notification + +from tests.env import ProductEnvironmentStub as ProductEnvironment +from tests.env import MultiproductTestCase + +class ProductNotificationTestCase(notification.NotificationTestCase, +MultiproductTestCase): + +@property +def env(self): +env = getattr(self, '_env', None) +if env is None: +self.global_env = self._setup_test_env() +self._upgrade_mp(self.global_env) +self._setup_test_log(self.global_env) +self._load_product_from_data(self.global_env, self.default_product) +self._env = env = ProductEnvironment( +self.global_env, self.default_product) +self._load_default_data(self._env) +return env + +@env.setter +def env(self, value): +pass + +def tearDown(self): +notification.notifysuite.tear_down() +self.global_env.reset_db() + +class ProductNotificationTestSuite(notification.NotificationTestSuite): +def __init__(self): +Start the local SMTP test server +notification.NotificationTestSuite.__init__(self) +self._tests = [] +self.addTest(unittest.makeSuite(ProductNotificationTestCase, 'test')) + + +def test_suite(): +if not notification.notifysuite: +notification.notifysuite = ProductNotificationTestSuite() +return notification.notifysuite + +if __name__ == '__main__': +unittest.TextTestRunner(verbosity=2).run(test_suite()) +
svn commit: r1447305 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/report.py
Author: jure Date: Mon Feb 18 15:16:24 2013 New Revision: 1447305 URL: http://svn.apache.org/r1447305 Log: #355, ticket report subsystem test cases, patch t355_r1444754_trac_test_ticket_report.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/report.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/report.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/report.py?rev=1447305view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/report.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/report.py Mon Feb 18 15:16:24 2013 @@ -0,0 +1,60 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's ticket reports in product environments + +import unittest + +from trac.ticket.tests.report import ReportTestCase + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase + +class ProductReportTestCase(ReportTestCase, MultiproductTestCase): + +@property +def env(self): +env = getattr(self, '_env', None) +if env is None: +self.global_env = self._setup_test_env() +self._upgrade_mp(self.global_env) +self._setup_test_log(self.global_env) +self._load_product_from_data(self.global_env, self.default_product) +self._env = env = ProductEnvironment( +self.global_env, self.default_product) +return env + +@env.setter +def env(self, value): +pass + +def tearDown(self): +self.global_env.reset_db() +self.global_env = self._env = None + + +def test_suite(): +return unittest.TestSuite([ +# TODO : Put report doctests in product context +# doctest.DocTestSuite(trac.ticket.report,) +unittest.makeSuite(ProductReportTestCase,'test'), +]) + +if __name__ == '__main__': +unittest.main(defaultTest='test_suite') +
svn commit: r1447322 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/env.py tests/attachment.py tests/env.py tests/wiki/ tests/wiki/__init__.py tests/wi
Author: jure Date: Mon Feb 18 15:24:57 2013 New Revision: 1447322 URL: http://svn.apache.org/r1447322 Log: #355, test cases for wiki modules, patch t355_r1444754_trac_test_wiki_model.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/model.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/attachment.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1447322r1=1447321r2=1447322view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Mon Feb 18 15:24:57 2013 @@ -217,7 +217,10 @@ class ProductEnvironment(Component, Comp top-level directory of the global environment will be the root of product file system area. -return os.path.join(self.parent.path, 'products', self.product.prefix) +folder = os.path.join(self.parent.path, 'products', self.product.prefix) +if not os.path.exists(folder): +os.makedirs(folder) +return folder @property def setup_participants(self): Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/attachment.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/attachment.py?rev=1447322r1=1447321r2=1447322view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/attachment.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/attachment.py Mon Feb 18 15:24:57 2013 @@ -44,7 +44,6 @@ class ProductAttachmentTestCase(Attachme self._setup_test_log(global_env) self._load_product_from_data(global_env, self.default_product) self.env = ProductEnvironment(global_env, self.default_product) -os.makedirs(self.env.path) # Root folder for default product environment self.attachments_dir = os.path.join(self.global_env.path, Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py?rev=1447322r1=1447321r2=1447322view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Mon Feb 18 15:24:57 2013 @@ -137,6 +137,8 @@ class MultiproductTestCase(unittest.Test env.path = tempfile.mkdtemp('bh-product-tempenv') else: env.path = path +if not os.path.exists(path): +os.mkdir(path) return env def _setup_test_log(self, env): Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/__init__.py?rev=1447322view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/__init__.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/wiki/__init__.py Mon Feb 18 15:24:57 2013 @@ -0,0 +1,20 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing
svn commit: r1447324 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview: ./ __init__.py api.py
Author: jure Date: Mon Feb 18 15:30:36 2013 New Revision: 1447324 URL: http://svn.apache.org/r1447324 Log: #355, MIME subsystem API test cases, patch t355_r1446579_trac_test_mimeview_api.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/api.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/__init__.py?rev=1447324view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/__init__.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/__init__.py Mon Feb 18 15:30:36 2013 @@ -0,0 +1,20 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's MIME API in product environments + Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/api.py?rev=1447324view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/api.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/api.py Mon Feb 18 15:30:36 2013 @@ -0,0 +1,63 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's ticket reports in product environments + +import unittest + +from trac.mimeview.tests.api import MimeviewTestCase + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase + +class ProductMimeviewTestCase(MimeviewTestCase, MultiproductTestCase): + +@property +def env(self): +env = getattr(self, '_env', None) +if env is None: +self.global_env = self._setup_test_env( +enable=['%s.%s' % (MimeviewTestCase.__module__, c) +for c in ['Converter0', 'Converter1', 'Converter2']] +) +self._upgrade_mp(self.global_env) +self._setup_test_log(self.global_env) +self._load_product_from_data(self.global_env, self.default_product) +self._env = env = ProductEnvironment( +self.global_env, self.default_product) +return env + +@env.setter +def env(self, value): +pass + +def tearDown(self): +self.global_env.reset_db() +self.global_env = self._env = None + + +def test_suite(): +return unittest.TestSuite([ +# TODO : Put MIME API doctests in product context +# doctest.DocTestSuite(trac.mimeview.api) +unittest.makeSuite(ProductMimeviewTestCase,'test'), +]) + +if __name__ == '__main__': +unittest.main(defaultTest='test_suite') +
svn commit: r1447328 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/patch.py
Author: jure Date: Mon Feb 18 15:32:08 2013 New Revision: 1447328 URL: http://svn.apache.org/r1447328 Log: #355, patch renderer test cases, patch t355_r1446579_trac_test_mimeview_patch.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/patch.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/patch.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/patch.py?rev=1447328view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/patch.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/patch.py Mon Feb 18 15:32:08 2013 @@ -0,0 +1,67 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's patch renderer in product environments + +import unittest + +from trac.mimeview.api import Mimeview +from trac.mimeview.patch import PatchRenderer +from trac.mimeview.tests.patch import PatchRendererTestCase +from trac.web.chrome import Chrome + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase + +class ProductPatchRendererTestCase(PatchRendererTestCase, MultiproductTestCase): + +@property +def env(self): +env = getattr(self, '_env', None) +if env is None: +self.global_env = self._setup_test_env( +enable=[Chrome, PatchRenderer] +) +self._upgrade_mp(self.global_env) +self._setup_test_log(self.global_env) +self._load_product_from_data(self.global_env, self.default_product) +self._env = env = ProductEnvironment( +self.global_env, self.default_product) +return env + +@env.setter +def env(self, value): +pass + +def setUp(self): +PatchRendererTestCase.setUp(self) +self.patch = Mimeview(self.env).renderers[0] + +def tearDown(self): +self.global_env.reset_db() +self.global_env = self._env = None + + +def test_suite(): +return unittest.TestSuite([ +unittest.makeSuite(ProductPatchRendererTestCase,'test'), +]) + +if __name__ == '__main__': +unittest.main(defaultTest='test_suite') +
svn commit: r1447334 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/pygments.py
Author: jure Date: Mon Feb 18 15:40:54 2013 New Revision: 1447334 URL: http://svn.apache.org/r1447334 Log: #355, Pygments renderer test cases, patch t355_r1446579_trac_test_mimeview_pygments.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/pygments.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/pygments.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/pygments.py?rev=1447334view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/pygments.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/mimeview/pygments.py Mon Feb 18 15:40:54 2013 @@ -0,0 +1,85 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's Pygments renderer in product environments + +import sys +if sys.version_info (2, 7): +import unittest2 as unittest +else: +import unittest + +from trac.mimeview.api import Mimeview +from trac.mimeview.pygments import PygmentsRenderer +from trac.mimeview.tests import pygments as test_pygments +from trac.web.chrome import Chrome + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase + +have_pygments = False + +if test_pygments.have_pygments: +super_class = test_pygments.PygmentsRendererTestCase +else: +class super_class(object): +test_empty_content = test_extra_mimetypes = test_newline_content = \ +test_python_hello = test_python_hello_mimeview = \ +lambda self : None + +class ProductPygmentsRendererTestCase(super_class, MultiproductTestCase): + +@property +def env(self): +env = getattr(self, '_env', None) +if env is None: +self.global_env = self._setup_test_env( +enable=[Chrome, PygmentsRenderer] +) +self._upgrade_mp(self.global_env) +self._setup_test_log(self.global_env) +self._load_product_from_data(self.global_env, self.default_product) +self._env = env = ProductEnvironment( +self.global_env, self.default_product) +return env + +@env.setter +def env(self, value): +pass + +def setUp(self): +test_pygments.PygmentsRendererTestCase.setUp(self) +self.pygments = Mimeview(self.env).renderers[0] + +def tearDown(self): +self.global_env.reset_db() +self.global_env = self._env = None + +ProductPygmentsRendererTestCase = unittest.skipUnless( +test_pygments.have_pygments, +'mimeview/tests/pygments (no pygments installed)' +)(ProductPygmentsRendererTestCase) + +def test_suite(): +return unittest.TestSuite([ +unittest.makeSuite(ProductPygmentsRendererTestCase,'test'), +]) + +if __name__ == '__main__': +unittest.main(defaultTest='test_suite') +
svn commit: r1446485 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct: dbcursor.py env.py
Author: jure Date: Fri Feb 15 09:42:04 2013 New Revision: 1446485 URL: http://svn.apache.org/r1446485 Log: #288, get_db_cnx and get_read_db properly implemented for ProductEnvironment Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1446485r1=1446484r2=1446485view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Fri Feb 15 09:42:04 2013 @@ -23,7 +23,7 @@ import sqlparse import sqlparse.tokens as Tokens import sqlparse.sql as Types -__all__ = ['BloodhoundIterableCursor'] +__all__ = ['BloodhoundIterableCursor', 'BloodhoundConnectionWrapper', 'ProductEnvContextManager'] SKIP_TABLES = ['system', 'auth_cookie', 'session', 'session_attribute', @@ -110,8 +110,27 @@ class BloodhoundConnectionWrapper(object return self.connection.executemany(query, params=params) def cursor(self): +return BloodhoundCursorWrapper(self.connection.cursor(), self.env) + +class BloodhoundCursorWrapper(object): + +def __init__(self, cursor, env): +self.cursor = cursor +self.env = env + +def __getattr__(self, name): +return getattr(self.cursor, name) + +def __iter__(self): +return self.cursor.__iter__() + +def execute(self, sql, args=None): +BloodhoundIterableCursor.set_env(self.env) +return self.cursor.execute(sql, args=args) + +def executemany(self, sql, args=None): BloodhoundIterableCursor.set_env(self.env) -return self.connection.cursor() +return self.cursor.executemany(sql, args=args) class ProductEnvContextManager(object): Wrap an underlying database context manager so as to keep track Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1446485r1=1446484r2=1446485view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Fri Feb 15 09:42:04 2013 @@ -24,7 +24,7 @@ from sqlite3 import OperationalError from trac.config import BoolOption, ConfigSection, Option from trac.core import Component, ComponentManager, implements -from trac.db.api import TransactionContextManager, QueryContextManager +from trac.db.api import TransactionContextManager, QueryContextManager, DatabaseManager from trac.util import get_pkginfo, lazy from trac.util.compat import sha1 from trac.versioncontrol import RepositoryManager @@ -32,7 +32,7 @@ from trac.web.href import Href from multiproduct.api import MultiProductSystem from multiproduct.config import Configuration -from multiproduct.dbcursor import ProductEnvContextManager +from multiproduct.dbcursor import ProductEnvContextManager, BloodhoundConnectionWrapper from multiproduct.model import Product import trac.env @@ -414,8 +414,7 @@ class ProductEnvironment(Component, Comp with env.db_query as db: ... -# share connection pool with global environment -return self.parent.get_db_cnx() +return BloodhoundConnectionWrapper(DatabaseManager(self).get_connection(), self) @lazy def db_exc(self): @@ -445,7 +444,7 @@ class ProductEnvironment(Component, Comp See `trac.db.api.get_read_db` for detailed documentation. -raise NotImplementedError('Deprecated method') +return BloodhoundConnectionWrapper(DatabaseManager(self).get_connection(readonly=True), self) @property def db_query(self):
svn commit: r1446498 - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_dashboard/bhdashboard/ bloodhound_dashboard/bhdashboard/layouts/ bloodhound_dashboard/bhdashboard/template
Author: jure Date: Fri Feb 15 10:30:14 2013 New Revision: 1446498 URL: http://svn.apache.org/r1446498 Log: Sync merge from trunk [This commit notification would consist of 79 parts, which exceeds the limit of 50 ones, so it was shortened to the summary.]
svn commit: r1446568 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py
Author: jure Date: Fri Feb 15 13:19:57 2013 New Revision: 1446568 URL: http://svn.apache.org/r1446568 Log: #288, populate global permission table on database upgrade Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1446568r1=1446567r2=1446568view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Fri Feb 15 13:19:57 2013 @@ -185,6 +185,10 @@ class MultiProductSystem(Component): self.log.info(Populating table '%s' for product '%s' ('%s'), table, product.name, product.prefix) db(INSERT INTO %s (%s, product) SELECT %s,'%s' FROM %s_temp % (table, cols, cols, product.prefix, table)) +if table == 'permission': +self.log.info(Populating table '%s' for global scope, table) +db(INSERT INTO %s (%s, product) SELECT %s,'%s' FROM %s_temp % + (table, cols, cols, '', table)) db(DROP TABLE %s_temp % table) db_installed_version = self._update_db_version(db, 3)
svn commit: r1446579 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py
Author: jure Date: Fri Feb 15 13:37:25 2013 New Revision: 1446579 URL: http://svn.apache.org/r1446579 Log: #288, fixup for get_read_db and get_db_cnx, using product envs when constructing DatabaseManager resulted in invalid db paths Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1446579r1=1446578r2=1446579view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Fri Feb 15 13:37:25 2013 @@ -414,7 +414,7 @@ class ProductEnvironment(Component, Comp with env.db_query as db: ... -return BloodhoundConnectionWrapper(DatabaseManager(self).get_connection(), self) +return BloodhoundConnectionWrapper(self.parent.get_db_cnx(), self) @lazy def db_exc(self): @@ -444,7 +444,7 @@ class ProductEnvironment(Component, Comp See `trac.db.api.get_read_db` for detailed documentation. -return BloodhoundConnectionWrapper(DatabaseManager(self).get_connection(readonly=True), self) +return BloodhoundConnectionWrapper(self.parent.get_read_db(), self) @property def db_query(self):
svn commit: r1446061 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/api.py multiproduct/env.py tests/ticket/batch.py
Author: jure Date: Thu Feb 14 08:21:37 2013 New Revision: 1446061 URL: http://svn.apache.org/r1446061 Log: #355, test cases for batch ticket updates, patch t355_r1444754_trac_test_ticket_batch.patch applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/batch.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1446061r1=1446060r2=1446061view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Thu Feb 14 08:21:37 2013 @@ -24,7 +24,7 @@ from genshi.builder import tag import copy from pkg_resources import resource_filename -from trac.config import PathOption +from trac.config import Option, PathOption from trac.core import Component, TracError, implements from trac.db import Table, Column, DatabaseManager, Index from trac.env import IEnvironmentSetupParticipant @@ -46,6 +46,19 @@ class MultiProductSystem(Component): implements(IEnvironmentSetupParticipant, ITemplateProvider, IPermissionRequestor, ITicketFieldProvider, IResourceManager) +product_base_url = Option('multiproduct', 'product_base_url', '', +A pattern used to generate the base URL of product environments, +e.g. the use cases listed in bh:wiki:/Proposals/BEP-0003#url-mapping . +Both absolute as well as relative URLs are supported. The later +will be resolved with respect to the base URL of the parent global +environment. The pattern may contain references to $(prefix)s and +$(name)s placeholders representing the product prefix and name +respectively . If nothing is set the following will be used +`products/$(prefix)s` + +Note the usage of `$(...)s` instead of `%(...)s` as the later form +would be interpreted by the ConfigParser itself. ) + product_config_parent = PathOption('inherit', 'multiproduct', '', The path to the configuration file containing the settings shared by sibling product environments. By default will inherit Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1446061r1=1446060r2=1446061view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Thu Feb 14 08:21:37 2013 @@ -22,7 +22,7 @@ import os.path from urlparse import urlsplit from sqlite3 import OperationalError -from trac.config import ConfigSection, Option +from trac.config import BoolOption, ConfigSection, Option from trac.core import Component, ComponentManager, implements from trac.db.api import TransactionContextManager, QueryContextManager from trac.util import get_pkginfo, lazy @@ -240,11 +240,25 @@ class ProductEnvironment(Component, Comp return '' -# TODO: Estimate product base URL considering global base URL, pattern, ... -base_url = '' - -# TODO: Estimate product base URL considering global base URL, pattern, ... -base_url_for_redirect = '' +base_url = Option('trac', 'base_url', '', +Reference URL for the Trac deployment. + +This is the base URL that will be used when producing +documents that will be used outside of the web browsing +context, like for example when inserting URLs pointing to Trac +resources in notification e-mails.) + +base_url_for_redirect = BoolOption('trac', 'use_base_url_for_redirect', +False, +Optionally use `[trac] base_url` for redirects. + +In some configurations, usually involving running Trac behind +a HTTP proxy, Trac can't automatically reconstruct the URL +that is used to access it. You may need to use this option to +force Trac to use the `base_url` setting also for +redirects. This introduces the obvious limitation that this +environment will only be usable when accessible from that URL, +as redirects are frequently used. ''(since 0.10.5)'') @property def
svn commit: r1444725 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/env.py tests/env.py tests/ticket/model.py
Author: jure Date: Mon Feb 11 10:24:23 2013 New Revision: 1444725 URL: http://svn.apache.org/r1444725 Log: #355, ticket model tests, patch t355_r1442601_trac_test_ticket_model.patch applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1444725r1=1444724r2=1444725view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Mon Feb 11 10:24:23 2013 @@ -105,7 +105,7 @@ class EnvironmentStub(trac.test.Environm self.parent = None self.product = None self.mpsystem = None -super(EnvironmentStub, self).__init__(default_data=default_data, +super(EnvironmentStub, self).__init__(default_data=False, enable=enable, disable=disable, path=path, destroying=destroying) # Apply multi product upgrades. This is required as the database proxy (translator) @@ -117,6 +117,9 @@ class EnvironmentStub(trac.test.Environm except OperationalError: pass +if default_data: +self.reset_db(default_data) + @staticmethod def enable_component_in_config(env, cls): Keep track of enabled state in configuration as well Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py?rev=1444725r1=1444724r2=1444725view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Mon Feb 11 10:24:23 2013 @@ -117,13 +117,14 @@ class MultiproductTestCase(unittest.Test # Test setup -def _setup_test_env(self, create_folder=True, path=None): +def _setup_test_env(self, create_folder=True, path=None, **kwargs): rPrepare a new test environment . Optionally set its path to a meaningful location (temp folder if `path` is `None`). -self.env = env = EnvironmentStub(enable=['trac.*', 'multiproduct.*']) +kwargs.setdefault('enable', ['trac.*', 'multiproduct.*']) +self.env = env = EnvironmentStub(**kwargs) if create_folder: if path is None: env.path = tempfile.mkdtemp('bh-product-tempenv') @@ -172,6 +173,20 @@ class MultiproductTestCase(unittest.Test # table remains but database version is deleted pass +def _load_default_data(self, env): +rInitialize environment with default data by respecting +values set in system table. + +from trac import db_default + +with env.db_transaction as db: +for table, cols, vals in db_default.get_data(db): +if table != 'system': +db.executemany('INSERT INTO %s (%s) VALUES (%s)' % +(table, ','.join(cols), +','.join(['%s' for c in cols])), +vals) + def _mp_setup(self): Shortcut for quick product-aware environment setup. Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py?rev=1444725view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py Mon Feb 11 10:24:23 2013 @@ -0,0 +1,62 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file
svn commit: r1444752 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py
Author: jure Date: Mon Feb 11 12:59:07 2013 New Revision: 1444752 URL: http://svn.apache.org/r1444752 Log: #355, t355_r1442601_trac_test_ticket_enum.patch applied (from Olemis), test cases for ticket enum fields Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py?rev=1444752r1=1444751r2=1444752view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/model.py Mon Feb 11 12:59:07 2013 @@ -18,11 +18,15 @@ Tests for Apache(TM) Bloodhound's tickets model in product environments +from datetime import datetime +import shutil import unittest +from trac.ticket.model import Milestone from trac.ticket.tests.model import TicketTestCase, TicketCommentTestCase, \ TicketCommentEditTestCase, TicketCommentDeleteTestCase, EnumTestCase, \ MilestoneTestCase, ComponentTestCase, VersionTestCase +from trac.util.datefmt import to_utimestamp, utc from multiproduct.env import ProductEnvironment from tests.env import MultiproductTestCase @@ -30,11 +34,8 @@ from tests.env import MultiproductTestCa class ProductTicketTestCase(TicketTestCase, MultiproductTestCase): def setUp(self): -self.global_env = self._setup_test_env(create_folder=False, -default_data=True) -self._upgrade_mp(self.global_env) -self._setup_test_log(self.global_env) -self._load_product_from_data(self.global_env, self.default_product) +self._mp_setup() +self.global_env = self.env self.env = ProductEnvironment(self.global_env, self.default_product) self._load_default_data(self.env) @@ -44,6 +45,72 @@ class ProductTicketTestCase(TicketTestCa def tearDown(self): self.global_env.reset_db() +self.env = self.global_env = None + +class ProductEnumTestCase(EnumTestCase, MultiproductTestCase): +def setUp(self): +self._mp_setup() +self.global_env = self.env +self.env = ProductEnvironment(self.global_env, self.default_product) +self._load_default_data(self.env) + +def tearDown(self): +self.global_env.reset_db() +self.env = self.global_env = None + +class ProductMilestoneTestCase(MilestoneTestCase, MultiproductTestCase): +def setUp(self): +self.global_env = self._setup_test_env(create_folder=True) +self._upgrade_mp(self.global_env) +self._setup_test_log(self.global_env) +self._load_product_from_data(self.global_env, self.default_product) + +self.env = ProductEnvironment(self.global_env, self.default_product) +self._load_default_data(self.env) + +def tearDown(self): +shutil.rmtree(self.global_env.path) +self.global_env.reset_db() +self.env = self.global_env = None + +def test_update_milestone(self): + +self.env.db_transaction(INSERT INTO milestone (name) VALUES ('Test')) + +milestone = Milestone(self.env, 'Test') +t1 = datetime(2001, 01, 01, tzinfo=utc) +t2 = datetime(2002, 02, 02, tzinfo=utc) +milestone.due = t1 +milestone.completed = t2 +milestone.description = 'Foo bar' +milestone.update() + +self.assertEqual( +[('Test', to_utimestamp(t1), to_utimestamp(t2), 'Foo bar', +self.default_product)], +self.env.db_query(SELECT * FROM milestone WHERE name='Test')) + +class ProductComponentTestCase(ComponentTestCase, MultiproductTestCase): +def setUp(self): +self._mp_setup() +self.global_env = self.env +self.env = ProductEnvironment(self.global_env, self.default_product) +self._load_default_data(self.env) + +def tearDown(self): +self.global_env.reset_db() +self.env = self.global_env = None + +class ProductVersionTestCase(VersionTestCase, MultiproductTestCase): +def setUp(self): +self._mp_setup() +self.global_env = self.env +self.env = ProductEnvironment(self.global_env, self.default_product) +self._load_default_data(self.env) + +def tearDown(self): +self.global_env.reset_db() +self.env = self.global_env = None def test_suite(): @@ -51,10 +118,10 @@ def test_suite(): suite.addTest(unittest.makeSuite(ProductTicketTestCase, 'test')) #suite.addTest(unittest.makeSuite(ProductTicketCommentEditTestCase, 'test')) #suite.addTest(unittest.makeSuite(ProductTicketCommentDeleteTestCase, 'test')) -#suite.addTest(unittest.makeSuite
svn commit: r1444754 [2/2] - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_dashboard/ bloodhound_multiproduct/ bloodhound_search/ bloodhound_search/bhsearch/ bloodhound_search
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_repositories.html URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_repositories.html?rev=1444754r1=1444753r2=1444754view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_repositories.html (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_repositories.html Mon Feb 11 13:05:18 2013 @@ -32,40 +32,40 @@ body h2Manage Repositories/h2 -py:def function=type_field(editable, selected=None) - div class=control-group -label class=control-label for=trac-typetypeType:/label -div class=controls - select class=input-medium size=1 id=trac-type name=type - disabled=${not editable or None} -option py:for=type in types value=$type selected=${type == selected or None}${type or _('(default)')}/option -option py:if=selected and selected not in types selected=selected$selected/option - /select - p class=help-block -span class=label label-infoDefault/span $default_type - /p +py:def function=type_field(editable, inline=False, selected=None) +div class=control-group py:strip=inline + label class=control-label for=trac-typeType:/label + div class=controls py:strip=inline +select class=input-medium size=1 id=trac-type name=type +disabled=${not editable or None} + option py:for=type in types value=$type selected=${type == selected or None}${type or _('(default)')}/option + option py:if=selected and selected not in types selected=selected$selected/option +/select +p class=help-inline + span class=label label-infoDefault/span $default_type +/p + /div /div - /div /py:def -py:def function=alias_field(editable, selected=None) - div class=control-group -label class=control-label for=trac-repositoryRepository:/label -div class=controls - select class=input-medium size=1 id=trac-repository - name=alias disabled=${not editable or None} -option py:for=(reponame, info) in sorted(repositories.iteritems()) py:if=not info.alias -value=$info.name selected=${info.name == selected or None}${info.name or _('(default)')}/option -option py:if=selected is not None and selected not in repositories selected=selected$selected/option - /select +py:def function=alias_field(editable, inline=False, selected=None) +div class=control-group py:strip=inline + label class=control-label for=trac-repositoryRepository:/label + div class=controls py:strip=inline +select class=input-medium size=1 id=trac-repository +name=alias disabled=${not editable or None} + option py:for=(reponame, info) in sorted(repositories.iteritems()) py:if=not info.alias + value=$info.name selected=${info.name == selected or None}${info.name or _('(default)')}/option + option py:if=selected is not None and selected not in repositories selected=selected$selected/option +/select + /div /div - /div /py:def py:choose test=view form py:when='detail' py:with=info = repositories[reponame] - class=well form-horizontal id=trac-modrepos method=post - action= +class=well form-horizontal id=trac-modrepos method=post +action= fieldset py:choose= py:with=readonly = not info.editable or None legend py:when=info.editableModify Repository:/legend legend py:otherwise=View Repository:/legend @@ -78,27 +78,27 @@ label class=control-label for=nameName:/label div class=controls input type=text id=name name=name value=$info.name - readonly=$readonly/ + readonly=$readonly/ /div /div py:choose py:when test='alias' in info - ${alias_field(info.editable, info.alias)} + ${alias_field(info.editable, selected=info.alias)} /py:when py:otherwise - ${type_field(info.editable, info.type)} +${type_field(info.editable, selected=info.type)} div class=control-group label class=control-label for=dirDirectory:/label div class=controls input type=text id=dir name=dir size=48 - value=$info.dir readonly=$readonly/ +
svn commit: r1443514 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests: db/ db/__init__.py db/api.py db/cursor.py db/mysql.py db/postgres.py db/util.py dbcursor.p
Author: jure Date: Thu Feb 7 14:50:28 2013 New Revision: 1443514 URL: http://svn.apache.org/viewvc?rev=1443514view=rev Log: #288, run trac.db.tests within product environment, skeleton(s) for further tests (mysql, postgres) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/cursor.py - copied unchanged from r1442598, incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/mysql.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/postgres.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/util.py Removed: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/__init__.py?rev=1443514view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/__init__.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/__init__.py Thu Feb 7 14:50:28 2013 @@ -0,0 +1,18 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/api.py?rev=1443514view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/api.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/db/api.py Thu Feb 7 14:50:28 2013 @@ -0,0 +1,51 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import unittest + +from trac.db.tests.api import ParseConnectionStringTestCase, StringsTestCase, ConnectionTestCase, WithTransactionTest + +from tests.db.util import ProductEnvMixin + +class ProductParseConnectionStringTestCase(ParseConnectionStringTestCase, ProductEnvMixin): +pass + +class ProductStringsTestCase(StringsTestCase, ProductEnvMixin): +pass + +class ProductConnectionTestCase(ConnectionTestCase, ProductEnvMixin): +pass + +class ProductWithTransactionTestCase(WithTransactionTest, ProductEnvMixin): +pass + +def suite(): +suite = unittest.TestSuite([ +unittest.makeSuite(ParseConnectionStringTestCase, 'test'), +unittest.makeSuite(StringsTestCase, 'test'), +unittest.makeSuite(ConnectionTestCase, 'test'), +unittest.makeSuite(WithTransactionTest, 'test'), +unittest.makeSuite(ProductParseConnectionStringTestCase, 'test'), +unittest.makeSuite(ProductStringsTestCase, 'test'), +unittest.makeSuite(ProductConnectionTestCase, 'test
svn commit: r1442889 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py
Author: jure Date: Wed Feb 6 10:32:11 2013 New Revision: 1442889 URL: http://svn.apache.org/viewvc?rev=1442889view=rev Log: #288, add cursor property to Bloodhound connection wrapper, patch t288_r1441419_sql_translate_cursor.patch (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1442889r1=1442888r2=1442889view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Wed Feb 6 10:32:11 2013 @@ -107,6 +107,10 @@ class BloodhoundConnectionWrapper(object BloodhoundIterableCursor.set_env(self.env) return self.connection.executemany(query, params=params) +def cursor(self): +BloodhoundIterableCursor.set_env(self.env) +return self.connection.cursor() + class ProductEnvContextManager(object): Wrap an underlying database context manager so as to keep track of (nested) product context.
svn commit: r1442890 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket: ./ __init__.py api.py
Author: jure Date: Wed Feb 6 10:33:38 2013 New Revision: 1442890 URL: http://svn.apache.org/viewvc?rev=1442890view=rev Log: #355, ticket API test cases, patch t355_r1437383_trac_test_ticket_api.patch (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/api.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/__init__.py?rev=1442890view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/__init__.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/__init__.py Wed Feb 6 10:33:38 2013 @@ -0,0 +1,20 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's tickets in product environments + Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/api.py?rev=1442890view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/api.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/ticket/api.py Wed Feb 6 10:33:38 2013 @@ -0,0 +1,92 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's tickets API in product environments + +import unittest + +from trac.perm import PermissionCache, PermissionSystem +from trac.test import Mock +from trac.ticket.api import TicketSystem +from trac.ticket.tests.api import TicketSystemTestCase + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase + +class ProductTicketSystemTestCase(TicketSystemTestCase, MultiproductTestCase): + +def setUp(self): +self.global_env = self._setup_test_env(create_folder=False) +self._upgrade_mp(self.global_env) +self._setup_test_log(self.global_env) +self._load_product_from_data(self.global_env, self.default_product) +self.env = ProductEnvironment(self.global_env, self.default_product) + +self.perm = PermissionSystem(self.env) +self.ticket_system = TicketSystem(self.env) +self.req = Mock() + +def tearDown(self): +self.global_env.reset_db() + +def test_custom_field_isolation(self): +self.env.config.set('ticket-custom', 'test', 'select') +self.env.config.set('ticket-custom', 'test.label', 'Test') +self.env.config.set('ticket-custom', 'test.value', '1') +self.env.config.set('ticket-custom', 'test.options', 'option1|option2') + +self.global_env.config.set('ticket-custom', 'test', 'text') +self.global_env.config.set('ticket-custom', 'test.label', 'Test') +self.global_env.config.set('ticket-custom', 'test.value', 'Foo bar') +self.global_env.config.set
svn commit: r1442575 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py
Author: jure Date: Tue Feb 5 13:20:30 2013 New Revision: 1442575 URL: http://svn.apache.org/viewvc?rev=1442575view=rev Log: #288, monkey patch trac.env.EnvironmentSetup.environment_created method to properly use direct transaction instead of project scoped one, also keep database multiproduct upgrade indicator when resetting database in test environment stub Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1442575r1=1442574r2=1442575view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Tue Feb 5 13:20:30 2013 @@ -72,6 +72,23 @@ class Environment(trac.env.Environment): # replace trac.env.Environment with Environment trac.env.Environment = Environment +def _environment_setup_environment_created(self): +Insert default data into the database. + +This code is copy pasted from trac.env.EnvironmentSetup with a slight change +of using direct (non-translated) transaction to setup default data. + +from trac import db_default +with self.env.db_direct_transaction as db: +for table, cols, vals in db_default.get_data(db): +db.executemany(INSERT INTO %s (%s) VALUES (%s) + % (table, ','.join(cols), ','.join(['%s' for c in cols])), + vals) +self._update_sample_config() + +# replace trac.env.EnvironmentSetup.environment_created with the patched version +trac.env.EnvironmentSetup.environment_created = _environment_setup_environment_created + # this must follow the monkey patch (trac.env.Environment) above, otherwise # trac.test.EnvironmentStub will not be correct as the class will derive from # not replaced trac.env.Environment @@ -87,18 +104,29 @@ class EnvironmentStub(trac.test.Environm path=None, destroying=False): self.parent = None self.product = None +self.mpsystem = None super(EnvironmentStub, self).__init__(default_data=default_data, enable=enable, disable=disable, path=path, destroying=destroying) # Apply multi product upgrades. This is required as the database proxy (translator) # is installed in any case, we want it to see multi-product enabled database # schema... -mpsystem = MultiProductSystem(self) +self.mpsystem = MultiProductSystem(self) try: -mpsystem.upgrade_environment() +self.mpsystem.upgrade_environment() except OperationalError: pass +def reset_db(self, default_data=None): +from multiproduct.api import DB_VERSION +schema_version = -1 +if self.mpsystem: +schema_version = self.mpsystem.get_version() +super(EnvironmentStub, self).reset_db(default_data=default_data) +if self.mpsystem and schema_version != -1: +with self.db_direct_transaction as db: +self.mpsystem._update_db_version(db, DB_VERSION) + # replace trac.test.EnvironmentStub trac.test.EnvironmentStub = EnvironmentStub
svn commit: r1441417 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py
Author: jure Date: Fri Feb 1 12:14:18 2013 New Revision: 1441417 URL: http://svn.apache.org/viewvc?rev=1441417view=rev Log: #355, test discovery patch t355_r1437383_pkgresources_discovery.diff (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py?rev=1441417r1=1441416r2=1441417view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/__init__.py Fri Feb 1 12:14:18 2013 @@ -15,3 +15,62 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. + +from collections import deque +from fnmatch import fnmatch +import sys +try: +import unittest2 as unittest +except ImportError: +import unittest + +from pkg_resources import resource_listdir, resource_isdir, resource_exists + + +class TestLoader(unittest.TestLoader): +testLoaderAttribute = '__testloader__' +testMethodPrefix = 'test' +sortTestMethodsUsing = cmp +suiteClass = unittest.TestSuite + +def discover_package(self, package_or_requirement, pattern='test*.py'): +Find and return all test modules from the specified package +directory, recursing into subdirectories to find them. Only test files +that match the pattern will be loaded. (Using shell style pattern +matching.) + +All test modules must be importable from the top level of the project +and registered with `pkg_resources` (e.g. via `setup.py develop`). + +If a target test module contains a '__testloader__' attribute then +related object will override current loader for every individual +module across the hierarchy. + +pending = deque([(package_or_requirement, self, True)]) +tests = [] +while pending: +mdlnm, loader, isdir = pending.popleft() +mdl = self._get_module_from_name(mdlnm) +loader = getattr(mdl, self.testLoaderAttribute, None) or loader +if mdlnm != package_or_requirement and hasattr(mdl, 'test_suite'): +tests.append(mdl.test_suite()) +else: +tests.append(loader.loadTestsFromModule(mdl)) +if isdir and resource_exists(mdlnm, '__init__.py'): +for fnm in resource_listdir(mdlnm, ''): +if resource_isdir(mdlnm, fnm): +pending.append( (mdlnm + '.' + fnm, loader, True) ) +elif any(fnm.endswith(ext) for ext in ['.py', '.pyc']) \ +and fnmatch(fnm, pattern) and fnm != '__init__.py': +submdlnm = mdlnm + '.' + fnm.rsplit('.', 1)[0] +pending.append( (submdlnm, loader, False) ) +return self.suiteClass(tests) + +def _get_module_from_name(self, name): +__import__(name) +return sys.modules[name] + +def test_suite(): +return TestLoader().discover_package('tests', pattern='*.py') + +
svn commit: r1441419 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/perm.py
Author: jure Date: Fri Feb 1 12:19:36 2013 New Revision: 1441419 URL: http://svn.apache.org/viewvc?rev=1441419view=rev Log: #355, Trac test cases rewritten for default permission data store, patch t355_r1437383_trac_test_perm.diff (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/perm.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/perm.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/perm.py?rev=1441419view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/perm.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/perm.py Fri Feb 1 12:19:36 2013 @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's product permissions subsystem + +import unittest + +from trac import perm +from trac.tests.perm import DefaultPermissionStoreTestCase + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase + + +class ProductDefaultPermissionStoreTestCase(DefaultPermissionStoreTestCase, +MultiproductTestCase): + +def setUp(self): +self.global_env = self._setup_test_env() +self._upgrade_mp(self.global_env) +self._setup_test_log(self.global_env) +self._load_product_from_data(self.env, self.default_product) +self.env = ProductEnvironment(self.env, self.default_product) + +self.store = perm.DefaultPermissionStore(self.env) + +def test_env_isolation(self): +global_env = self.global_env +env = self.env + +self._load_product_from_data(self.global_env, 'tp2') +env1 = ProductEnvironment(self.global_env, 'tp2') + +global_store = perm.DefaultPermissionStore(global_env) +store = perm.DefaultPermissionStore(env) +store1 = perm.DefaultPermissionStore(env1) + +global_env.db_transaction.executemany( +INSERT INTO permission VALUES (%s,%s), +[('dev', 'WIKI_MODIFY'), + ('dev', 'REPORT_ADMIN'), + ('john', 'dev')]) +env.db_transaction.executemany( +INSERT INTO permission VALUES (%s,%s), +[('dev', 'WIKI_VIEW'), + ('dev', 'REPORT_VIEW'), + ('john', 'dev')]) +env1.db_transaction.executemany( +INSERT INTO permission VALUES (%s,%s), +[('dev', 'TICKET_CREATE'), + ('dev', 'MILESTONE_VIEW'), + ('john', 'dev')]) + +self.assertEquals(['REPORT_ADMIN', 'WIKI_MODIFY'], + sorted(global_store.get_user_permissions('john'))) +self.assertEquals(['REPORT_VIEW', 'WIKI_VIEW'], + sorted(store.get_user_permissions('john'))) +self.assertEquals(['MILESTONE_VIEW', 'TICKET_CREATE'], + sorted(store1.get_user_permissions('john'))) + + +def test_suite(): +return unittest.makeSuite(ProductDefaultPermissionStoreTestCase,'test') + +if __name__ == '__main__': +unittest.main(defaultTest='test_suite') +
svn commit: r1440970 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct: api.py dbcursor.py env.py
Author: jure Date: Thu Jan 31 14:20:50 2013 New Revision: 1440970 URL: http://svn.apache.org/viewvc?rev=1440970view=rev Log: #288, properly keep connection context by using connection wrapper, apply multi-product upgrades on test database Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1440970r1=1440969r2=1440970view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Thu Jan 31 14:20:50 2013 @@ -97,7 +97,7 @@ class MultiProductSystem(Component): self.log.debug(upgrading existing environment for %s plugin. % PLUGIN_NAME) db_installed_version = self.get_version() -with self.env.db_transaction as db: +with self.env.db_direct_transaction as db: if db_installed_version 1: # Initial installation db(ALTER TABLE ticket ADD COLUMN product TEXT) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1440970r1=1440969r2=1440970view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Thu Jan 31 14:20:50 2013 @@ -32,10 +32,17 @@ SKIP_TABLES = ['system', 'auth_cookie', 'ticket_change', 'ticket_custom', 'report', 'bloodhound_product', 'bloodhound_productresourcemap', 'bloodhound_productconfig', + 'sqlite_master' ] TRANSLATE_TABLES = ['ticket', 'enum', 'component', 'milestone', 'version', 'permission', 'wiki'] PRODUCT_COLUMN = 'product' -DEFAULT_PRODUCT = '' +GLOBAL_PRODUCT = '' + +# Singleton used to mark translator as unset +class empty_translator(object): +pass + +translator_not_set = empty_translator() class BloodhoundIterableCursor(trac.db.util.IterableCursor): __slots__ = trac.db.util.IterableCursor.__slots__ + ['_translator'] @@ -43,20 +50,18 @@ class BloodhoundIterableCursor(trac.db.u def __init__(self, cursor, log=None): super(BloodhoundIterableCursor, self).__init__(cursor, log=log) -self._translator = None - -@property -def translator(self): -if not self._translator: -product_prefix = self.env.product.prefix if (self.env and self.env.product) else DEFAULT_PRODUCT -self._translator = BloodhoundProductSQLTranslate(SKIP_TABLES, - TRANSLATE_TABLES, - PRODUCT_COLUMN, - product_prefix) -return self._translator +self._translator = translator_not_set def _translate_sql(self, sql): -return self.translator.translate(sql) if (self.env and self.env.product) else sql +if self._translator is translator_not_set: +self._translator = None +if not self.env is None: +product_prefix = self.env.product.prefix if self.env.product else GLOBAL_PRODUCT +self._translator = BloodhoundProductSQLTranslate(SKIP_TABLES, + TRANSLATE_TABLES, + PRODUCT_COLUMN, + product_prefix) +return self._translator.translate(sql) if (self._translator is not None) else sql def execute(self, sql, args=None): return super(BloodhoundIterableCursor, self).execute(self._translate_sql(sql), args=args) @@ -76,6 +81,28 @@ class BloodhoundIterableCursor(trac.db.u def get_env(cls): return cls._tls.env +# replace trac.db.util.IterableCursor with BloodhoundIterableCursor +trac.db.util.IterableCursor = BloodhoundIterableCursor + +class BloodhoundConnectionWrapper(object): + +def __init__(self, connection
svn commit: r1440346 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_dashboard/bhdashboard/ bloodhound_multiproduct/multiproduct/
Author: jure Date: Wed Jan 30 11:14:17 2013 New Revision: 1440346 URL: http://svn.apache.org/viewvc?rev=1440346view=rev Log: #288, product environment context manager from t288_r1438538_sql_translate_global_env.diff (from olemis) and some changes to make it work properly Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py?rev=1440346r1=1440345r2=1440346view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py Wed Jan 30 11:14:17 2013 @@ -158,7 +158,7 @@ class ModelBase(object): sdata) for key in self._meta['key_fields']: -if not self._data[key]: +if self._data[key] is None: sdata = {'key':key} sdata.update(self._meta) raise TracError('%(key)s required for %(object_name)s' % Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1440346r1=1440345r2=1440346view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Wed Jan 30 11:14:17 2013 @@ -118,10 +118,13 @@ class MultiProductSystem(Component): db_installed_version = self._update_db_version(db, 2) if db_installed_version 3: -from multiproduct.dbcursor import DEFAULT_PRODUCT from multiproduct.model import Product import trac.db_default + +DEFAULT_PRODUCT = 'default' + migrate_tables = ['enum', 'component', 'milestone', 'version', 'permission', 'wiki'] + # extend trac default schema by adding product column and extending key with product table_defs = [copy.deepcopy(t) for t in trac.db_default.schema if t.name in migrate_tables] for t in table_defs: Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1440346r1=1440345r2=1440346view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Wed Jan 30 11:14:17 2013 @@ -35,7 +35,7 @@ SKIP_TABLES = ['system', 'auth_cookie', ] TRANSLATE_TABLES = ['ticket', 'enum', 'component', 'milestone', 'version', 'permission', 'wiki'] PRODUCT_COLUMN = 'product' -DEFAULT_PRODUCT = 'default' +DEFAULT_PRODUCT = '' class BloodhoundIterableCursor(trac.db.util.IterableCursor): __slots__ = trac.db.util.IterableCursor.__slots__ + ['_translator'] @@ -72,6 +72,63 @@ class BloodhoundIterableCursor(trac.db.u def set_env(cls, env): cls._tls.env = env +@classmethod +def get_env(cls): +return cls._tls.env + +class ProductEnvContextManager(object): +Wrap an underlying database context manager so as to keep track +of (nested) product context. + +def __init__(self, context, env=None): +Initialize product database context. + +:param context: Inner database context (e.g. `QueryContextManager`, +`TransactionContextManager` ) +:param env: An instance of either `trac.env.Environment` or +`multiproduct.env.ProductEnvironment` used to +reduce the scope of database queries. If set +to `None` then SQL queries will not be translated, +which is equivalent to having direct database access. + +self.db_context = context
svn commit: r1438019 - /incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/config.py
Author: jure Date: Thu Jan 24 14:34:53 2013 New Revision: 1438019 URL: http://svn.apache.org/viewvc?rev=1438019view=rev Log: #115, t115_r1436300_option_accessor.diff applied, polymorphic access to Section methods in Option accessor (from Olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/config.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/config.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/config.py?rev=1438019r1=1438018r2=1438019view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/config.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/config.py Thu Jan 24 14:34:53 2013 @@ -567,7 +567,9 @@ class Option(object): Descriptor for configuration options. registry = {} -accessor = Section.get + +def accessor(self, section, name, default): +return section.get(name, default) @staticmethod def get_registry(compmgr=None): @@ -615,17 +617,20 @@ class Option(object): class BoolOption(Option): Descriptor for boolean configuration options. -accessor = Section.getbool +def accessor(self, section, name, default): +return section.getbool(name, default) class IntOption(Option): Descriptor for integer configuration options. -accessor = Section.getint +def accessor(self, section, name, default): +return section.getint(name, default) class FloatOption(Option): Descriptor for float configuration options. -accessor = Section.getfloat +def accessor(self, section, name, default): +return section.getfloat(name, default) class ListOption(Option): @@ -673,7 +678,8 @@ class PathOption(Option): Relative paths are resolved to absolute paths using the directory containing the configuration file as the reference. -accessor = Section.getpath +def accessor(self, section, name, default): +return section.getpath(name, default) class ExtensionOption(Option):
svn commit: r1437357 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py
Author: jure Date: Wed Jan 23 11:59:38 2013 New Revision: 1437357 URL: http://svn.apache.org/viewvc?rev=1437357view=rev Log: Properly keep track of database versions, upgrade schema accordingly Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1437357r1=1437356r2=1437357view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Wed Jan 23 11:59:38 2013 @@ -68,43 +68,48 @@ class MultiProductSystem(Component): PLUGIN_NAME, DB_VERSION)) return db_installed_version DB_VERSION - + +def _update_db_version(self, db, version): +old_version = self.get_version() +if old_version != -1: +self.log.info(Updating multiproduct database schema from version %d + to %d % (old_version, version)) +db(UPDATE system SET value=%s + WHERE name=%s, (version, DB_SYSTEM_KEY)) +else: +self.log.info(Initial multiproduct database schema set to version %d % version) +db( +INSERT INTO system (name, value) VALUES ('%s','%s') + % (DB_SYSTEM_KEY, version)) +return version + def upgrade_environment(self, db_dummy=None): Installs or updates tables to current version self.log.debug(upgrading existing environment for %s plugin. % PLUGIN_NAME) db_installed_version = self.get_version() -#cursor = db.cursor() with self.env.db_transaction as db: -if db_installed_version 0: +if db_installed_version 1: # Initial installation -db( -INSERT INTO system (name, value) VALUES ('%s','%s') - % (DB_SYSTEM_KEY, DB_VERSION)) db(ALTER TABLE ticket ADD COLUMN product TEXT) self.log.debug(creating initial db tables for %s plugin. % PLUGIN_NAME) - db_connector, dummy = DatabaseManager(self.env)._get_connector() for table in self.SCHEMA: for statement in db_connector.to_sql(table): db(statement) -db_installed_version = self.get_version() - -if db_installed_version == 1: +db_installed_version = self._update_db_version(db, 1) + +if db_installed_version 2: from multiproduct.model import Product products = Product.select(self.env) for prod in products: db(UPDATE ticket SET product=%s WHERE product=%s, (prod.prefix, prod.name)) - -db(UPDATE system SET value=%s - WHERE name=%s, (DB_VERSION, DB_SYSTEM_KEY)) -self.log.info(Upgraded multiproduct db schema from version %d - to %d % (db_installed_version, DB_VERSION)) +db_installed_version = self._update_db_version(db, 2) -if db_installed_version == 2: -from trac import bloodhound +if db_installed_version 3: +from multiproduct.dbcursor import DEFAULT_PRODUCT migrate_tables = ['enum', 'component', 'milestone', 'version', 'wiki'] table_defs = [ Table('enum', key=('type', 'name', 'product'))[ @@ -143,7 +148,10 @@ class MultiProductSystem(Component): table_columns = dict() table_vals = {} for table in table_defs: -table_columns[table.name] = filter(lambda column: column != 'product', [column.name for column in list(filter(lambda t: t.name == table.name, table_defs)[0].columns)]) +table_columns[table.name] = filter(lambda column: column != 'product', + [column.name for column in +list(filter(lambda t: t.name == table.name, + table_defs)[0].columns)]) table_columns['bloodhound_product'] = ['prefix', 'name', 'description', 'owner'] def fetch_table(table
svn commit: r1437383 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py
Author: jure Date: Wed Jan 23 13:24:12 2013 New Revision: 1437383 URL: http://svn.apache.org/viewvc?rev=1437383view=rev Log: #115, ProductSetting table should be introduced as part of the environment upgrade and not as part of initial database schema so that existing environments can be upgraded Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1437383r1=1437382r2=1437383view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Wed Jan 23 13:24:12 2013 @@ -33,7 +33,7 @@ from trac.web.chrome import ITemplatePro from multiproduct.model import Product, ProductResourceMap, ProductSetting -DB_VERSION = 3 +DB_VERSION = 4 DB_SYSTEM_KEY = 'bloodhound_multi_product_version' PLUGIN_NAME = 'Bloodhound multi product' @@ -44,7 +44,7 @@ class MultiProductSystem(Component): IPermissionRequestor, ITicketFieldProvider, IResourceManager) SCHEMA = [mcls._get_schema() \ - for mcls in (Product, ProductResourceMap, ProductSetting)] + for mcls in (Product, ProductResourceMap)] def get_version(self): Finds the current version of the bloodhound database schema @@ -191,6 +191,14 @@ class MultiProductSystem(Component): insert_with_product(table, p[0]) db_installed_version = self._update_db_version(db, 3) +if db_installed_version 4: +self.log.debug(creating additional db tables for %s plugin. % + PLUGIN_NAME) +db_connector, dummy = DatabaseManager(self.env)._get_connector() +for statement in db_connector.to_sql(ProductSetting._get_schema()): +db(statement) +db_installed_version = self._update_db_version(db, 4) + # ITemplateProvider methods def get_templates_dirs(self): provide the plugin templates
svn commit: r1436256 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/dbcursor.py tests/dbcursor.py
Author: jure Date: Mon Jan 21 10:14:53 2013 New Revision: 1436256 URL: http://svn.apache.org/viewvc?rev=1436256view=rev Log: #288, don't reformat SQL after translate, test cases updated Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1436256r1=1436255r2=1436256view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Mon Jan 21 10:14:53 2013 @@ -622,14 +622,10 @@ class BloodhoundProductSQLTranslate(obje 'DROP': self._drop, } try: -format_sql = True -formatted_sql = lambda sql: sqlparse.format(sql.to_unicode(), reindent=True) \ -if format_sql \ -else sql.to_unicode() +formatted_sql = lambda sql: sql.to_unicode() sql_statement = sqlparse.parse(sql)[0] if '_' in sql: self._sqlparse_underline_hack(sql_statement) -#format_sql = False t = sql_statement.token_first() if t.match(Tokens.DML, dml_handlers.keys()): dml_handlers[t.value](sql_statement, t) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py?rev=1436256r1=1436255r2=1436256view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py Mon Jan 21 10:14:53 2013 @@ -24,7 +24,7 @@ from multiproduct.dbcursor import Bloodh # Test case data, each section consists of list of tuples of original and correctly translated SQL statements data = { # non-translated SELECTs -'system_select_nontranslated': [ +'system_select_nontranslated' : [ ( SELECT TYPE, id, filename, @@ -36,14 +36,14 @@ data = { AND time %s AND TYPE = %s, SELECT TYPE, id, - filename, - time, - description, - author -FROM attachment -WHERE time %s - AND time %s - AND TYPE = %s + filename, + time, + description, + author +FROM attachment +WHERE time %s + AND time %s + AND TYPE = %s ), ( SELECT id, @@ -58,21 +58,21 @@ WHERE time %s 'type', 'url'), SELECT id, - name, - value -FROM repository -WHERE name IN ('alias', - 'description', - 'dir', - 'hidden', - 'name', - 'type', - 'url') + name, + value +FROM repository +WHERE name IN ('alias', + 'description', + 'dir', + 'hidden', + 'name', + 'type', + 'url') ), ], # translated SELECTs -'system_select_translated': [ +'system_select_translated' : [ ( SELECT name, due, @@ -81,14 +81,11 @@ WHERE name IN ('alias', FROM milestone WHERE name=%s, SELECT name, - due, - completed, - description -FROM - (SELECT * - FROM milestone - WHERE product=PRODUCT) AS milestone -WHERE name=%s + due, + completed, + description +FROM (SELECT * FROM milestone WHERE product=PRODUCT) AS milestone +WHERE name=%s ), ( SELECT COALESCE(component, ''), @@ -96,12 +93,9 @@ WHERE name=%s FROM ticket GROUP BY COALESCE(component, ''), SELECT COALESCE(component, ''), - count(COALESCE(component, '')) -FROM - (SELECT * - FROM ticket - WHERE product=PRODUCT) AS ticket -GROUP BY COALESCE(component, '') + count(COALESCE(component, '')) +FROM (SELECT * FROM ticket WHERE product=PRODUCT) AS ticket +GROUP BY COALESCE(component
svn commit: r1436300 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/env.py tests/attachment.py tests/env.py
Author: jure Date: Mon Jan 21 12:25:38 2013 New Revision: 1436300 URL: http://svn.apache.org/viewvc?rev=1436300view=rev Log: #355 patch t355_r1434677_trac_test_attachments.diff applied (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/attachment.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1436300r1=1436299r2=1436300view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Mon Jan 21 12:25:38 2013 @@ -137,6 +137,14 @@ class ProductEnvironment(Component, Comp raise AttributeError('%s' object has no attribute '%s' % (self.__class__.__name__, attrnm)) +@lazy +def path(self): +The subfolder `./products/product prefix` relative to the +top-level directory of the global environment will be the root of +product file system area. + +return os.path.join(self.parent.path, 'products', self.product.prefix) + @property def setup_participants(self): Setup participants list for product environments will always @@ -267,7 +275,6 @@ class ProductEnvironment(Component, Comp self.parent = env self.product = product -self.path = self.parent.path self.systeminfo = [] self._href = self._abs_href = None Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/attachment.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/attachment.py?rev=1436300view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/attachment.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/attachment.py Mon Jan 21 12:25:38 2013 @@ -0,0 +1,72 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for Apache(TM) Bloodhound's attachments in product environments + +import shutil +import os.path +import unittest + +from trac.attachment import Attachment +from trac.test import EnvironmentStub +from trac.tests.attachment import AttachmentTestCase + +from multiproduct.env import ProductEnvironment +from tests.env import MultiproductTestCase + +class ProductAttachmentTestCase(AttachmentTestCase, MultiproductTestCase): + +def setUp(self): +try: +AttachmentTestCase.setUp(self) +except: +self.global_env = self.env +self.tearDown() +raise +else: +self.global_env = global_env = self.env +self._upgrade_mp(global_env) +self._setup_test_log(global_env) +self._load_product_from_data(global_env, self.default_product) +self.env = ProductEnvironment(global_env, self.default_product) +os.makedirs(self.env.path) + +# Root folder for default product environment +self.attachments_dir = os.path.join(self.global_env.path, +'products', self.default_product, 'files', 'attachments') + +def tearDown(self): +if os.path.exists(self.global_env.path): +shutil.rmtree(self.global_env.path) +self.env.reset_db() + +def test_product_path_isolation(self): +product_attachment = Attachment(self.env, 'ticket', '42') +global_attachment = Attachment(self.global_env, 'ticket', '42') +global_attachment.filename = product_attachment.filename = 'foo.txt' + +self.assertNotEqual
svn commit: r1435121 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/dbcursor.py tests/dbcursor.py
Author: jure Date: Fri Jan 18 12:54:44 2013 New Revision: 1435121 URL: http://svn.apache.org/viewvc?rev=1435121view=rev Log: #288, workaround for sqlparse underline (_) bug, added translated SQL test cases Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1435121r1=1435120r2=1435121view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Fri Jan 18 12:54:44 2013 @@ -87,6 +87,45 @@ class BloodhoundProductSQLTranslate(obje self._product_column = product_column self._product_prefix = product_prefix +def _sqlparse_underline_hack(self, token): +underline_token = lambda token: token.ttype == Tokens.Token.Error and token.value == '_' +identifier_token = lambda token: isinstance(token, Types.Identifier) or isinstance(token, Types.Token) +def prefix_token(token, prefix): +if identifier_token(token): +if isinstance(token, Types.IdentifierList): +token = token.tokens[0] +token.value = prefix + token.value +token.normalized = token.value.upper() if token.ttype in Tokens.Keyword \ +else token.value +if hasattr(token, 'tokens'): +if len(token.tokens) != 1: +raise Exception(Internal error, invalid token list) +token.tokens[0].value, token.tokens[0].normalized = token.value, token.normalized +return + +if hasattr(token, 'tokens') and token.tokens and len(token.tokens): +current = self._token_first(token) +while current: +leftover = None +if underline_token(current): +prefix = '' +while underline_token(current): +prefix += current.value +prev = current +current = self._token_next(token, current) +self._token_delete(token, prev) +# expression ends with _ ... push the token to parent +if not current: +return prev +prefix_token(current, prefix) +else: +leftover = self._sqlparse_underline_hack(current) +if leftover: +leftover.parent = token +self._token_insert_after(token, current, leftover) +current = leftover if leftover else self._token_next(token, current) +return None + def _select_table_name_alias(self, tokens): return filter(lambda t: t.upper() != 'AS', [t.value for t in tokens if t.value.strip()]) def _column_expression_name_alias(self, tokens): @@ -210,6 +249,8 @@ class BloodhoundProductSQLTranslate(obje alias = name parent.tokens[self._token_idx(parent, token)] = sqlparse.parse(self._prefixed_table_view_sql(name, alias))[0] +if table_name_callback: +table_name_callback(name) def inject_table_alias(token, alias): parent.tokens[self._token_idx(parent, token)] = sqlparse.parse(self._select_alias_sql(alias))[0] @@ -301,7 +342,7 @@ class BloodhoundProductSQLTranslate(obje fields_token = self._token_next(parent, token) if token.match(Tokens.Keyword, ['ALL', 'DISTINCT']) else token current_token, field_lists = self._select_expression_tokens(parent, fields_token, ['FROM'] + self._from_end_words) def handle_insert_table(table_name): -if table_name == insert_table: +if insert_table and insert_table in self._translate_tables: for keyword in [self._product_column, ',', ' ']: self._token_insert_before(parent, fields_token, Types.Token(Tokens.Keyword, keyword)) return @@ -581,14 +622,23 @@ class BloodhoundProductSQLTranslate(obje 'DROP': self._drop, } try: +format_sql = True +formatted_sql = lambda sql: sqlparse.format(sql.to_unicode(), reindent=True
svn commit: r1434677 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py
Author: jure Date: Thu Jan 17 14:14:01 2013 New Revision: 1434677 URL: http://svn.apache.org/viewvc?rev=1434677view=rev Log: #288 unit tests ... more will follow Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py?rev=1434677view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/dbcursor.py Thu Jan 17 14:14:01 2013 @@ -0,0 +1,1116 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +Tests for multiproduct/dbcursor.py + +import unittest +from multiproduct.dbcursor import BloodhoundProductSQLTranslate, SKIP_TABLES, TRANSLATE_TABLES, PRODUCT_COLUMN + +# Test case data, each section consists of list of tuples of original and correctly translated SQL statements +data = { +# non-translated SELECTs +'system_select_nontranslated': [ +( +SELECT TYPE, id, + filename, + time, + description, + author +FROM attachment +WHERE time %s + AND time %s + AND TYPE = %s, +SELECT TYPE, id, + filename, + time, + description, + author +FROM attachment +WHERE time %s + AND time %s + AND TYPE = %s +), +( +SELECT id, + name, + value +FROM repository +WHERE name IN ('alias', + 'description', + 'dir', + 'hidden', + 'name', + 'type', + 'url'), +SELECT id, + name, + value +FROM repository +WHERE name IN ('alias', + 'description', + 'dir', + 'hidden', + 'name', + 'type', + 'url') +), +], + +# translated SELECTs +'system_select_translated': [ +( +SELECT name, + due, + completed, + description +FROM milestone +WHERE name=%s, +SELECT name, + due, + completed, + description +FROM + (SELECT * + FROM milestone + WHERE product=PRODUCT) AS milestone +WHERE name=%s +), +( +SELECT COALESCE(component, ''), + count(COALESCE(component, '')) +FROM ticket +GROUP BY COALESCE(component, ''), +SELECT COALESCE(component, ''), + count(COALESCE(component, '')) +FROM + (SELECT * + FROM ticket + WHERE product=PRODUCT) AS ticket +GROUP BY COALESCE(component, '') +), +( +SELECT id, time, reporter, TYPE, summary, + description +FROM ticket +WHERE time=%s + AND time=%s, +SELECT id, time, reporter, TYPE, summary, + description +FROM + (SELECT * + FROM ticket + WHERE product=PRODUCT) AS ticket +WHERE time=%s + AND time=%s +), +( +SELECT t.id, + tc.time, + tc.author, + t.type, + t.summary, + tc.field, + tc.oldvalue, + tc.newvalue +FROM ticket_change tc +INNER JOIN ticket t ON t.id = tc.ticket +AND tc.time=13513751 +AND tc.time=13540571 +ORDER BY tc.time, +SELECT t.id, + tc.time, + tc.author, + t.type, + t.summary, + tc.field, + tc.oldvalue, + tc.newvalue +FROM ticket_change tc +INNER JOIN + (SELECT * + FROM ticket + WHERE product=PRODUCT) AS t ON t.id = tc.ticket +AND tc.time=13513751 +AND tc.time=13540571 +ORDER BY tc.time +), +( +SELECT COUNT(*) +FROM + (SELECT t.id AS id
svn commit: r1433893 - in /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct: multiproduct/env.py tests/config.py tests/env.py
Author: jure Date: Wed Jan 16 10:51:48 2013 New Revision: 1433893 URL: http://svn.apache.org/viewvc?rev=1433893view=rev Log: Applied #350 patch t350_r1433322_product_component_enable.diff (from olemis) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/config.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1433893r1=1433892r2=1433893view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Wed Jan 16 10:51:48 2013 @@ -29,6 +29,7 @@ from trac.util.compat import sha1 from trac.versioncontrol import RepositoryManager from trac.web.href import Href +from multiproduct.config import Configuration from multiproduct.model import Product from multiproduct.dbcursor import BloodhoundIterableCursor @@ -129,7 +130,7 @@ class ProductEnvironment(Component, Comp get_log_dir, backup try: -if attrnm == 'parent': +if attrnm in ('parent', '_rules'): raise AttributeError return getattr(self.parent, attrnm) except AttributeError: @@ -281,7 +282,23 @@ class ProductEnvironment(Component, Comp enable_component = trac.env.Environment.enable_component.im_func get_known_users = trac.env.Environment.get_known_users.im_func get_repository = trac.env.Environment.get_repository.im_func -is_component_enabled = trac.env.Environment.is_component_enabled.im_func + +is_component_enabled_local = trac.env.Environment.is_component_enabled.im_func + +def is_component_enabled(self, cls): +Implemented to only allow activation of components already +activated in the global environment that are in turn not disabled in +the configuration. + +This is called by the `ComponentManager` base class when a +component is about to be activated. If this method returns +`False`, the component does not get activated. If it returns +`None`, the component only gets activated if it is located in +the `plugins` directory of the environment. + +if not self.parent.is_component_enabled(cls): +return False +return self.is_component_enabled_local(cls) def get_db_cnx(self): Return a database connection from the connection pool @@ -427,8 +444,8 @@ class ProductEnvironment(Component, Comp def setup_config(self): Load the configuration object. -# FIXME: Install product-specific configuration object -self.config = self.parent.config +# FIXME: Inherit global environment setting ? +self.config = Configuration(self.parent, self.product.prefix) self.setup_log() def setup_log(self): Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/config.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/config.py?rev=1433893r1=1433892r2=1433893view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/config.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/config.py Wed Jan 16 10:51:48 2013 @@ -189,9 +189,9 @@ class ProductConfigTestCase(Configuratio self._test_with_inherit(testcb) -def suite(): +def test_suite(): return unittest.makeSuite(ProductConfigTestCase,'test') if __name__ == '__main__': -unittest.main(defaultTest='suite') +unittest.main(defaultTest='test_suite') Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py?rev=1433893r1=1433892r2=1433893view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Wed Jan 16 10:51:48 2013 @@ -34,6 +34,7 @@ else: from unittest.case import _AssertRaisesContext from trac.config import Option +from trac.core import Component from trac.env import
svn commit: r1433320 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_multiproduct/multiproduct/env.py bloodhound_multiproduct/tests/env.py bloodhound_theme/setup.py
Author: jure Date: Tue Jan 15 09:30:22 2013 New Revision: 1433320 URL: http://svn.apache.org/viewvc?rev=1433320view=rev Log: Towards #115, patch t115_r1431447_product_envs_bep3_p1.diff from olemis Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/setup.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1433320r1=1433319r2=1433320view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Tue Jan 15 09:30:22 2013 @@ -46,7 +46,7 @@ class Environment(trac.env.Environment): def __init__(self, path, create=False, options=[]): super(Environment, self).__init__(path, create=create, options=options) # global environment w/o parent -self.env = None +self.parent = None self.product = None @property @@ -82,11 +82,23 @@ class ProductEnvironment(Component, Comp implements(trac.env.ISystemInfoProvider) -@property -def system_info_providers(self): -rSystem info will still be determined by the global environment. - -return self.env.system_info_providers +def __getattr__(self, attrnm): +Forward attribute access request to parent environment. + +Initially this will affect the following members of +`trac.env.Environment` class: + +system_info_providers, secure_cookies, project_admin_trac_url, +get_system_info, get_version, get_templates_dir, get_templates_dir, +get_log_dir, backup + +try: +if attrnm == 'parent': +raise AttributeError +return getattr(self.parent, attrnm) +except AttributeError: +raise AttributeError('%s' object has no attribute '%s' % +(self.__class__.__name__, attrnm)) @property def setup_participants(self): @@ -116,12 +128,6 @@ class ProductEnvironment(Component, Comp base_url_for_redirect = '' @property -def secure_cookies(self): -Restrict cookies to HTTPS connections. - -return self.env.secure_cookies - -@property def project_name(self): Name of the product. @@ -139,24 +145,18 @@ class ProductEnvironment(Component, Comp which the `base_url` resides. This is used in notification e-mails. -return self.env.project_url +# FIXME: Should products have different values i.e. config option ? +return self.parent.project_url project_admin = Option('project', 'admin', '', E-Mail address of the product's leader / administrator.) @property -def project_admin_trac_url(self): -Base URL of a Trac instance where errors in this Trac -should be reported. - -return self.env.project_admin_trac_url - -# FIXME: Should products have different values i.e. config option ? -@property def project_footer(self): Page footer text (right-aligned). -return self.env.project_footer +# FIXME: Should products have different values i.e. config option ? +return self.parent.project_footer project_icon = Option('project', 'icon', 'common/trac.ico', URL of the icon of the product.) @@ -207,6 +207,12 @@ class ProductEnvironment(Component, Comp :param product: product prefix or an instance of multiproduct.model.Product +if not isinstance(env, trac.env.Environment): +raise TypeError(Initializer must be called with \ +trac.env.Environment instance as first argument \ +(got %s instance instead) % +(self._component_name(env.__class__),) ) + ComponentManager.__init__(self) if isinstance(product, Product): @@ -221,9 +227,9 @@ class ProductEnvironment(Component, Comp product, products) raise LookupError(Missing product %s % (product,)) -self.env = env +self.parent = env self.product = product -self.path = self.env.path +self.path = self.parent.path self.systeminfo = [] self._href = self._abs_href = None @@ -231,16 +237,12 @@ class ProductEnvironment(Component, Comp # ISystemInfoProvider methods -def get_system_info(self): -return
svn commit: r1433448 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_multiproduct/multiproduct/ trac/trac/ trac/trac/web/
Author: jure Date: Tue Jan 15 14:57:49 2013 New Revision: 1433448 URL: http://svn.apache.org/viewvc?rev=1433448view=rev Log: Towards #322, #323, install global hooks from trac/__init__.py (hardcoded atm), provide EnvironmentStub replacement for tests to run properly Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/main.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?rev=1433448r1=1433447r2=1433448view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Tue Jan 15 14:57:49 2013 @@ -16,7 +16,7 @@ # specific language governing permissions and limitations # under the License. -from trac.db.util import IterableCursor +import trac.db.util from trac.util import concurrency import sqlparse @@ -37,8 +37,8 @@ TRANSLATE_TABLES = ['ticket', 'enum', 'c PRODUCT_COLUMN = 'product' DEFAULT_PRODUCT = 'default' -class BloodhoundIterableCursor(IterableCursor): -__slots__ = IterableCursor.__slots__ + ['_translator'] +class BloodhoundIterableCursor(trac.db.util.IterableCursor): +__slots__ = trac.db.util.IterableCursor.__slots__ + ['_translator'] _tls = concurrency.ThreadLocal(env=None) def __init__(self, cursor, log=None): @@ -72,6 +72,9 @@ class BloodhoundIterableCursor(IterableC def set_env(cls, env): cls._tls.env = env +# replace trac.db.util.IterableCursor with BloodhoundIterableCursor +trac.db.util.IterableCursor = BloodhoundIterableCursor + class BloodhoundProductSQLTranslate(object): _join_statements = ['LEFT JOIN', 'LEFT OUTER JOIN', 'RIGHT JOIN', 'RIGHT OUTER JOIN', Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1433448r1=1433447r2=1433448view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Tue Jan 15 14:57:49 2013 @@ -29,11 +29,11 @@ from trac.util.compat import sha1 from trac.versioncontrol import RepositoryManager from trac.web.href import Href -import trac.env - from multiproduct.model import Product from multiproduct.dbcursor import BloodhoundIterableCursor +import trac.env + class Environment(trac.env.Environment): Bloodhound environment manager @@ -44,10 +44,11 @@ class Environment(trac.env.Environment): (in the context of selected product). def __init__(self, path, create=False, options=[]): -super(Environment, self).__init__(path, create=create, options=options) -# global environment w/o parent +# global environment w/o parent, set these two before super.__init__ +# as database access can take place within trac.env.Environment self.parent = None self.product = None +super(Environment, self).__init__(path, create=create, options=options) @property def db_query(self): @@ -59,6 +60,41 @@ class Environment(trac.env.Environment): BloodhoundIterableCursor.set_env(self) return super(Environment, self).db_transaction +# replace trac.env.Environment with Environment +trac.env.Environment = Environment + +# this must follow the monkey patch (trac.env.Environment) above, otherwise +# trac.test.EnvironmentStub will not be correct as the class will derive from +# not replaced trac.env.Environment +import trac.test + +class EnvironmentStub(trac.test.EnvironmentStub): +Bloodhound test environment stub + +This class replaces trac.test.EnvironmentStub and extends it with parent and product +properties (same case as with the Environment). + +def __init__(self, default_data=False, enable=None, disable=None, + path=None, destroying=False): +self.parent = None +self.product = None +super
svn commit: r1432059 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_multiproduct/multiproduct/env.py bloodhound_multiproduct/multiproduct/hooks.py trac/trac/hooks.py trac/trac/w
Author: jure Date: Fri Jan 11 14:20:22 2013 New Revision: 1432059 URL: http://svn.apache.org/viewvc?rev=1432059view=rev Log: Towards integrating #115 and #288, still wip Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/main.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1432059r1=1432058r2=1432059view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Fri Jan 11 14:20:22 2013 @@ -24,15 +24,41 @@ from urlparse import urlsplit from trac.config import ConfigSection, Option from trac.core import Component, ComponentManager, implements from trac.db.api import with_transaction -from trac.env import Environment, ISystemInfoProvider from trac.util import get_pkginfo, lazy from trac.util.compat import sha1 from trac.versioncontrol import RepositoryManager from trac.web.href import Href +import trac.env + from multiproduct.model import Product from multiproduct.dbcursor import BloodhoundIterableCursor +class Environment(trac.env.Environment): +Bloodhound environment manager + +This class is intended as monkey-patch replacement for +trac.env.Environment. Required database access methods/properties +are replaced to provide global view of the database in contrast +to ProductEnvironment that features per-product view of the database +(in the context of selected product). + +def __init__(self, path, create=False, options=[]): +super(Environment, self).__init__(path, create=create, options=options) +# global environment w/o parent +self.env = None +self.product = None + +@property +def db_query(self): +BloodhoundIterableCursor.set_env(self) +return super(Environment, self).db_query + +@property +def db_transaction(self): +BloodhoundIterableCursor.set_env(self) +return super(Environment, self).db_transaction + class ProductEnvironment(Component, ComponentManager): Bloodhound product-aware environment manager. @@ -54,7 +80,7 @@ class ProductEnvironment(Component, Comp See https://issues.apache.org/bloodhound/wiki/Proposals/BEP-0003 -implements(ISystemInfoProvider) +implements(trac.env.ISystemInfoProvider) @property def system_info_providers(self): @@ -197,6 +223,7 @@ class ProductEnvironment(Component, Comp self.env = env self.product = product +self.path = self.env.path self.systeminfo = [] self._href = self._abs_href = None @@ -208,14 +235,14 @@ class ProductEnvironment(Component, Comp return self.env.get_system_info() # Same as parent environment's . Avoid duplicated code -component_activated = Environment.component_activated.im_func -_component_name = Environment._component_name.im_func -_component_rules = Environment._component_rules -enable_component = Environment.enable_component.im_func -get_known_users = Environment.get_known_users.im_func -get_systeminfo = Environment.get_system_info.im_func -get_repository = Environment.get_repository.im_func -is_component_enabled = Environment.is_component_enabled.im_func +component_activated = trac.env.Environment.component_activated.im_func +_component_name = trac.env.Environment._component_name.im_func +_component_rules = trac.env.Environment._component_rules +enable_component = trac.env.Environment.enable_component.im_func +get_known_users = trac.env.Environment.get_known_users.im_func +get_systeminfo = trac.env.Environment.get_system_info.im_func +get_repository = trac.env.Environment.get_repository.im_func +is_component_enabled = trac.env.Environment.is_component_enabled.im_func def get_db_cnx(self): Return a database connection from the connection pool Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py?rev=1432059r1=1432058r2=1432059view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py (original
svn commit: r1432086 - /incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py
Author: jure Date: Fri Jan 11 15:16:39 2013 New Revision: 1432086 URL: http://svn.apache.org/viewvc?rev=1432086view=rev Log: #323, only install global hooks once Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py?rev=1432086r1=1432085r2=1432086view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py Fri Jan 11 15:16:39 2013 @@ -20,6 +20,7 @@ import imp import inspect from config import Configuration +from util.concurrency import threading __all__ = ['environment_factory', 'install_global_hooks'] @@ -53,14 +54,26 @@ def _get_hook_class(env_path, hook_path, return cls return None +_global_hooks_installed = False +_global_hooks_lock = threading.Lock() + def install_global_hooks(environ, env_path): -config = _get_config(env_path) -hook_paths = config.get('trac', 'global_hooks', default=None) -if hook_paths: -for hook_path in hook_paths.split(','): -cls = _get_hook_class(env_path, hook_path, GlobalHooksBase) -if cls: -cls().install_hooks(environ, env_path) +global _global_hooks_installed, _global_hooks_lock +if _global_hooks_installed: +return +_global_hooks_lock.acquire() +try: +if not _global_hooks_installed: +config = _get_config(env_path) +hook_paths = config.get('trac', 'global_hooks', default=None) +if hook_paths: +for hook_path in hook_paths.split(','): +cls = _get_hook_class(env_path, hook_path, GlobalHooksBase) +if cls: +cls().install_hooks(environ, env_path) +_global_hooks_installed = True +finally: +_global_hooks_lock.release() return def environment_factory(env):
svn commit: r1432088 - /incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py
Author: jure Date: Fri Jan 11 15:17:56 2013 New Revision: 1432088 URL: http://svn.apache.org/viewvc?rev=1432088view=rev Log: #115 and #288 integration, make product cursors actually work Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1432088r1=1432087r2=1432088view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Fri Jan 11 15:17:56 2013 @@ -23,7 +23,7 @@ from urlparse import urlsplit from trac.config import ConfigSection, Option from trac.core import Component, ComponentManager, implements -from trac.db.api import with_transaction +from trac.db.api import with_transaction, TransactionContextManager, QueryContextManager from trac.util import get_pkginfo, lazy from trac.util.compat import sha1 from trac.versioncontrol import RepositoryManager @@ -328,7 +328,7 @@ class ProductEnvironment(Component, Comp `db_transaction`). BloodhoundIterableCursor.set_env(self) -return self.env.db_query +return QueryContextManager(self.env) @property def db_transaction(self): @@ -364,7 +364,7 @@ class ProductEnvironment(Component, Comp (`db_query` or `db_transaction`). BloodhoundIterableCursor.set_env(self) -return self.env.db_transaction +return TransactionContextManager(self.env) def shutdown(self, tid=None): Close the environment.
svn commit: r1431351 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_multiproduct/multiproduct/ trac/trac/bloodhound/ trac/trac/web/
Author: jure Date: Thu Jan 10 13:38:13 2013 New Revision: 1431351 URL: http://svn.apache.org/viewvc?rev=1431351view=rev Log: Towards integrating #115 and #288, still wip Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py - copied, changed from r1430286, incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py Removed: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/ Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/standalone.py Copied: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py (from r1430286, incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py) URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py?p2=incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.pyp1=incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.pyr1=1430286r2=1431351rev=1431351view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/dbcursor.py Thu Jan 10 13:38:13 2013 @@ -35,6 +35,7 @@ SKIP_TABLES = ['system', 'permission', ' ] TRANSLATE_TABLES = ['ticket', 'enum', 'component', 'milestone', 'version', 'wiki'] PRODUCT_COLUMN = 'product' +DEFAULT_PRODUCT = 'default' class BloodhoundIterableCursor(IterableCursor): __slots__ = IterableCursor.__slots__ + ['_translator'] @@ -47,16 +48,15 @@ class BloodhoundIterableCursor(IterableC @property def translator(self): if not self._translator: -from env import DEFAULT_PRODUCT -product = self.env.product_scope if self.env else DEFAULT_PRODUCT +product_prefix = self.env.product.prefix if (self.env and self.env.product) else DEFAULT_PRODUCT self._translator = BloodhoundProductSQLTranslate(SKIP_TABLES, TRANSLATE_TABLES, PRODUCT_COLUMN, - product) + product_prefix) return self._translator def _translate_sql(self, sql): -return self.translator.translate(sql) if (self.env and not self.env.product_aware) else sql +return self.translator.translate(sql) if (self.env and self.env.product) else sql def execute(self, sql, args=None): return super(BloodhoundIterableCursor, self).execute(self._translate_sql(sql), args=args) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py?rev=1431351r1=1431350r2=1431351view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py Thu Jan 10 13:38:13 2013 @@ -19,15 +19,19 @@ Bloodhound product environment and related APIs import os.path +from urlparse import urlsplit from trac.config import ConfigSection, Option -from trac.core import Component, ComponentManager, ExtensionPoint, \ -implements, TracError +from trac.core import Component, ComponentManager, implements +from trac.db.api import with_transaction from trac.env import Environment, ISystemInfoProvider from trac.util import get_pkginfo, lazy from trac.util.compat import sha1 +from trac.versioncontrol import RepositoryManager +from trac.web.href import Href from multiproduct.model import Product +from multiproduct.dbcursor import BloodhoundIterableCursor class ProductEnvironment(Component, ComponentManager): Bloodhound product-aware environment manager. @@ -232,9 +236,8 @@ class ProductEnvironment(Component, Comp with env.db_query as db: ... -# TODO: Install database schema proxy with limited scope (see #288) -#return DatabaseManager(self).get_connection() -raise NotImplementedError +# share connection pool with global environment +return self.env.get_db_cnx() @lazy def db_exc(self): @@ -251,21
svn commit: r1430768 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_dashboard/bhdashboard/ bloodhound_multiproduct/multiproduct/ bloodhound_multiproduct/tests/
Author: jure Date: Wed Jan 9 10:24:22 2013 New Revision: 1430768 URL: http://svn.apache.org/viewvc?rev=1430768view=rev Log: Product specific environment configuration, ticket #115 (from Olemis) Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/config.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/env.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/config.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/tests/env.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/model.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py?rev=1430768r1=1430767r2=1430768view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_dashboard/bhdashboard/model.py Wed Jan 9 10:24:22 2013 @@ -118,8 +118,9 @@ class ModelBase(object): self._update_from_row(row) break else: -raise ResourceNotFound('No %(object_name)s with %(where)s' % -sdata) +raise ResourceNotFound( +('No %(object_name)s with %(where)s' % sdata) +% tuple(values)) def delete(self): Deletes the matching record from the database @@ -145,14 +146,15 @@ class ModelBase(object): for k in self._meta['key_fields']]))): sdata = {'keys':','.join([%s='%s' % (k, self._data[k]) for k in self._meta['key_fields']])} -elif len(self.select(self._env, where = +elif self._meta['unique_fields'] and len(self.select(self._env, where = dict([(k,self._data[k]) for k in self._meta['unique_fields']]))): sdata = {'keys':','.join([%s='%s' % (k, self._data[k]) for k in self._meta['unique_fields']])} if sdata: sdata.update(self._meta) -raise TracError('%(object_name)s %(keys)s already exists' % +sdata['values'] = self._data +raise TracError('%(object_name)s %(keys)s already exists %(values)s' % sdata) for key in self._meta['key_fields']: @@ -208,7 +210,7 @@ class ModelBase(object): TicketSystem(self._env).reset_ticket_fields() @classmethod -def select(cls, env, db=None, where=None): +def select(cls, env, db=None, where=None, limit=None): Query the database to get a set of records back rows = [] fields = cls._meta['key_fields']+cls._meta['non_key_fields'] @@ -219,7 +221,11 @@ class ModelBase(object): wherestr, values = dict_to_kv_str(where) if wherestr: wherestr = ' WHERE ' + wherestr -for row in env.db_query(sql + wherestr, values): +if limit is not None: +limitstr = ' LIMIT ' + str(int(limit)) +else: +limitstr = '' +for row in env.db_query(sql + wherestr + limitstr, values): # we won't know which class we need until called model = cls.__new__(cls) data = dict([(fields[i], row[i]) for i in range(len(fields))]) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1430768r1=1430767r2=1430768view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Wed Jan 9 10:24:22 2013 @@ -31,7 +31,7 @@ from trac.ticket.api import ITicketField from trac.util.translation import _, N_ from trac.web.chrome import ITemplateProvider -from multiproduct.model import Product, ProductResourceMap +from multiproduct.model import Product, ProductResourceMap, ProductSetting DB_VERSION = 3 DB_SYSTEM_KEY = 'bloodhound_multi_product_version' @@ -43,9 +43,9 @@ class
svn commit: r1430262 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_multiproduct/multiproduct/hooks.py trac/trac/hooks.py trac/trac/web/main.py
Author: jure Date: Tue Jan 8 12:55:37 2013 New Revision: 1430262 URL: http://svn.apache.org/viewvc?rev=1430262view=rev Log: Towards #322, #323, support for environment factory/global hooks added to trac Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/main.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py?rev=1430262view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/hooks.py Tue Jan 8 12:55:37 2013 @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from trac.hooks import EnvironmentFactoryBase, GlobalHooksBase + +class MultiProductEnvironmentFactory(EnvironmentFactoryBase): +def open_environment(self, environ, env_path, use_cache=False): +return None + +class MultiProductGlobalHooks(GlobalHooksBase): +def install_hooks(self, environ, env_path): +return Added: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py?rev=1430262view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/hooks.py Tue Jan 8 12:55:37 2013 @@ -0,0 +1,68 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import os +import imp +import inspect + +from config import Configuration + +__all__ = ['environment_factory', 'install_global_hooks'] + +class EnvironmentFactoryBase(object): +def open_environment(self, environ, env_path, use_cache=False): +return None + +class GlobalHooksBase(object): +def install_hooks(self, environ, env_path): +return + +def _get_plugins_dir(env_path): +return os.path.normcase(os.path.realpath(os.path.join(env_path, 'plugins'))) + +def _get_config(env_path): +return Configuration(os.path.join(env_path, 'conf', 'trac.ini'), + {'envname': os.path.basename(env_path)}) + +def _hook_load(env_path, hook_path): +hook_name = os.path.basename(hook_path[:-3]) +plugins_dir = _get_plugins_dir(env_path) +load_path = os.path.join(plugins_dir, hook_path) +module = imp.load_source(hook_name, load_path) +return module + +def _get_hook_class(env_path, hook_path, class_type): +module = _hook_load(env_path, hook_path) +for (name, cls) in inspect.getmembers(module, inspect.isclass): +if issubclass(cls, class_type): +return cls +return None + +def environment_factory(environ, env_path): +config = _get_config(env_path) +hook_path = config.get('hooks', 'environment_factory', default=None) +return _get_hook_class(env_path, hook_path, EnvironmentFactoryBase) if hook_path else None + +def install_global_hooks(environ, env_path
svn commit: r1430304 [2/2] - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_dashboard/bhdashboard/ bloodhound_dashboard/bhdashboard/widgets/ bloodhound_multiproduct/multiproduc
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bloodhound_theme.html URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bloodhound_theme.html?rev=1430304r1=1430303r2=1430304view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bloodhound_theme.html (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bloodhound_theme.html Tue Jan 8 14:37:00 2013 @@ -104,45 +104,37 @@ option py:if=field.optional/option option py:for=option in field.options selected=${value == option or None} +value = $option py:content=option/option optgroup py:for=optgroup in field.optgroups py:if=optgroup.options label=${optgroup.label} option py:for=option in optgroup.options selected=${value == option or None} + value = $option py:content=option/option /optgroup /select /py:def py:def function=qct_box() - label for=field-summarySummary/label - input type=text id=field-summary - name=field_summary placeholder=Ticket summary / + div +label for=field-summarySummary/label +input type=text id=field-summary +name=field_summary placeholder=Ticket summary / + /div + div +label for=field-descriptionDescription/label +textarea id=field-description name=field_description +rows=3 cols=28 +placeholder=Ticket description/textarea + /div div class=form-horizontal -py:if test=qct.fields.product -label class=control-label for=field-productProduct/label -div class=controls - ${field_select(qct.fields.product, None)} -/div -/py:if -py:if test=qct.fields.version -label class=control-label for=field-versionVersion/label -div class=controls - ${field_select(qct.fields.version, None)} -/div -/py:if -py:if test=qct.fields.type -label class=control-label for=field-typeType/label -div class=controls - ${field_select(qct.fields.type, None)} -/div -/py:if -py:if test=qct.fields.component -label class=control-label for=field-componentComponent/label -div class=controls - ${field_select(qct.fields.component, None)} -/div -/py:if +py:for each=field in qct.fields + label class=control-label for=field-${field.name}${field.label}/label + div class=controls +${field_select(field, None)} + /div +/py:for /div /py:def py:choose test= @@ -156,7 +148,13 @@ div id=qct-box class=dropdown-menu style=width: 300px; py:choose= div class=popover-title - a href=${href.newticket()}h3Create Ticket/h3/a + h3 +Create Ticket +a style=top: -33px; right: -25px; position: relative; +class=pull-right href=${href.newticket()} + smallFull dialogue raquo;/small +/a + /h3 /div div class=popover-content py:when test='TICKET_CREATE' in perm @@ -278,8 +276,8 @@ div class=row footer div class=span8 ${chrome.labels.footer_left_prefix} - Powered by a href=http://www.apache.org/;ApachesupTM/sup/a - a href=${href.about()}${chrome.labels.application_short} + Powered by + a href=${href.about()}${chrome.labels.application_full} ${chrome.labels.application_version}/a ${chrome.labels.footer_left_postfix} /div Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py?rev=1430304r1=1430303r2=1430304view=diff
svn commit: r1425616 - /incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py
Author: jure Date: Mon Dec 24 09:56:53 2012 New Revision: 1425616 URL: http://svn.apache.org/viewvc?rev=1425616view=rev Log: Make quick search work again by covering special case(s) of SELECTs (from sqlparse perspective) Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py?rev=1425616r1=1425615r2=1425616view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py Mon Dec 24 09:56:53 2012 @@ -89,10 +89,13 @@ class BloodhoundProductSQLTranslate(obje def _column_expression_name_alias(self, tokens): return filter(lambda t: t.upper() != 'AS', [t.value for t in tokens if t.value.strip()]) +def _select_alias_sql(self, alias): +return ' AS %s' % alias + def _translated_table_view_sql(self, name, alias=None): sql = '(SELECT * FROM %s WHERE %s=%s)' % (name, self._product_column, self._product_prefix) if alias: -sql += ' AS %s' % alias +sql += self._select_alias_sql(alias) return sql def _prefixed_table_entity_name(self, tablename): @@ -120,6 +123,12 @@ class BloodhoundProductSQLTranslate(obje return parent.insert_after(where, token) def _token_idx(self, parent, token): return parent.token_index(token) +def _token_delete(self, parent, token): +idx = self._token_idx(parent, token) +del parent.tokens[idx] +return idx +def _token_insert(self, parent, idx, token): +parent.tokens.insert(idx, token) def _eval_expression_value(self, parent, token): if isinstance(token, Types.Parenthesis): @@ -133,10 +142,9 @@ class BloodhoundProductSQLTranslate(obje # hack to workaround sqlparse bug that wrongly presents list of tokens # as IdentifierList in certain situations if isinstance(token, Types.IdentifierList): -idx = self._token_idx(parent, token) -del parent.tokens[idx] +idx = self._token_delete(parent, token) for t in token.tokens: -parent.tokens.insert(idx, t) +self._token_insert(parent, idx, t) idx += 1 token = self._token_next(parent, start_token) return token @@ -200,6 +208,9 @@ class BloodhoundProductSQLTranslate(obje parent.tokens[self._token_idx(parent, token)] = sqlparse.parse(self._prefixed_table_view_sql(name, alias))[0] +def inject_table_alias(token, alias): +parent.tokens[self._token_idx(parent, token)] = sqlparse.parse(self._select_alias_sql(alias))[0] + def process_table_name_tokens(nametokens): if nametokens: l = self._select_table_name_alias(nametokens) @@ -209,7 +220,7 @@ class BloodhoundProductSQLTranslate(obje alias = l[1] if len(l) 1 else name token = nametokens[0] for t in nametokens[1:]: -del parent.tokens[self._token_idx(parent, t)] +self._token_delete(parent, t) inject_table_view(token, name, alias) return list() @@ -230,7 +241,7 @@ class BloodhoundProductSQLTranslate(obje parenthesis = filter(lambda t: isinstance(t, Types.Parenthesis), current_token.tokens) if parenthesis: for p in parenthesis: -t = self._token_next(p, p.token_first()) +t = self._token_next(p, self._token_first(p)) if not t.match(Tokens.DML, 'SELECT'): raise Exception(Invalid subselect statement) self._select(p, t) @@ -241,6 +252,21 @@ class BloodhoundProductSQLTranslate(obje table_name_tokens.append(current_token) else: inject_table_view(current_token, tablename, tablealias) +elif isinstance(current_token, Types.Parenthesis): +t = self._token_next(current_token, self._token_first(current_token)) +if t.match(Tokens.DML, 'SELECT'): +identifier_token = self._token_next(parent, current_token) +as_token = None +if identifier_token.match(Tokens.Keyword, 'AS'): +as_token = identifier_token +identifier_token = self._token_next(parent, identifier_token
svn commit: r1424391 - /incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py
Author: jure Date: Thu Dec 20 10:21:52 2012 New Revision: 1424391 URL: http://svn.apache.org/viewvc?rev=1424391view=rev Log: Towards #288, properly expand identifier list(s) within FROM Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py?rev=1424391r1=1424390r2=1424391view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py Thu Dec 20 10:21:52 2012 @@ -133,12 +133,11 @@ class BloodhoundProductSQLTranslate(obje # hack to workaround sqlparse bug that wrongly presents list of tokens # as IdentifierList in certain situations if isinstance(token, Types.IdentifierList): -expression_token_idx = self._token_idx(parent, token) -del parent.tokens[expression_token_idx] -last_token = start_token +idx = self._token_idx(parent, token) +del parent.tokens[idx] for t in token.tokens: -self._token_insert_after(parent, last_token, t) -last_token = t +parent.tokens.insert(idx, t) +idx += 1 token = self._token_next(parent, start_token) return token @@ -215,16 +214,18 @@ class BloodhoundProductSQLTranslate(obje return list() current_token = self._token_next(parent, start_token) -last_token = current_token +prev_token = start_token table_name_tokens = list() join_tokens = list() while current_token and \ not current_token.match(Tokens.Keyword, end_words) and \ not isinstance(current_token, Types.Where): -last_token = current_token next_token = self._token_next(parent, current_token) if current_token.is_whitespace(): pass +elif isinstance(current_token, Types.IdentifierList): +current_token = self._expression_token_unwind_hack(parent, current_token, prev_token) +continue elif isinstance(current_token, Types.Identifier): parenthesis = filter(lambda t: isinstance(t, Types.Parenthesis), current_token.tokens) if parenthesis: @@ -260,9 +261,9 @@ class BloodhoundProductSQLTranslate(obje table_name_tokens.append(current_token) else: raise Exception(Failed to parse FROM table name) +prev_token = current_token current_token = next_token - -if last_token: +if prev_token: process_table_name_tokens(table_name_tokens) return current_token
svn commit: r1423779 - in /incubator/bloodhound/branches/bep_0003_multiproduct/installer: requirements-dev.txt requirements.txt
Author: jure Date: Wed Dec 19 08:04:07 2012 New Revision: 1423779 URL: http://svn.apache.org/viewvc?rev=1423779view=rev Log: sqlparse requirement added - required by the SQL database proxy component Modified: incubator/bloodhound/branches/bep_0003_multiproduct/installer/requirements-dev.txt incubator/bloodhound/branches/bep_0003_multiproduct/installer/requirements.txt Modified: incubator/bloodhound/branches/bep_0003_multiproduct/installer/requirements-dev.txt URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/installer/requirements-dev.txt?rev=1423779r1=1423778r2=1423779view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/installer/requirements-dev.txt (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/installer/requirements-dev.txt Wed Dec 19 08:04:07 2012 @@ -17,6 +17,7 @@ Pygments pytz +sqlparse Babel Genshi -e ../trac Modified: incubator/bloodhound/branches/bep_0003_multiproduct/installer/requirements.txt URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/installer/requirements.txt?rev=1423779r1=1423778r2=1423779view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/installer/requirements.txt (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/installer/requirements.txt Wed Dec 19 08:04:07 2012 @@ -17,6 +17,7 @@ Pygments pytz +sqlparse Babel Genshi ../trac
svn commit: r1422822 - /incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py
Author: jure Date: Mon Dec 17 10:04:02 2012 New Revision: 1422822 URL: http://svn.apache.org/viewvc?rev=1422822view=rev Log: Towards #288, prefix all 'foreign' (3rd party plugin) tables with product prefix in SELECT, UPDATE, DELETE, INSERT statements, next step is DDL Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py?rev=1422822r1=1422821r2=1422822view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py Mon Dec 17 10:04:02 2012 @@ -25,6 +25,14 @@ import sqlparse.sql as Types __all__ = ['BloodhoundIterableCursor'] +SKIP_TABLES = ['system', 'permission', 'auth_cookie', + 'session', 'session_attribute', + 'cache', + 'attachment', 'repository', 'revision', 'node_change', + 'ticket_change', 'ticket_custom', + 'report', + 'bloodhound_product', 'bloodhound_productresourcemap', + ] TRANSLATE_TABLES = ['ticket', 'enum', 'component', 'milestone', 'version', 'wiki'] PRODUCT_COLUMN = 'product' @@ -41,7 +49,8 @@ class BloodhoundIterableCursor(IterableC if not self._translator: from env import DEFAULT_PRODUCT product = self.env.product_scope if self.env else DEFAULT_PRODUCT -self._translator = BloodhoundProductSQLTranslate(TRANSLATE_TABLES, +self._translator = BloodhoundProductSQLTranslate(SKIP_TABLES, + TRANSLATE_TABLES, PRODUCT_COLUMN, product) return self._translator @@ -69,7 +78,8 @@ class BloodhoundProductSQLTranslate(obje 'JOIN', 'INNER JOIN'] _from_end_words = ['WHERE', 'GROUP', 'HAVING', 'ORDER', 'UNION'] -def __init__(self, translate_tables, product_column, product_prefix): +def __init__(self, skip_tables, translate_tables, product_column, product_prefix): +self._skip_tables = skip_tables self._translate_tables = translate_tables self._product_column = product_column self._product_prefix = product_prefix @@ -79,12 +89,19 @@ class BloodhoundProductSQLTranslate(obje def _column_expression_name_alias(self, tokens): return filter(lambda t: t.upper() != 'AS', [t.value for t in tokens if t.value.strip()]) -def _patch_table_view_sql(self, name, alias=None): +def _translated_table_view_sql(self, name, alias=None): sql = '(SELECT * FROM %s WHERE %s=%s)' % (name, self._product_column, self._product_prefix) if alias: sql += ' AS %s' % alias return sql +def _prefixed_table_name(self, tablename): +return %s_%s % (self._product_prefix, tablename) + +def _prefixed_table_view_sql(self, name, alias): +return '(SELECT * FROM %s) AS %s' % (self._prefixed_table_name(name), + alias) + def _token_first(self, parent): return parent.token_first() def _token_next_match(self, parent, start_token, ttype, token): @@ -160,8 +177,8 @@ class BloodhoundProductSQLTranslate(obje tokens = list() if current_token: current_token = self._token_next(parent, current_token) -while current_token and\ - not current_token.match(Tokens.Keyword, end_words) and\ +while current_token and \ + not current_token.match(Tokens.Keyword, end_words) and \ not isinstance(current_token, Types.Where): tokens.append(current_token) current_token = self._token_next(parent, current_token) @@ -169,10 +186,20 @@ class BloodhoundProductSQLTranslate(obje def _select_from(self, parent, start_token, end_words, table_name_callback=None, force_alias=False): def inject_table_view(token, name, alias): -if force_alias and not alias: -alias = name -parent.tokens[self._token_idx(parent, token)] = sqlparse.parse(self._patch_table_view_sql(name, - alias=alias))[0] +if name in self._skip_tables: +pass +elif name in self._translate_tables: +if force_alias and not alias: +alias = name +parent.tokens[self._token_idx(parent, token)] = sqlparse.parse(self
svn commit: r1422829 - /incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py
Author: jure Date: Mon Dec 17 10:18:45 2012 New Revision: 1422829 URL: http://svn.apache.org/viewvc?rev=1422829view=rev Log: Properly evaluate DELETE conditions Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py?rev=1422829r1=1422828r2=1422829view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py Mon Dec 17 10:18:45 2012 @@ -449,8 +449,6 @@ class BloodhoundProductSQLTranslate(obje else: raise Exception(Invalid DELETE statement, expected table name) start_token = self._replace_table_name(parent, table_name_token, tablename) -if not tablename in self._translate_tables: -return self._update_delete_where_limit(tablename, parent, start_token) return @@ -470,3 +468,4 @@ class BloodhoundProductSQLTranslate(obje except Exception: raise Exception(Failed to translate SQL '%s' % sql) return translated_sql +
svn commit: r1420572 - in /incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac: bloodhound.py bloodhound/ bloodhound/__init__.py bloodhound/db.py bloodhound/env.py bloodhoundsql.py web/stand
Author: jure Date: Wed Dec 12 08:37:22 2012 New Revision: 1420572 URL: http://svn.apache.org/viewvc?rev=1420572view=rev Log: * reorganized code, moved bloodhound code to separate directory Added: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/__init__.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py - copied, changed from r1420086, incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhoundsql.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/env.py - copied, changed from r1420086, incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound.py Removed: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhoundsql.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/standalone.py Added: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/__init__.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/__init__.py?rev=1420572view=auto == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/__init__.py (added) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/__init__.py Wed Dec 12 08:37:22 2012 @@ -0,0 +1,20 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# License); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from trac.bloodhound.env import * +from trac.bloodhound.db import * Copied: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py (from r1420086, incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhoundsql.py) URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py?p2=incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.pyp1=incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhoundsql.pyr1=1420086r2=1420572rev=1420572view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhoundsql.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound/db.py Wed Dec 12 08:37:22 2012 @@ -16,11 +16,52 @@ # specific language governing permissions and limitations # under the License. +from trac.db.util import IterableCursor +from trac.util import concurrency + import sqlparse import sqlparse.tokens as Tokens import sqlparse.sql as Types -__all__ = ['BloodhoundProductSQLTranslate'] +__all__ = ['BloodhoundIterableCursor'] + +TRANSLATE_TABLES = ['ticket', 'enum', 'component', 'milestone', 'version', 'wiki'] +PRODUCT_COLUMN = 'product' + +class BloodhoundIterableCursor(IterableCursor): +__slots__ = IterableCursor.__slots__ + ['_translator'] +_tls = concurrency.ThreadLocal(env=None) + +def __init__(self, cursor, log=None): +super(BloodhoundIterableCursor, self).__init__(cursor, log=log) +self._translator = None + +@property +def translator(self): +if not self._translator: +from env import DEFAULT_PRODUCT +product = self.env.product_scope if self.env else DEFAULT_PRODUCT +self._translator = BloodhoundProductSQLTranslate(TRANSLATE_TABLES, + PRODUCT_COLUMN, + product) +return self._translator + +def _translate_sql(self, sql): +return self.translator.translate(sql) if (self.env and not self.env.product_aware) else sql + +def execute(self, sql, args=None): +return super(BloodhoundIterableCursor, self).execute(self._translate_sql(sql), args=args) + +def executemany(self, sql, args=None): +return super(BloodhoundIterableCursor, self).executemany(self._translate_sql(sql), args=args) + +@property +def env(self): +return self._tls.env
svn commit: r1420075 - in /incubator/bloodhound/branches/bep_0003_multiproduct: bloodhound_multiproduct/multiproduct/api.py bloodhound_multiproduct/multiproduct/model.py trac/trac/bloodhound.py trac/t
Author: jure Date: Tue Dec 11 10:28:05 2012 New Revision: 1420075 URL: http://svn.apache.org/viewvc?rev=1420075view=rev Log: initial SQL proxy patch as described in ticket #288 Added: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhound.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/bloodhoundsql.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/model.py incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/web/standalone.py Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py?rev=1420075r1=1420074r2=1420075view=diff == --- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py (original) +++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_multiproduct/multiproduct/api.py Tue Dec 11 10:28:05 2012 @@ -23,7 +23,7 @@ from genshi.builder import tag from pkg_resources import resource_filename from trac.core import Component, TracError, implements -from trac.db import Table, Column, DatabaseManager +from trac.db import Table, Column, DatabaseManager, Index from trac.env import IEnvironmentSetupParticipant from trac.perm import IPermissionRequestor from trac.resource import IResourceManager @@ -33,7 +33,7 @@ from trac.web.chrome import ITemplatePro from multiproduct.model import Product -DB_VERSION = 2 +DB_VERSION = 3 DB_SYSTEM_KEY = 'bloodhound_multi_product_version' PLUGIN_NAME = 'Bloodhound multi product' @@ -114,7 +114,89 @@ class MultiProductSystem(Component): WHERE name=%s, (DB_VERSION, DB_SYSTEM_KEY)) self.log.info(Upgraded multiproduct db schema from version %d to %d % (db_installed_version, DB_VERSION)) - + +if db_installed_version == 2: +from trac import bloodhound +migrate_tables = ['enum', 'component', 'milestone', 'version', 'wiki'] +table_defs = [ +Table('enum', key=('type', 'name', 'product'))[ +Column('type'), +Column('name'), +Column('value'), +Column('product')], +Table('component', key=('name', 'product'))[ +Column('name'), +Column('owner'), +Column('description'), +Column('product')], +Table('milestone', key=('name', 'product'))[ +Column('name'), +Column('due', type='int64'), +Column('completed', type='int64'), +Column('description'), +Column('product')], +Table('version', key=('name', 'product'))[ +Column('name'), +Column('time', type='int64'), +Column('description'), +Column('product')], +Table('wiki', key=('name', 'version', 'product'))[ +Column('name'), +Column('version', type='int'), +Column('time', type='int64'), +Column('author'), +Column('ipnr'), +Column('text'), +Column('comment'), +Column('readonly', type='int'), +Column('product'), +Index(['time'])], +] +table_columns = dict() +table_vals = {} +for table in table_defs: +table_columns[table.name] = filter(lambda column: column != 'product', [column.name for column in list(filter(lambda t: t.name == table.name, table_defs)[0].columns)]) +table_columns['bloodhound_product'] = ['prefix', 'name', 'description', 'owner'] +def fetch_table(table): +table_vals[table] = list(db(SELECT %s FROM %s % (','.join(table_columns[table]), table))) +for table in table_columns.keys(): +self.log.info(Fetching table '%s', table) +fetch_table(table) +for table in migrate_tables: +self.log.info(Dropping obsolete table '%s', table) +db(DROP TABLE %s % table) +db_connector, _ = DatabaseManager(self.env).get_connector() +for table in table_defs