svn commit: r1460314 - in /incubator/bloodhound/branches/bep_0003_multiproduct: ./ bloodhound_dashboard/bhdashboard/widgets/ bloodhound_search/ bloodhound_search/bhsearch/templates/ bloodhound_theme/b

2013-03-24 Thread jure
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

2013-03-24 Thread jure
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

2013-03-24 Thread jure
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

2013-03-24 Thread jure
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

2013-03-24 Thread jure
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

2013-03-20 Thread jure
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

2013-03-20 Thread jure
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

2013-03-19 Thread jure
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

2013-03-19 Thread jure
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

2013-03-18 Thread jure
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

2013-03-18 Thread jure
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

2013-03-15 Thread jure
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

2013-03-15 Thread jure
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

2013-03-14 Thread jure
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

2013-03-13 Thread jure
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

2013-03-13 Thread jure
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

2013-03-12 Thread jure
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

2013-03-12 Thread jure
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

2013-03-12 Thread jure
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

2013-03-12 Thread jure
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/

2013-03-12 Thread jure
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/

2013-03-12 Thread jure
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

2013-03-12 Thread jure
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

2013-03-12 Thread jure
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

2013-03-11 Thread jure
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

2013-03-08 Thread jure
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

2013-03-07 Thread jure
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/

2013-03-07 Thread jure
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

2013-03-06 Thread jure
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

2013-03-06 Thread jure
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

2013-03-06 Thread jure
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

2013-03-05 Thread jure
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

2013-03-05 Thread jure
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

2013-03-05 Thread jure
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

2013-03-04 Thread jure
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/__

2013-02-28 Thread jure
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/

2013-02-27 Thread jure
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

2013-02-26 Thread jure
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

2013-02-25 Thread jure
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

2013-02-22 Thread jure
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

2013-02-22 Thread jure
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

2013-02-20 Thread jure
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

2013-02-20 Thread jure
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

2013-02-19 Thread jure
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

2013-02-19 Thread jure
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

2013-02-19 Thread jure
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

2013-02-18 Thread jure
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

2013-02-18 Thread jure
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

2013-02-18 Thread jure
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

2013-02-18 Thread jure
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

2013-02-18 Thread jure
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

2013-02-18 Thread jure
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

2013-02-18 Thread jure
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

2013-02-18 Thread jure
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

2013-02-15 Thread jure
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

2013-02-15 Thread jure
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

2013-02-15 Thread jure
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

2013-02-15 Thread jure
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

2013-02-14 Thread jure
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

2013-02-11 Thread jure
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

2013-02-11 Thread jure
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

2013-02-11 Thread jure
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

2013-02-07 Thread jure
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

2013-02-06 Thread jure
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

2013-02-06 Thread jure
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

2013-02-05 Thread jure
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

2013-02-01 Thread jure
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

2013-02-01 Thread jure
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

2013-01-31 Thread jure
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/

2013-01-30 Thread jure
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

2013-01-24 Thread jure
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

2013-01-23 Thread jure
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

2013-01-23 Thread jure
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

2013-01-21 Thread jure
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

2013-01-21 Thread jure
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

2013-01-18 Thread jure
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

2013-01-17 Thread jure
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

2013-01-16 Thread jure
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

2013-01-15 Thread jure
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/

2013-01-15 Thread jure
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

2013-01-11 Thread jure
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

2013-01-11 Thread jure
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

2013-01-11 Thread jure
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/

2013-01-10 Thread jure
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/

2013-01-09 Thread jure
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

2013-01-08 Thread jure
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

2013-01-08 Thread jure
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

2012-12-24 Thread jure
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

2012-12-20 Thread jure
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

2012-12-19 Thread jure
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

2012-12-17 Thread jure
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

2012-12-17 Thread jure
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

2012-12-12 Thread jure
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

2012-12-11 Thread jure
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