--- a/appobject.py Tue Aug 04 15:06:09 2009 +0200
+++ b/appobject.py Tue Aug 04 15:08:18 2009 +0200
@@ -1,4 +1,6 @@
-"""Base class for dynamically loaded objects manipulated in the web interface
+"""Base class for dynamically loaded objects accessible through the vregistry.
+
+You'll also find some convenience classes to build selectors.
:organization: Logilab
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
@@ -7,20 +9,23 @@
"""
__docformat__ = "restructuredtext en"
+import types
+from logging import getLogger
from datetime import datetime, timedelta, time
from logilab.common.decorators import classproperty
from logilab.common.deprecation import deprecated
+from logilab.common.logging_ext import set_log_methods
from rql.nodes import VariableRef, SubQuery
from rql.stmts import Union, Select
from cubicweb import Unauthorized, NoSelectableObject
-from cubicweb.vregistry import VObject, AndSelector
-from cubicweb.selectors import yes
from cubicweb.utils import UStringIO, ustrftime, strptime, todate, todatetime
ONESECOND = timedelta(0, 1, 0)
+CACHE_REGISTRY = {}
+
class Cache(dict):
def __init__(self):
@@ -29,14 +34,200 @@
self.cache_creation_date = _now
self.latest_cache_lookup = _now
-CACHE_REGISTRY = {}
+
+# selector base classes and operations ########################################
+
+def objectify_selector(selector_func):
+ """convenience decorator for simple selectors where a class definition
+ would be overkill::
+
+ @objectify_selector
+ def yes(cls, *args, **kwargs):
+ return 1
+
+ """
+ return type(selector_func.__name__, (Selector,),
+ {'__call__': lambda self, *args, **kwargs: selector_func(*args, **kwargs)})
+
+
+def _instantiate_selector(selector):
+ """ensures `selector` is a `Selector` instance
+
+ NOTE: This should only be used locally in build___select__()
+ XXX: then, why not do it ??
+ """
+ if isinstance(selector, types.FunctionType):
+ return objectify_selector(selector)()
+ if isinstance(selector, type) and issubclass(selector, Selector):
+ return selector()
+ return selector
+
+
+class Selector(object):
+ """base class for selector classes providing implementation
+ for operators ``&`` and ``|``
+
+ This class is only here to give access to binary operators, the
+ selector logic itself should be implemented in the __call__ method
+
+
+ a selector is called to help choosing the correct object for a
+ particular context by returning a score (`int`) telling how well
+ the class given as first argument apply to the given context.
+
+ 0 score means that the class doesn't apply.
+ """
+
+ @property
+ def func_name(self):
+ # backward compatibility
+ return self.__class__.__name__
+
+ def search_selector(self, selector):
+ """search for the given selector or selector instance in the selectors
+ tree. Return it of None if not found
+ """
+ if self is selector:
+ return self
+ if isinstance(selector, type) and isinstance(self, selector):
+ return self
+ return None
+
+ def __str__(self):
+ return self.__class__.__name__
+
+ def __and__(self, other):
+ return AndSelector(self, other)
+ def __rand__(self, other):
+ return AndSelector(other, self)
+
+ def __or__(self, other):
+ return OrSelector(self, other)
+ def __ror__(self, other):
+ return OrSelector(other, self)
+
+ def __invert__(self):
+ return NotSelector(self)
+
+ # XXX (function | function) or (function & function) not managed yet
+
+ def __call__(self, cls, *args, **kwargs):
+ return NotImplementedError("selector %s must implement its logic "
+ "in its __call__ method" % self.__class__)
+
+
+class MultiSelector(Selector):
+ """base class for compound selector classes"""
+
+ def __init__(self, *selectors):
+ self.selectors = self.merge_selectors(selectors)
+
+ def __str__(self):
+ return '%s(%s)' % (self.__class__.__name__,
+ ','.join(str(s) for s in self.selectors))
+
+ @classmethod
+ def merge_selectors(cls, selectors):
+ """deal with selector instanciation when necessary and merge
+ multi-selectors if possible:
-class AppRsetObject(VObject):
- """This is the base class for CubicWeb application objects
- which are selected according to a request and result set.
+ AndSelector(AndSelector(sel1, sel2), AndSelector(sel3, sel4))
+ ==> AndSelector(sel1, sel2, sel3, sel4)
+ """
+ merged_selectors = []
+ for selector in selectors:
+ try:
+ selector = _instantiate_selector(selector)
+ except:
+ pass
+ #assert isinstance(selector, Selector), selector
+ if isinstance(selector, cls):
+ merged_selectors += selector.selectors
+ else:
+ merged_selectors.append(selector)
+ return merged_selectors
+
+ def search_selector(self, selector):
+ """search for the given selector or selector instance in the selectors
+ tree. Return it of None if not found
+ """
+ for childselector in self.selectors:
+ if childselector is selector:
+ return childselector
+ found = childselector.search_selector(selector)
+ if found is not None:
+ return found
+ return None
+
+
+class AndSelector(MultiSelector):
+ """and-chained selectors (formerly known as chainall)"""
+ def __call__(self, cls, *args, **kwargs):
+ score = 0
+ for selector in self.selectors:
+ partscore = selector(cls, *args, **kwargs)
+ if not partscore:
+ return 0
+ score += partscore
+ return score
+
- Classes are kept in the vregistry and instantiation is done at selection
- time.
+class OrSelector(MultiSelector):
+ """or-chained selectors (formerly known as chainfirst)"""
+ def __call__(self, cls, *args, **kwargs):
+ for selector in self.selectors:
+ partscore = selector(cls, *args, **kwargs)
+ if partscore:
+ return partscore
+ return 0
+
+class NotSelector(Selector):
+ """negation selector"""
+ def __init__(self, selector):
+ self.selector = selector
+
+ def __call__(self, cls, *args, **kwargs):
+ score = self.selector(cls, *args, **kwargs)
+ return int(not score)
+
+ def __str__(self):
+ return 'NOT(%s)' % super(NotSelector, self).__str__()
+
+
+class yes(Selector):
+ """return arbitrary score
+
+ default score of 0.5 so any other selector take precedence
+ """
+ def __init__(self, score=0.5):
+ self.score = score
+
+ def __call__(self, *args, **kwargs):
+ return self.score
+
+
+# the base class for all appobjects ############################################
+
+class AppObject(object):
+ """This is the base class for CubicWeb application objects which are
+ selected according to a context (usually at least a request and a result
+ set).
+
+ Concrete application objects classes are designed to be loaded by the
+ vregistry and should be accessed through it, not by direct instantiation.
+
+ The following attributes should be set on concret appobject classes:
+ :__registry__:
+ name of the registry for this object (string like 'views',
+ 'templates'...)
+ :id:
+ object's identifier in the registry (string like 'main',
+ 'primary', 'folder_box')
+ :__select__:
+ class'selector
+
+ Moreover, the `__abstract__` attribute may be set to True to indicate
+ that a appobject is abstract and should not be registered.
At registration time, the following attributes are set on the class:
:vreg:
@@ -46,20 +237,64 @@
:config:
the instance's configuration
- At instantiation time, the following attributes are set on the instance:
+ At selection time, the following attributes are set on the instance:
:req:
current request
:rset:
- result set on which the object is applied
+ context result set or None
+ :row:
+ if a result set is set and the context is about a particular cell in the
+ result set, and not the result set as a whole, specify the row number we
+ are interested in, else None
+ :col:
+ if a result set is set and the context is about a particular cell in the
+ result set, and not the result set as a whole, specify the col number we
+ are interested in, else None
"""
+ __registry__ = None
+ id = None
__select__ = yes()
@classmethod
- def registered(cls, vreg):
- super(AppRsetObject, cls).registered(vreg)
- cls.vreg = vreg
- cls.schema = vreg.schema
- cls.config = vreg.config
+ def classid(cls):
+ """returns a unique identifier for the appobject"""
+ return '%s.%s' % (cls.__module__, cls.__name__)
+
+ # XXX bw compat code
+ @classmethod
+ def build___select__(cls):
+ for klass in cls.mro():
+ if klass.__name__ == 'AppObject':
+ continue # the bw compat __selector__ is there
+ klassdict = klass.__dict__
+ if ('__select__' in klassdict and '__selectors__' in klassdict
+ and '__selgenerated__' not in klassdict):
+ raise TypeError("__select__ and __selectors__ can't be used together on class %s" % cls)
+ if '__selectors__' in klassdict and '__selgenerated__' not in klassdict:
+ cls.__selgenerated__ = True
+ # case where __selectors__ is defined locally (but __select__
+ # is in a parent class)
+ selectors = klassdict['__selectors__']
+ if len(selectors) == 1:
+ # micro optimization: don't bother with AndSelector if there's
+ # only one selector
+ select = _instantiate_selector(selectors[0])
+ else:
+ select = AndSelector(*selectors)
+ cls.__select__ = select
+
+ @classmethod
+ def registered(cls, registry):
+ """called by the registry when the appobject has been registered.
+
+ It must return the object that will be actually registered (this may be
+ the right hook to create an instance for example). By default the
+ appobject is returned without any transformation.
+ """
+ cls.build___select__()
+ cls.vreg = registry.vreg
+ cls.schema = registry.schema
+ cls.config = registry.config
cls.register_properties()
return cls
@@ -67,15 +302,6 @@
def vreg_initialization_completed(cls):
pass
- @classmethod
- def selected(cls, *args, **kwargs):
- """by default web app objects are usually instantiated on
- selection according to a request, a result set, and optional
- row and col
- """
- assert len(args) <= 2
- return cls(*args, **kwargs)
-
# Eproperties definition:
# key: id of the property (the actual CWProperty key is build using
# <registry name>.<obj id>.<property id>
@@ -111,7 +337,7 @@
return selector
def __init__(self, req=None, rset=None, row=None, col=None, **extra):
- super(AppRsetObject, self).__init__()
+ super(AppObject, self).__init__()
self.req = req
self.rset = rset
self.row = row
@@ -151,8 +377,8 @@
# try to get page boundaries from the navigation component
# XXX we should probably not have a ref to this component here (eg in
# cubicweb.common)
- nav = self.vreg.select_object('components', 'navigation', self.req,
- rset=self.rset)
+ nav = self.vreg['components'].select_object('navigation', self.req,
+ rset=self.rset)
if nav:
start, stop = nav.page_boundaries()
rql = self._limit_offset_rql(stop - start, start)
@@ -188,10 +414,11 @@
rqlst.parent = None
return rql
- def view(self, __vid, rset=None, __fallback_vid=None, **kwargs):
+ def view(self, __vid, rset=None, __fallback_oid=None, __registry='views',
+ **kwargs):
"""shortcut to self.vreg.view method avoiding to pass self.req"""
- return self.vreg.render(__vid, self.req, __fallback_vid, rset=rset,
- **kwargs)
+ return self.vreg[__registry].render(__vid, self.req, __fallback_oid,
+ rset=rset, **kwargs)
def initialize_varmaker(self):
varmaker = self.req.get_page_data('rql_varmaker')
@@ -341,22 +568,4 @@
if first in ('insert', 'set', 'delete'):
raise Unauthorized(self.req._('only select queries are authorized'))
-
-class AppObject(AppRsetObject):
- """base class for application objects which are not selected
- according to a result set, only by their identifier.
-
- Those objects may not have req, rset and cursor set.
- """
-
- @classmethod
- def selected(cls, *args, **kwargs):
- """by default web app objects are usually instantiated on
- selection
- """
- return cls(*args, **kwargs)
-
- def __init__(self, req=None, rset=None, **kwargs):
- self.req = req
- self.rset = rset
- self.__dict__.update(kwargs)
+set_log_methods(AppObject, getLogger('cubicweb.appobject'))
--- a/common/test/unittest_migration.py Tue Aug 04 15:06:09 2009 +0200
+++ b/common/test/unittest_migration.py Tue Aug 04 15:08:18 2009 +0200
@@ -37,8 +37,8 @@
self.config = MigrTestConfig('data')
from yams.schema import Schema
self.config.load_schema = lambda expand_cubes=False: Schema('test')
- self.config.__class__.cubicweb_vobject_path = frozenset()
- self.config.__class__.cube_vobject_path = frozenset()
+ self.config.__class__.cubicweb_appobject_path = frozenset()
+ self.config.__class__.cube_appobject_path = frozenset()
def test_filter_scripts_base(self):
self.assertListEquals(filter_scripts(self.config, SMIGRDIR, (2,3,0), (2,4,0)),
--- a/cwconfig.py Tue Aug 04 15:06:09 2009 +0200
+++ b/cwconfig.py Tue Aug 04 15:08:18 2009 +0200
@@ -142,7 +142,7 @@
name = None
# log messages format (see logging module documentation for available keys)
log_format = '%(asctime)s - (%(name)s) %(levelname)s: %(message)s'
- # nor remove vobjects based on unused interface
+ # nor remove appobjects based on unused interface
cleanup_interface_sobjects = True
if os.environ.get('APYCOT_ROOT'):
@@ -169,14 +169,7 @@
{'type' : 'string',
'default': '',
'help': 'Pyro name server\'s host. If not set, will be detected by a \
-broadcast query',
- 'group': 'pyro-name-server', 'inputlevel': 1,
- }),
- ('pyro-ns-port',
- {'type' : 'int',
- 'default': None,
- 'help': 'Pyro name server\'s listening port. If not set, default \
-port will be used.',
+broadcast query. It may contains port information using <host>:<port> notation.',
'group': 'pyro-name-server', 'inputlevel': 1,
}),
('pyro-ns-group',
@@ -419,8 +412,8 @@
except Exception, ex:
cls.warning("can't init cube %s: %s", cube, ex)
- cubicweb_vobject_path = set(['entities'])
- cube_vobject_path = set(['entities'])
+ cubicweb_appobject_path = set(['entities'])
+ cube_appobject_path = set(['entities'])
@classmethod
def build_vregistry_path(cls, templpath, evobjpath=None, tvobjpath=None):
@@ -430,13 +423,13 @@
:param evobjpath:
optional list of sub-directories (or files without the .py ext) of
the cubicweb library that should be tested and added to the output list
- if they exists. If not give, default to `cubicweb_vobject_path` class
+ if they exists. If not give, default to `cubicweb_appobject_path` class
attribute.
:param tvobjpath:
optional list of sub-directories (or files without the .py ext) of
directories given in `templpath` that should be tested and added to
the output list if they exists. If not give, default to
- `cube_vobject_path` class attribute.
+ `cube_appobject_path` class attribute.
"""
vregpath = cls.build_vregistry_cubicweb_path(evobjpath)
vregpath += cls.build_vregistry_cube_path(templpath, tvobjpath)
@@ -446,7 +439,7 @@
def build_vregistry_cubicweb_path(cls, evobjpath=None):
vregpath = []
if evobjpath is None:
- evobjpath = cls.cubicweb_vobject_path
+ evobjpath = cls.cubicweb_appobject_path
for subdir in evobjpath:
path = join(CW_SOFTWARE_ROOT, subdir)
if exists(path):
@@ -457,7 +450,7 @@
def build_vregistry_cube_path(cls, templpath, tvobjpath=None):
vregpath = []
if tvobjpath is None:
- tvobjpath = cls.cube_vobject_path
+ tvobjpath = cls.cube_appobject_path
for directory in templpath:
for subdir in tvobjpath:
path = join(directory, subdir)
--- a/cwvreg.py Tue Aug 04 15:06:09 2009 +0200
+++ b/cwvreg.py Tue Aug 04 15:08:18 2009 +0200
@@ -8,14 +8,16 @@
__docformat__ = "restructuredtext en"
_ = unicode
-from logilab.common.decorators import cached, clear_cache
+from logilab.common.decorators import cached, clear_cache, monkeypatch
from logilab.common.deprecation import deprecated
from rql import RQLHelper
from cubicweb import (ETYPE_NAME_MAP, Binary, UnknownProperty, UnknownEid,
+ ObjectNotFound, NoSelectableObject, RegistryNotFound,
RegistryOutOfDate)
-from cubicweb.vregistry import VRegistry, ObjectNotFound, NoSelectableObject
+from cubicweb.utils import dump_class
+from cubicweb.vregistry import VRegistry, Registry
from cubicweb.rtags import RTAGS
@@ -33,14 +35,171 @@
if impl:
return sorted(impl.expected_ifaces)
except AttributeError:
- pass # old-style vobject classes with no accepts_interfaces
+ pass # old-style appobject classes with no accepts_interfaces
except:
print 'bad selector %s on %s' % (obj.__select__, obj)
raise
return ()
-class CubicWebRegistry(VRegistry):
+class CWRegistry(Registry):
+ def __init__(self, vreg):
+ super(CWRegistry, self).__init__(vreg.config)
+ self.vreg = vreg
+ self.schema = vreg.schema
+
+ def initialization_completed(self):
+ # call vreg_initialization_completed on appobjects and print
+ # registry content
+ for appobjects in self.itervalues():
+ for appobject in appobjects:
+ appobject.vreg_initialization_completed()
+
+ def render(self, __oid, req, __fallback_oid=None, rset=None, **kwargs):
+ """select object, or fallback object if specified and the first one
+ isn't selectable, then render it
+ """
+ try:
+ obj = self.select(__oid, req, rset=rset, **kwargs)
+ except NoSelectableObject:
+ if __fallback_oid is None:
+ raise
+ obj = self.select(__fallback_oid, req, **kwargs)
+ return obj.render(**kwargs)
+
+ def select_vobject(self, oid, *args, **kwargs):
+ selected = self.select_object(oid, *args, **kwargs)
+ if selected and selected.propval('visible'):
+ return selected
+ return None
+
+ def possible_vobjects(self, *args, **kwargs):
+ """return an ordered list of possible app objects in a given registry,
+ supposing they support the 'visible' and 'order' properties (as most
+ visualizable objects)
+ """
+ return sorted([x for x in self.possible_objects(*args, **kwargs)
+ if x.propval('visible')],
+ key=lambda x: x.propval('order'))
+
+
+VRegistry.REGISTRY_FACTORY[None] = CWRegistry
+
+
+class ETypeRegistry(CWRegistry):
+
+ def initialization_completed(self):
+ """on registration completed, clear etype_class internal cache
+ """
+ super(ETypeRegistry, self).initialization_completed()
+ # clear etype cache if you don't want to run into deep weirdness
+ clear_cache(self, 'etype_class')
+
+ def register(self, obj, **kwargs):
+ oid = kwargs.get('oid') or obj.id
+ if oid != 'Any' and not oid in self.schema:
+ self.error('don\'t register %s, %s type not defined in the '
+ 'schema', obj, obj.id)
+ return
+ kwargs['clear'] = True
+ super(ETypeRegistry, self).register(obj, **kwargs)
+
+ @cached
+ def etype_class(self, etype):
+ """return an entity class for the given entity type.
+
+ Try to find out a specific class for this kind of entity or default to a
+ dump of the nearest parent class (in yams inheritance) registered.
+
+ Fall back to 'Any' if not yams parent class found.
+ """
+ etype = str(etype)
+ if etype == 'Any':
+ return self.select('Any', 'Any')
+ eschema = self.schema.eschema(etype)
+ baseschemas = [eschema] + eschema.ancestors()
+ # browse ancestors from most specific to most generic and try to find an
+ # associated custom entity class
+ for baseschema in baseschemas:
+ try:
+ btype = ETYPE_NAME_MAP[baseschema]
+ except KeyError:
+ btype = str(baseschema)
+ try:
+ objects = self[btype]
+ assert len(objects) == 1, objects
+ cls = objects[0]
+ break
+ except ObjectNotFound:
+ pass
+ else:
+ # no entity class for any of the ancestors, fallback to the default
+ # one
+ objects = self['Any']
+ assert len(objects) == 1, objects
+ cls = objects[0]
+ if cls.id == etype:
+ cls.__initialize__()
+ return cls
+ cls = dump_class(cls, etype)
+ cls.id = etype
+ cls.__initialize__()
+ return cls
+
+VRegistry.REGISTRY_FACTORY['etypes'] = ETypeRegistry
+
+
+class ViewsRegistry(CWRegistry):
+
+ def main_template(self, req, oid='main-template', **kwargs):
+ """display query by calling the given template (default to main),
+ and returning the output as a string instead of requiring the [w]rite
+ method as argument
+ """
+ res = self.render(oid, req, **kwargs)
+ if isinstance(res, unicode):
+ return res.encode(req.encoding)
+ assert isinstance(res, str)
+ return res
+
+ def possible_views(self, req, rset=None, **kwargs):
+ """return an iterator on possible views for this result set
+
+ views returned are classes, not instances
+ """
+ for vid, views in self.items():
+ if vid[0] == '_':
+ continue
+ try:
+ view = self.select_best(views, req, rset=rset, **kwargs)
+ if view.linkable():
+ yield view
+ except NoSelectableObject:
+ continue
+ except Exception:
+ self.exception('error while trying to select %s view for %s',
+ vid, rset)
+
+VRegistry.REGISTRY_FACTORY['views'] = ViewsRegistry
+
+
+class ActionsRegistry(CWRegistry):
+
+ def possible_actions(self, req, rset=None, **kwargs):
+ if rset is None:
+ actions = self.possible_vobjects(req, rset=rset, **kwargs)
+ else:
+ actions = rset.possible_actions(**kwargs) # cached implementation
+ result = {}
+ for action in actions:
+ result.setdefault(action.category, []).append(action)
+ return result
+
+VRegistry.REGISTRY_FACTORY['actions'] = ActionsRegistry
+
+
+
+class CubicWebVRegistry(VRegistry):
"""Central registry for the cubicweb instance, extending the generic
VRegistry with some cubicweb specific stuff.
@@ -66,28 +225,38 @@
if initlog:
# first init log service
config.init_log(debug=debug)
- super(CubicWebRegistry, self).__init__(config)
+ super(CubicWebVRegistry, self).__init__(config)
self.schema = None
self.reset()
self.initialized = False
+ def setdefault(self, regid):
+ try:
+ return self[regid]
+ except RegistryNotFound:
+ self[regid] = self.registry_class(regid)(self)
+ return self[regid]
+
def items(self):
- return [item for item in self._registries.items()
+ return [item for item in super(CubicWebVRegistry, self).items()
if not item[0] in ('propertydefs', 'propertyvalues')]
+ def iteritems(self):
+ return (item for item in super(CubicWebVRegistry, self).iteritems()
+ if not item[0] in ('propertydefs', 'propertyvalues'))
def values(self):
- return [value for key, value in self._registries.items()
- if not key in ('propertydefs', 'propertyvalues')]
+ return [value for key, value in self.items()]
+ def itervalues(self):
+ return (value for key, value in self.items())
def reset(self):
- self._registries = {}
- self._lastmodifs = {}
+ super(CubicWebVRegistry, self).reset()
self._needs_iface = {}
# two special registries, propertydefs which care all the property
# definitions, and propertyvals which contains values for those
# properties
- self._registries['propertydefs'] = {}
- self._registries['propertyvalues'] = self.eprop_values = {}
+ self['propertydefs'] = {}
+ self['propertyvalues'] = self.eprop_values = {}
for key, propdef in self.config.eproperty_definitions():
self.register_property(key, **propdef)
@@ -108,9 +277,7 @@
tests
"""
self.schema = schema
- for registry, regcontent in self._registries.items():
- if registry in ('propertydefs', 'propertyvalues'):
- continue
+ for registry, regcontent in self.items():
for objects in regcontent.values():
for obj in objects:
obj.schema = schema
@@ -126,13 +293,7 @@
self._needs_iface[obj] = ifaces
def register(self, obj, **kwargs):
- if kwargs.get('registryname', obj.__registry__) == 'etypes':
- if obj.id != 'Any' and not obj.id in self.schema:
- self.error('don\'t register %s, %s type not defined in the '
- 'schema', obj, obj.id)
- return
- kwargs['clear'] = True
- super(CubicWebRegistry, self).register(obj, **kwargs)
+ super(CubicWebVRegistry, self).register(obj, **kwargs)
# XXX bw compat
ifaces = use_interfaces(obj)
if ifaces:
@@ -153,166 +314,92 @@
for cubesdir in self.config.cubes_search_path():
if cubesdir != self.config.CUBES_DIR:
extrapath[cubesdir] = 'cubes'
- if super(CubicWebRegistry, self).register_objects(path, force_reload,
+ if super(CubicWebVRegistry, self).register_objects(path, force_reload,
extrapath):
self.initialization_completed()
- # call vreg_initialization_completed on appobjects and print
- # registry content
- for registry, objects in self.items():
- self.debug('available in registry %s: %s', registry,
- sorted(objects))
- for appobjects in objects.itervalues():
- for appobject in appobjects:
- appobject.vreg_initialization_completed()
# don't check rtags if we don't want to cleanup_interface_sobjects
for rtag in RTAGS:
rtag.init(self.schema,
check=self.config.cleanup_interface_sobjects)
def initialization_completed(self):
- # clear etype cache if you don't want to run into deep weirdness
- clear_cache(self, 'etype_class')
+ for regname, reg in self.items():
+ self.debug('available in registry %s: %s', regname, sorted(reg))
+ reg.initialization_completed()
# we may want to keep interface dependent objects (e.g.for i18n
# catalog generation)
if self.config.cleanup_interface_sobjects:
- # remove vobjects that don't support any available interface
+ # remove appobjects that don't support any available interface
implemented_interfaces = set()
if 'Any' in self.get('etypes', ()):
for etype in self.schema.entities():
- cls = self.etype_class(etype)
+ cls = self['etypes'].etype_class(etype)
for iface in cls.__implements__:
implemented_interfaces.update(iface.__mro__)
implemented_interfaces.update(cls.__mro__)
for obj, ifaces in self._needs_iface.items():
ifaces = frozenset(isinstance(iface, basestring)
and iface in self.schema
- and self.etype_class(iface)
+ and self['etypes'].etype_class(iface)
or iface
for iface in ifaces)
if not ('Any' in ifaces or ifaces & implemented_interfaces):
- self.debug('kicking vobject %s (no implemented '
+ self.debug('kicking appobject %s (no implemented '
'interface among %s)', obj, ifaces)
self.unregister(obj)
# clear needs_iface so we don't try to remove some not-anymore-in
# objects on automatic reloading
self._needs_iface.clear()
+ def parse(self, session, rql, args=None):
+ rqlst = self.rqlhelper.parse(rql)
+ def type_from_eid(eid, session=session):
+ return session.describe(eid)[0]
+ try:
+ self.rqlhelper.compute_solutions(rqlst, {'eid': type_from_eid}, args)
+ except UnknownEid:
+ for select in rqlst.children:
+ select.solutions = []
+ return rqlst
+
+ @property
@cached
+ def rqlhelper(self):
+ return RQLHelper(self.schema,
+ special_relations={'eid': 'uid', 'has_text': 'fti'})
+
+
+ @deprecated('use vreg["etypes"].etype_class(etype)')
def etype_class(self, etype):
- """return an entity class for the given entity type.
- Try to find out a specific class for this kind of entity or
- default to a dump of the class registered for 'Any'
- """
- etype = str(etype)
- if etype == 'Any':
- return self.select('etypes', 'Any', 'Any')
- eschema = self.schema.eschema(etype)
- baseschemas = [eschema] + eschema.ancestors()
- # browse ancestors from most specific to most generic and
- # try to find an associated custom entity class
- for baseschema in baseschemas:
- try:
- btype = ETYPE_NAME_MAP[baseschema]
- except KeyError:
- btype = str(baseschema)
- try:
- cls = self.select('etypes', btype, etype)
- break
- except ObjectNotFound:
- pass
- else:
- # no entity class for any of the ancestors, fallback to the default
- # one
- cls = self.select('etypes', 'Any', etype)
- return cls
-
- def render(self, __oid, req, __fallback_oid=None, __registry='views',
- rset=None, **kwargs):
- """select object, or fallback object if specified and the first one
- isn't selectable, then render it
- """
- try:
- obj = self.select(__registry, __oid, req, rset=rset, **kwargs)
- except NoSelectableObject:
- if __fallback_oid is None:
- raise
- obj = self.select(__registry, __fallback_oid, req, rset=rset,
- **kwargs)
- return obj.render(**kwargs)
-
- def main_template(self, req, oid='main-template', **context):
- """display query by calling the given template (default to main),
- and returning the output as a string instead of requiring the [w]rite
- method as argument
- """
- res = self.render(oid, req, **context)
- if isinstance(res, unicode):
- return res.encode(req.encoding)
- assert isinstance(res, str)
- return res
+ return self["etypes"].etype_class(etype)
- def select_vobject(self, registry, oid, *args, **kwargs):
- selected = self.select_object(registry, oid, *args, **kwargs)
- if selected and selected.propval('visible'):
- return selected
- return None
+ @deprecated('use vreg["views"].main_template(*args, **kwargs)')
+ def main_template(self, req, oid='main-template', **context):
+ return self["views"].main_template(req, oid, **context)
+ @deprecated('use vreg[registry].possible_vobjects(*args, **kwargs)')
def possible_vobjects(self, registry, *args, **kwargs):
- """return an ordered list of possible app objects in a given registry,
- supposing they support the 'visible' and 'order' properties (as most
- visualizable objects)
- """
- return [x for x in sorted(self.possible_objects(registry, *args, **kwargs),
- key=lambda x: x.propval('order'))
- if x.propval('visible')]
+ return self[registry].possible_vobjects(*args, **kwargs)
+ @deprecated('use vreg["actions"].possible_actions(*args, **kwargs)')
def possible_actions(self, req, rset=None, **kwargs):
- if rset is None:
- actions = self.possible_vobjects('actions', req, rset=rset, **kwargs)
- else:
- actions = rset.possible_actions(**kwargs) # cached implementation
- result = {}
- for action in actions:
- result.setdefault(action.category, []).append(action)
- return result
-
- def possible_views(self, req, rset=None, **kwargs):
- """return an iterator on possible views for this result set
+ return self["actions"].possible_actions(req, rest=rset, **kwargs)
- views returned are classes, not instances
- """
- for vid, views in self.registry('views').items():
- if vid[0] == '_':
- continue
- try:
- view = self.select_best(views, req, rset=rset, **kwargs)
- if view.linkable():
- yield view
- except NoSelectableObject:
- continue
- except Exception:
- self.exception('error while trying to select %s view for %s',
- vid, rset)
-
- @deprecated("use .select_object('boxes', ...)")
+ @deprecated("use vreg['boxes'].select_object(...)")
def select_box(self, oid, *args, **kwargs):
- """return the most specific view according to the result set"""
- return self.select_object('boxes', oid, *args, **kwargs)
+ return self['boxes'].select_object(oid, *args, **kwargs)
- @deprecated("use .select_object('components', ...)")
+ @deprecated("use vreg['components'].select_object(...)")
def select_component(self, cid, *args, **kwargs):
- """return the most specific component according to the result set"""
- return self.select_object('components', cid, *args, **kwargs)
+ return self['components'].select_object(cid, *args, **kwargs)
- @deprecated("use .select_object('actions', ...)")
+ @deprecated("use vreg['actions'].select_object(...)")
def select_action(self, oid, *args, **kwargs):
- """return the most specific view according to the result set"""
- return self.select_object('actions', oid, *args, **kwargs)
+ return self['actions'].select_object(oid, *args, **kwargs)
- @deprecated("use .select('views', ...)")
+ @deprecated("use vreg['views'].select(...)")
def select_view(self, __vid, req, rset=None, **kwargs):
- """return the most specific view according to the result set"""
- return self.select('views', __vid, req, rset=rset, **kwargs)
+ return self['views'].select(__vid, req, rset=rset, **kwargs)
# properties handling #####################################################
@@ -326,7 +413,7 @@
def register_property(self, key, type, help, default=None, vocabulary=None,
sitewide=False):
"""register a given property"""
- properties = self._registries['propertydefs']
+ properties = self['propertydefs']
assert type in YAMS_TO_PY
properties[key] = {'type': type, 'vocabulary': vocabulary,
'default': default, 'help': help,
@@ -338,7 +425,7 @@
boolean)
"""
try:
- return self._registries['propertydefs'][key]
+ return self['propertydefs'][key]
except KeyError:
if key.startswith('system.version.'):
soft = key.split('.')[-1]
@@ -349,9 +436,9 @@
def property_value(self, key):
try:
- return self._registries['propertyvalues'][key]
+ return self['propertyvalues'][key]
except KeyError:
- return self._registries['propertydefs'][key]['default']
+ return self['propertydefs'][key]['default']
def typed_value(self, key, value):
"""value is an unicode string, return it correctly typed. Let potential
@@ -374,7 +461,7 @@
"""init the property values registry using the given set of couple (key, value)
"""
self.initialized = True
- values = self._registries['propertyvalues']
+ values = self['propertyvalues']
for key, val in propvalues:
try:
values[key] = self.typed_value(key, val)
@@ -385,61 +472,6 @@
self.warning('%s (you should probably delete that property '
'from the database)', ex)
- def parse(self, session, rql, args=None):
- rqlst = self.rqlhelper.parse(rql)
- def type_from_eid(eid, session=session):
- return session.describe(eid)[0]
- try:
- self.rqlhelper.compute_solutions(rqlst, {'eid': type_from_eid}, args)
- except UnknownEid:
- for select in rqlst.children:
- select.solutions = []
- return rqlst
-
- @property
- @cached
- def rqlhelper(self):
- return RQLHelper(self.schema,
- special_relations={'eid': 'uid', 'has_text': 'fti'})
-
-
-class MulCnxCubicWebRegistry(CubicWebRegistry):
- """special registry to be used when an application has to deal with
- connections to differents repository. This class add some additional wrapper
- trying to hide buggy class attributes since classes are not designed to be
- shared among multiple registries.
- """
- def etype_class(self, etype):
- """return an entity class for the given entity type.
- Try to find out a specific class for this kind of entity or
- default to a dump of the class registered for 'Any'
- """
- usercls = super(MulCnxCubicWebRegistry, self).etype_class(etype)
- if etype == 'Any':
- return usercls
- usercls.e_schema = self.schema.eschema(etype)
- return usercls
-
- def select_best(self, vobjects, *args, **kwargs):
- """return an instance of the most specific object according
- to parameters
-
- raise NoSelectableObject if no object apply
- """
- for vobjectcls in vobjects:
- self._fix_cls_attrs(vobjectcls)
- selected = super(MulCnxCubicWebRegistry, self).select_best(
- vobjects, *args, **kwargs)
- # redo the same thing on the instance so it won't use equivalent class
- # attributes (which may change)
- self._fix_cls_attrs(selected)
- return selected
-
- def _fix_cls_attrs(self, vobject):
- vobject.vreg = self
- vobject.schema = self.schema
- vobject.config = self.config
-
from datetime import datetime, date, time, timedelta
--- a/dbapi.py Tue Aug 04 15:06:09 2009 +0200
+++ b/dbapi.py Tue Aug 04 15:08:18 2009 +0200
@@ -16,9 +16,11 @@
from itertools import count
from logilab.common.logging_ext import set_log_methods
+from logilab.common.decorators import monkeypatch
+from logilab.common.deprecation import deprecated
+
from cubicweb import ETYPE_NAME_MAP, ConnectionError, RequestSessionMixIn
-from cubicweb.cwvreg import CubicWebRegistry, MulCnxCubicWebRegistry
-from cubicweb.cwconfig import CubicWebNoAppConfiguration
+from cubicweb import cwvreg, cwconfig
_MARKER = object()
@@ -28,6 +30,54 @@
except KeyError:
return ''
+def _fix_cls_attrs(reg, appobject):
+ appobject.vreg = reg.vreg
+ appobject.schema = reg.schema
+ appobject.config = reg.config
+
+def multiple_connections_fix():
+ """some monkey patching necessary when an application has to deal with
+ several connections to different repositories. It tries to hide buggy class
+ attributes since classes are not designed to be shared among multiple
+ registries.
+ """
+ defaultcls = cwvreg.VRegistry.REGISTRY_FACTORY[None]
+ orig_select_best = defaultcls.orig_select_best = defaultcls.select_best
+ @monkeypatch(defaultcls)
+ def select_best(self, appobjects, *args, **kwargs):
+ """return an instance of the most specific object according
+ to parameters
+
+ raise NoSelectableObject if no object apply
+ """
+ for appobjectcls in appobjects:
+ _fix_cls_attrs(self, appobjectcls)
+ selected = orig_select_best(self, appobjects, *args, **kwargs)
+ # redo the same thing on the instance so it won't use equivalent class
+ # attributes (which may change)
+ _fix_cls_attrs(self, selected)
+ return selected
+
+ etypescls = cwvreg.VRegistry.REGISTRY_FACTORY['etypes']
+ orig_etype_class = etypescls.orig_etype_class = etypescls.etype_class
+ @monkeypatch(defaultcls)
+ def etype_class(self, etype):
+ """return an entity class for the given entity type.
+ Try to find out a specific class for this kind of entity or
+ default to a dump of the class registered for 'Any'
+ """
+ usercls = orig_etype_class(self, etype)
+ if etype == 'Any':
+ return usercls
+ usercls.e_schema = self.schema.eschema(etype)
+ return usercls
+
+def multiple_connections_unfix():
+ defaultcls = cwvreg.VRegistry.REGISTRY_FACTORY[None]
+ defaultcls.select_best = defaultcls.orig_select_best
+ etypescls = cwvreg.VRegistry.REGISTRY_FACTORY['etypes']
+ etypescls.etype_class = etypescls.orig_etype_class
+
class ConnectionProperties(object):
def __init__(self, cnxtype=None, lang=None, close=True, log=False):
self.cnxtype = cnxtype or 'pyro'
@@ -51,24 +101,14 @@
from cubicweb.server.repository import Repository
return Repository(config, vreg=vreg)
else: # method == 'pyro'
- from Pyro import core, naming
- from Pyro.errors import NamingError, ProtocolError
- core.initClient(banner=0)
- nsid = ':%s.%s' % (config['pyro-ns-group'], database)
- locator = naming.NameServerLocator()
# resolve the Pyro object
+ from logilab.common.pyro_ext import ns_get_proxy
try:
- nshost, nsport = config['pyro-ns-host'], config['pyro-ns-port']
- uri = locator.getNS(nshost, nsport).resolve(nsid)
- except ProtocolError:
- raise ConnectionError('Could not connect to the Pyro name server '
- '(host: %s:%i)' % (nshost, nsport))
- except NamingError:
- raise ConnectionError('Could not get repository for %s '
- '(not registered in Pyro), '
- 'you may have to restart your server-side '
- 'instance' % nsid)
- return core.getProxyForURI(uri)
+ return ns_get_proxy(database,
+ defaultnsgroup=config['pyro-ns-group'],
+ nshost=config['pyro-ns-host'])
+ except Exception, ex:
+ raise ConnectionError(str(ex))
def repo_connect(repo, login, password, cnxprops=None):
"""Constructor to create a new connection to the CubicWeb repository.
@@ -82,22 +122,18 @@
cnx.vreg = repo.vreg
return cnx
-def connect(database=None, login=None, password=None, host=None,
- group=None, cnxprops=None, port=None, setvreg=True, mulcnx=True,
- initlog=True):
+def connect(database=None, login=None, password=None, host=None, group=None,
+ cnxprops=None, setvreg=True, mulcnx=True, initlog=True):
"""Constructor for creating a connection to the CubicWeb repository.
Returns a Connection object.
- When method is 'pyro' and setvreg is True, use a special registry class
- (MulCnxCubicWebRegistry) made to deal with connections to differents instances
- in the same process unless specified otherwise by setting the mulcnx to
- False.
+ When method is 'pyro', setvreg is True, try to deal with connections to
+ differents instances in the same process unless specified otherwise by
+ setting the mulcnx to False.
"""
- config = CubicWebNoAppConfiguration()
+ config = cwconfig.CubicWebNoAppConfiguration()
if host:
config.global_set_option('pyro-ns-host', host)
- if port:
- config.global_set_option('pyro-ns-port', port)
if group:
config.global_set_option('pyro-ns-group', group)
cnxprops = cnxprops or ConnectionProperties()
@@ -107,9 +143,8 @@
vreg = repo.vreg
elif setvreg:
if mulcnx:
- vreg = MulCnxCubicWebRegistry(config, initlog=initlog)
- else:
- vreg = CubicWebRegistry(config, initlog=initlog)
+ multiple_connections_fix()
+ vreg = cwvreg.CubicWebVRegistry(config, initlog=initlog)
schema = repo.get_schema()
for oldetype, newetype in ETYPE_NAME_MAP.items():
if oldetype in schema:
@@ -126,7 +161,7 @@
"""usefull method for testing and scripting to get a dbapi.Connection
object connected to an in-memory repository instance
"""
- if isinstance(config, CubicWebRegistry):
+ if isinstance(config, cwvreg.CubicWebVRegistry):
vreg = config
config = None
else:
@@ -401,7 +436,7 @@
raise ProgrammingError('Closed connection')
return self._repo.get_schema()
- def load_vobjects(self, cubes=_MARKER, subpath=None, expand=True,
+ def load_appobjects(self, cubes=_MARKER, subpath=None, expand=True,
force_reload=None):
config = self.vreg.config
if cubes is _MARKER:
@@ -434,11 +469,13 @@
if self._repo.config.instance_hooks:
hm.register_hooks(config.load_hooks(self.vreg))
+ load_vobjects = deprecated()(load_appobjects)
+
def use_web_compatible_requests(self, baseurl, sitetitle=None):
"""monkey patch DBAPIRequest to fake a cw.web.request, so you should
able to call html views using rset from a simple dbapi connection.
- You should call `load_vobjects` at some point to register those views.
+ You should call `load_appobjects` at some point to register those views.
"""
from cubicweb.web.request import CubicWebRequestBase as cwrb
DBAPIRequest.build_ajax_replace_url = cwrb.build_ajax_replace_url.im_func
@@ -476,8 +513,9 @@
if req is None:
req = self.request()
rset = req.eid_rset(eid, 'CWUser')
- user = self.vreg.etype_class('CWUser')(req, rset, row=0, groups=groups,
- properties=properties)
+ user = self.vreg['etypes'].etype_class('CWUser')(req, rset, row=0,
+ groups=groups,
+ properties=properties)
user['login'] = login # cache login
return user
--- a/devtools/__init__.py Tue Aug 04 15:06:09 2009 +0200
+++ b/devtools/__init__.py Tue Aug 04 15:08:18 2009 +0200
@@ -142,8 +142,8 @@
class BaseApptestConfiguration(TestServerConfiguration, TwistedConfiguration):
repo_method = 'inmemory'
options = merge_options(TestServerConfiguration.options + TwistedConfiguration.options)
- cubicweb_vobject_path = TestServerConfiguration.cubicweb_vobject_path | TwistedConfiguration.cubicweb_vobject_path
- cube_vobject_path = TestServerConfiguration.cube_vobject_path | TwistedConfiguration.cube_vobject_path
+ cubicweb_appobject_path = TestServerConfiguration.cubicweb_appobject_path | TwistedConfiguration.cubicweb_appobject_path
+ cube_appobject_path = TestServerConfiguration.cube_appobject_path | TwistedConfiguration.cube_appobject_path
def available_languages(self, *args):
return ('en', 'fr', 'de')
--- a/devtools/_apptest.py Tue Aug 04 15:06:09 2009 +0200
+++ b/devtools/_apptest.py Tue Aug 04 15:08:18 2009 +0200
@@ -14,7 +14,7 @@
import yams.schema
from cubicweb.dbapi import repo_connect, ConnectionProperties, ProgrammingError
-from cubicweb.cwvreg import CubicWebRegistry
+from cubicweb.cwvreg import CubicWebVRegistry
from cubicweb.web.application import CubicWebPublisher
from cubicweb.web import Redirect
@@ -79,7 +79,7 @@
source = config.sources()['system']
if verbose:
print "init test database ..."
- self.vreg = vreg = CubicWebRegistry(config)
+ self.vreg = vreg = CubicWebVRegistry(config)
self.admlogin = source['db-user']
# restore database <=> init database
self.restore_database()
@@ -191,7 +191,7 @@
optional_args = {}
optional_args['vid'] = vid
req = self.create_request(rql=rql, **optional_args)
- return self.vreg.main_template(req, template)
+ return self.vreg['views'].main_template(req, template)
def call_edit(self, req):
"""shortcut for self.app.edit()"""
@@ -207,7 +207,7 @@
def iter_possible_views(self, req, rset):
"""returns a list of possible vids for <rql>"""
- for view in self.vreg.possible_views(req, rset):
+ for view in self.vreg['views'].possible_views(req, rset):
if view.category == 'startupview':
continue
yield view.id
@@ -216,7 +216,7 @@
def iter_startup_views(self, req):
"""returns the list of startup views"""
- for view in self.vreg.possible_views(req, None):
+ for view in self.vreg['views'].possible_views(req, None):
if view.category != 'startupview':
continue
yield view.id
@@ -233,7 +233,7 @@
if verbose:
print "init test database ..."
source = config.sources()['system']
- self.vreg = CubicWebRegistry(config)
+ self.vreg = CubicWebVRegistry(config)
self.cnx = init_test_database(driver=source['db-driver'],
vreg=self.vreg)[1]
if verbose:
--- a/devtools/apptest.py Tue Aug 04 15:06:09 2009 +0200
+++ b/devtools/apptest.py Tue Aug 04 15:08:18 2009 +0200
@@ -175,7 +175,7 @@
def etype_instance(self, etype, req=None):
req = req or self.request()
- e = self.env.vreg.etype_class(etype)(req, None, None)
+ e = self.env.vreg['etypes'].etype_class(etype)(req)
e.eid = None
return e
@@ -224,21 +224,21 @@
self.vreg.config.global_set_option(optname, value)
def pviews(self, req, rset):
- return sorted((a.id, a.__class__) for a in self.vreg.possible_views(req, rset))
+ return sorted((a.id, a.__class__) for a in self.vreg['views'].possible_views(req, rset=rset))
def pactions(self, req, rset, skipcategories=('addrelated', 'siteactions', 'useractions')):
- return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset=rset)
+ return [(a.id, a.__class__) for a in self.vreg['actions'].possible_vobjects(req, rset=rset)
if a.category not in skipcategories]
def pactions_by_cats(self, req, rset, categories=('addrelated',)):
- return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset=rset)
+ return [(a.id, a.__class__) for a in self.vreg['actions'].possible_vobjects(req, rset=rset)
if a.category in categories]
paddrelactions = deprecated()(pactions_by_cats)
def pactionsdict(self, req, rset, skipcategories=('addrelated', 'siteactions', 'useractions')):
res = {}
- for a in self.vreg.possible_vobjects('actions', req, rset=rset):
+ for a in self.vreg['actions'].possible_vobjects(req, rset=rset):
if a.category not in skipcategories:
res.setdefault(a.category, []).append(a.__class__)
return res
@@ -249,7 +249,7 @@
dump = simplejson.dumps
args = [dump(arg) for arg in args]
req = self.request(fname=fname, pageid='123', arg=args)
- ctrl = self.vreg.select('controllers', 'json', req)
+ ctrl = self.vreg['controllers'].select('json', req)
return ctrl.publish(), req
# default test setup and teardown #########################################
@@ -294,7 +294,7 @@
def setUp(self):
super(ControllerTC, self).setUp()
self.req = self.request()
- self.ctrl = self.vreg.select('controllers', 'edit', self.req)
+ self.ctrl = self.vreg['controllers'].select('edit', self.req)
def publish(self, req):
assert req is self.ctrl.req
@@ -308,7 +308,7 @@
def expect_redirect_publish(self, req=None):
if req is not None:
- self.ctrl = self.vreg.select('controllers', 'edit', req)
+ self.ctrl = self.vreg['controllers'].select('edit', req)
else:
req = self.req
try:
--- a/devtools/devctl.py Tue Aug 04 15:06:09 2009 +0200
+++ b/devtools/devctl.py Tue Aug 04 15:08:18 2009 +0200
@@ -29,8 +29,8 @@
class DevCubeConfiguration(ServerConfiguration, WebConfiguration):
"""dummy config to get full library schema and entities"""
creating = True
- cubicweb_vobject_path = ServerConfiguration.cubicweb_vobject_path | WebConfiguration.cubicweb_vobject_path
- cube_vobject_path = ServerConfiguration.cube_vobject_path | WebConfiguration.cube_vobject_path
+ cubicweb_appobject_path = ServerConfiguration.cubicweb_appobject_path | WebConfiguration.cubicweb_appobject_path
+ cube_appobject_path = ServerConfiguration.cube_appobject_path | WebConfiguration.cube_appobject_path
def __init__(self, cube):
super(DevCubeConfiguration, self).__init__(cube)
@@ -90,7 +90,7 @@
notice that relation definitions description and static vocabulary
should be marked using '_' and extracted using xgettext
"""
- from cubicweb.cwvreg import CubicWebRegistry
+ from cubicweb.cwvreg import CubicWebVRegistry
cube = cubedir and split(cubedir)[-1]
libconfig = DevDepConfiguration(cube)
libconfig.cleanup_interface_sobjects = False
@@ -102,7 +102,7 @@
config = libconfig
libconfig = None
schema = config.load_schema(remove_unused_rtypes=False)
- vreg = CubicWebRegistry(config)
+ vreg = CubicWebVRegistry(config)
# set_schema triggers objects registrations
vreg.set_schema(schema)
w(DEFAULT_POT_HEAD)
@@ -187,8 +187,8 @@
#cube = (cube and 'cubes.%s.' % cube or 'cubicweb.')
done = set()
if libconfig is not None:
- from cubicweb.cwvreg import CubicWebRegistry
- libvreg = CubicWebRegistry(libconfig)
+ from cubicweb.cwvreg import CubicWebVRegistry
+ libvreg = CubicWebVRegistry(libconfig)
libvreg.set_schema(libschema) # trigger objects registration
# prefill done set
list(_iter_vreg_objids(libvreg, done))
--- a/devtools/fake.py Tue Aug 04 15:06:09 2009 +0200
+++ b/devtools/fake.py Tue Aug 04 15:08:18 2009 +0200
@@ -35,26 +35,21 @@
def sources(self):
return {}
-class FakeVReg(object):
+class FakeVReg(dict):
def __init__(self, schema=None, config=None):
self.schema = schema
self.config = config or FakeConfig()
self.properties = {'ui.encoding': 'UTF8',
'ui.language': 'en',
}
+ self.update({
+ 'controllers' : {'login': []},
+ 'views' : {},
+ })
def property_value(self, key):
return self.properties[key]
- _registries = {
- 'controllers' : [Mock(id='view'), Mock(id='login'),
- Mock(id='logout'), Mock(id='edit')],
- 'views' : [Mock(id='primary'), Mock(id='oneline'), Mock(id='list')],
- }
-
- def registry_objects(self, name, oid=None):
- return self._registries[name]
-
def etype_class(self, etype):
class Entity(dict):
e_schema = self.schema[etype]
--- a/devtools/testlib.py Tue Aug 04 15:06:09 2009 +0200
+++ b/devtools/testlib.py Tue Aug 04 15:08:18 2009 +0200
@@ -185,7 +185,8 @@
req = req or rset and rset.req or self.request()
req.form['vid'] = vid
kwargs['rset'] = rset
- view = self.vreg.select('views', vid, req, **kwargs)
+ viewsreg = self.vreg['views']
+ view = viewsreg.select(vid, req, **kwargs)
# set explicit test description
if rset is not None:
self.set_description("testing %s, mod=%s (%s)" % (
@@ -197,9 +198,9 @@
viewfunc = view.render
else:
kwargs['view'] = view
- templateview = self.vreg.select('views', template, req, **kwargs)
- viewfunc = lambda **k: self.vreg.main_template(req, template,
- **kwargs)
+ templateview = viewsreg.select(template, req, **kwargs)
+ viewfunc = lambda **k: viewsreg.main_template(req, template,
+ **kwargs)
kwargs.pop('rset')
return self._test_view(viewfunc, view, template, kwargs)
@@ -272,7 +273,8 @@
req = rset.req
only_once_vids = ('primary', 'secondary', 'text')
req.data['ex'] = ValueError("whatever")
- for vid, views in self.vreg.registry('views').items():
+ viewsvreg = self.vreg['views']
+ for vid, views in viewsvreg.items():
if vid[0] == '_':
continue
if rset.rowcount > 1 and vid in only_once_vids:
@@ -282,7 +284,7 @@
and not issubclass(view, NotificationView)]
if views:
try:
- view = self.vreg.select_best(views, req, rset=rset)
+ view = viewsvreg.select_best(views, req, rset=rset)
if view.linkable():
yield view
else:
@@ -295,19 +297,19 @@
def list_actions_for(self, rset):
"""returns the list of actions that can be applied on `rset`"""
req = rset.req
- for action in self.vreg.possible_objects('actions', req, rset=rset):
+ for action in self.vreg['actions'].possible_objects(req, rset=rset):
yield action
def list_boxes_for(self, rset):
"""returns the list of boxes that can be applied on `rset`"""
req = rset.req
- for box in self.vreg.possible_objects('boxes', req, rset=rset):
+ for box in self.vreg['boxes'].possible_objects(req, rset=rset):
yield box
def list_startup_views(self):
"""returns the list of startup views"""
req = self.request()
- for view in self.vreg.possible_views(req, None):
+ for view in self.vreg['views'].possible_views(req, None):
if view.category == 'startupview':
yield view.id
else:
@@ -375,9 +377,9 @@
rset2 = rset.limit(limit=1, offset=row)
yield rset2
-def not_selected(vreg, vobject):
+def not_selected(vreg, appobject):
try:
- vreg._selected[vobject.__class__] -= 1
+ vreg._selected[appobject.__class__] -= 1
except (KeyError, AttributeError):
pass
@@ -385,26 +387,29 @@
from cubicweb.devtools.apptest import TestEnvironment
env = testclass._env = TestEnvironment('data', configcls=testclass.configcls,
requestcls=testclass.requestcls)
- vreg = env.vreg
- vreg._selected = {}
- orig_select_best = vreg.__class__.select_best
- def instr_select_best(self, *args, **kwargs):
- selected = orig_select_best(self, *args, **kwargs)
+ for reg in env.vreg.values():
+ reg._selected = {}
try:
- self._selected[selected.__class__] += 1
- except KeyError:
- self._selected[selected.__class__] = 1
- except AttributeError:
- pass # occurs on vreg used to restore database
- return selected
- vreg.__class__.select_best = instr_select_best
+ orig_select_best = reg.__class__.__orig_select_best
+ except:
+ orig_select_best = reg.__class__.select_best
+ def instr_select_best(self, *args, **kwargs):
+ selected = orig_select_best(self, *args, **kwargs)
+ try:
+ self._selected[selected.__class__] += 1
+ except KeyError:
+ self._selected[selected.__class__] = 1
+ except AttributeError:
+ pass # occurs on reg used to restore database
+ return selected
+ reg.__class__.select_best = instr_select_best
+ reg.__class__.__orig_select_best = orig_select_best
def print_untested_objects(testclass, skipregs=('hooks', 'etypes')):
- vreg = testclass._env.vreg
- for registry, vobjectsdict in vreg.items():
- if registry in skipregs:
+ for regname, reg in testclass._env.vreg.iteritems():
+ if regname in skipregs:
continue
- for vobjects in vobjectsdict.values():
- for vobject in vobjects:
- if not vreg._selected.get(vobject):
- print 'not tested', registry, vobject
+ for appobjects in reg.itervalues():
+ for appobject in appobjects:
+ if not reg._selected.get(appobject):
+ print 'not tested', regname, appobject
--- a/entities/__init__.py Tue Aug 04 15:06:09 2009 +0200
+++ b/entities/__init__.py Tue Aug 04 15:08:18 2009 +0200
@@ -14,7 +14,6 @@
from cubicweb import Unauthorized, typed_eid
from cubicweb.entity import Entity
-from cubicweb.utils import dump_class
from cubicweb.interfaces import IBreadCrumbs, IFeed
@@ -26,19 +25,6 @@
id = 'Any'
__implements__ = (IBreadCrumbs, IFeed)
- @classmethod
- def selected(cls, etype):
- """the special Any entity is used as the default factory, so
- the actual class has to be constructed at selection time once we
- have an actual entity'type
- """
- if cls.id == etype:
- return cls
- usercls = dump_class(cls, etype)
- usercls.id = etype
- usercls.__initialize__()
- return usercls
-
fetch_attrs = ('modification_date',)
@classmethod
def fetch_order(cls, attr, var):
--- a/entities/test/unittest_base.py Tue Aug 04 15:06:09 2009 +0200
+++ b/entities/test/unittest_base.py Tue Aug 04 15:08:18 2009 +0200
@@ -263,21 +263,24 @@
class InterfaceTC(EnvBasedTC):
def test_nonregr_subclasses_and_mixins_interfaces(self):
+ self.failUnless(implements(CWUser, IWorkflowable))
class MyUser(CWUser):
__implements__ = (IMileStone,)
self.vreg._loadedmods[__name__] = {}
- self.vreg.register_vobject_class(MyUser)
- self.failUnless(implements(CWUser, IWorkflowable))
- self.failUnless(implements(MyUser, IMileStone))
- self.failUnless(implements(MyUser, IWorkflowable))
+ self.vreg.register_appobject_class(MyUser)
+ self.vreg['etypes'].initialization_completed()
+ MyUser_ = self.vreg['etypes'].etype_class('CWUser')
+ self.failUnless(MyUser is MyUser_)
+ self.failUnless(implements(MyUser_, IMileStone))
+ self.failUnless(implements(MyUser_, IWorkflowable))
class SpecializedEntityClassesTC(EnvBasedTC):
def select_eclass(self, etype):
# clear selector cache
- clear_cache(self.vreg, 'etype_class')
- return self.vreg.etype_class(etype)
+ clear_cache(self.vreg['etypes'], 'etype_class')
+ return self.vreg['etypes'].etype_class(etype)
def test_etype_class_selection_and_specialization(self):
# no specific class for Subdivisions, the default one should be selected
@@ -290,7 +293,7 @@
for etype in ('Company', 'Division', 'SubDivision'):
class Foo(AnyEntity):
id = etype
- self.vreg.register_vobject_class(Foo)
+ self.vreg.register_appobject_class(Foo)
eclass = self.select_eclass('SubDivision')
if etype == 'SubDivision':
self.failUnless(eclass is Foo)
--- a/entity.py Tue Aug 04 15:06:09 2009 +0200
+++ b/entity.py Tue Aug 04 15:08:18 2009 +0200
@@ -20,7 +20,7 @@
from cubicweb import Unauthorized
from cubicweb.rset import ResultSet
from cubicweb.selectors import yes
-from cubicweb.appobject import AppRsetObject
+from cubicweb.appobject import AppObject
from cubicweb.schema import RQLVocabularyConstraint, RQLConstraint, bw_normalize_etype
from cubicweb.common.uilib import printable_value, soup2xhtml
@@ -132,7 +132,7 @@
return super(_metaentity, mcs).__new__(mcs, name, bases, classdict)
-class Entity(AppRsetObject, dict):
+class Entity(AppObject, dict):
"""an entity instance has e_schema automagically set on
the class and instances has access to their issuing cursor.
@@ -167,15 +167,6 @@
# class attributes set automatically at registration time
e_schema = None
- @classmethod
- def registered(cls, registry):
- """build class using descriptor at registration time"""
- assert cls.id is not None
- super(Entity, cls).registered(registry)
- if cls.id != 'Any':
- cls.__initialize__()
- return cls
-
MODE_TAGS = set(('link', 'create'))
CATEGORY_TAGS = set(('primary', 'secondary', 'generic', 'generated')) # , 'metadata'))
@classmethod
@@ -265,7 +256,7 @@
continue
if card == '?':
restrictions[-1] += '?' # left outer join if not mandatory
- destcls = cls.vreg.etype_class(desttype)
+ destcls = cls.vreg['etypes'].etype_class(desttype)
destcls._fetch_restrictions(var, varmaker, destcls.fetch_attrs,
selection, orderby, restrictions,
user, ordermethod, visited=visited)
@@ -277,8 +268,9 @@
@classmethod
@cached
def parent_classes(cls):
- parents = [cls.vreg.etype_class(e.type) for e in cls.e_schema.ancestors()]
- parents.append(cls.vreg.etype_class('Any'))
+ parents = [cls.vreg['etypes'].etype_class(e.type)
+ for e in cls.e_schema.ancestors()]
+ parents.append(cls.vreg['etypes'].etype_class('Any'))
return parents
@classmethod
@@ -299,7 +291,7 @@
return mainattr, needcheck
def __init__(self, req, rset=None, row=None, col=0):
- AppRsetObject.__init__(self, req, rset, row, col)
+ AppObject.__init__(self, req, rset, row, col)
dict.__init__(self)
self._related_cache = {}
if rset is not None:
@@ -364,10 +356,10 @@
def has_perm(self, action):
return self.e_schema.has_perm(self.req, action, self.eid)
- def view(self, vid, **kwargs):
+ def view(self, vid, __registry='views', **kwargs):
"""shortcut to apply a view on this entity"""
- return self.vreg.render(vid, self.req, rset=self.rset,
- row=self.row, col=self.col, **kwargs)
+ return self.vreg[__registry].render(vid, self.req, rset=self.rset,
+ row=self.row, col=self.col, **kwargs)
def absolute_url(self, *args, **kwargs):
"""return an absolute url to view this entity"""
@@ -702,13 +694,13 @@
if len(targettypes) > 1:
fetchattrs_list = []
for ttype in targettypes:
- etypecls = self.vreg.etype_class(ttype)
+ etypecls = self.vreg['etypes'].etype_class(ttype)
fetchattrs_list.append(set(etypecls.fetch_attrs))
fetchattrs = reduce(set.intersection, fetchattrs_list)
rql = etypecls.fetch_rql(self.req.user, [restriction], fetchattrs,
settype=False)
else:
- etypecls = self.vreg.etype_class(targettypes[0])
+ etypecls = self.vreg['etypes'].etype_class(targettypes[0])
rql = etypecls.fetch_rql(self.req.user, [restriction], settype=False)
# optimisation: remove ORDERBY if cardinality is 1 or ? (though
# greater_card return 1 for those both cases)
@@ -764,7 +756,7 @@
else:
restriction += [cstr.restriction for cstr in constraints
if isinstance(cstr, RQLConstraint)]
- etypecls = self.vreg.etype_class(targettype)
+ etypecls = self.vreg['etypes'].etype_class(targettype)
rql = etypecls.fetch_rql(self.req.user, restriction,
mainvar=searchedvar, ordermethod=ordermethod)
# ensure we have an order defined
--- a/etwist/server.py Tue Aug 04 15:06:09 2009 +0200
+++ b/etwist/server.py Tue Aug 04 15:08:18 2009 +0200
@@ -109,7 +109,7 @@
self.pyro_listen_timeout = 0.02
start_task(1, self.pyro_loop_event)
self.appli.repo.start_looping_tasks()
- self.url_rewriter = self.appli.vreg.select_object('components', 'urlrewriter')
+ self.url_rewriter = self.appli.vreg['components'].select_object('urlrewriter')
interval = min(config['cleanup-session-time'] or 120,
config['cleanup-anonymous-session-time'] or 720) / 2.
start_task(interval, self.appli.session_handler.clean_sessions)
@@ -330,7 +330,7 @@
def _gc_debug():
import gc
from pprint import pprint
- from cubicweb.vregistry import VObject
+ from cubicweb.appobject import AppObject
gc.collect()
count = 0
acount = 0
@@ -338,7 +338,7 @@
for obj in gc.get_objects():
if isinstance(obj, CubicWebTwistedRequestAdapter):
count += 1
- elif isinstance(obj, VObject):
+ elif isinstance(obj, AppObject):
acount += 1
else:
try:
--- a/etwist/twconfig.py Tue Aug 04 15:06:09 2009 +0200
+++ b/etwist/twconfig.py Tue Aug 04 15:08:18 2009 +0200
@@ -87,8 +87,8 @@
options = merge_options(TwistedConfiguration.options
+ ServerConfiguration.options)
- cubicweb_vobject_path = TwistedConfiguration.cubicweb_vobject_path | ServerConfiguration.cubicweb_vobject_path
- cube_vobject_path = TwistedConfiguration.cube_vobject_path | ServerConfiguration.cube_vobject_path
+ cubicweb_appobject_path = TwistedConfiguration.cubicweb_appobject_path | ServerConfiguration.cubicweb_appobject_path
+ cube_appobject_path = TwistedConfiguration.cube_appobject_path | ServerConfiguration.cube_appobject_path
def pyro_enabled(self):
"""tell if pyro is activated for the in memory repository"""
return self['pyro-server']
--- a/goa/db.py Tue Aug 04 15:06:09 2009 +0200
+++ b/goa/db.py Tue Aug 04 15:08:18 2009 +0200
@@ -274,8 +274,8 @@
def view(self, vid, __registry='views', **kwargs):
"""shortcut to apply a view on this entity"""
- return self.vreg.render(__registry, vid, self.req, rset=self.rset,
- row=self.row, col=self.col, **kwargs)
+ return self.vreg[__registry]render(vid, self.req, rset=self.rset,
+ row=self.row, col=self.col, **kwargs)
@classmethod
def _rest_attr_info(cls):
--- a/goa/goaconfig.py Tue Aug 04 15:06:09 2009 +0200
+++ b/goa/goaconfig.py Tue Aug 04 15:08:18 2009 +0200
@@ -17,8 +17,8 @@
from cubicweb.goa.dbmyams import load_schema
UNSUPPORTED_OPTIONS = set(('connections-pool-size',
- 'pyro-port', 'pyro-id', 'pyro-instance-id',
- 'pyro-ns-host', 'pyro-ns-port', 'pyro-ns-group',
+ 'pyro-host', 'pyro-id', 'pyro-instance-id',
+ 'pyro-ns-host', 'pyro-ns-group',
'https-url', 'host', 'pid-file', 'uid', 'base-url', 'log-file',
'smtp-host', 'smtp-port',
'embed-allowed',
@@ -81,9 +81,9 @@
options = [(optname, optdict) for optname, optdict in options
if not optname in UNSUPPORTED_OPTIONS]
- cubicweb_vobject_path = WebConfiguration.cubicweb_vobject_path | ServerConfiguration.cubicweb_vobject_path
- cubicweb_vobject_path = list(cubicweb_vobject_path) + ['goa/appobjects']
- cube_vobject_path = WebConfiguration.cube_vobject_path | ServerConfiguration.cube_vobject_path
+ cubicweb_appobject_path = WebConfiguration.cubicweb_appobject_path | ServerConfiguration.cubicweb_appobject_path
+ cubicweb_appobject_path = list(cubicweb_appobject_path) + ['goa/appobjects']
+ cube_appobject_path = WebConfiguration.cube_appobject_path | ServerConfiguration.cube_appobject_path
# use file system schema
bootstrap_schema = read_instance_schema = False
--- a/goa/goavreg.py Tue Aug 04 15:06:09 2009 +0200
+++ b/goa/goavreg.py Tue Aug 04 15:08:18 2009 +0200
@@ -11,7 +11,7 @@
from os.path import join, isdir
from cubicweb import CW_SOFTWARE_ROOT
-from cubicweb.cwvreg import CubicWebRegistry
+from cubicweb.cwvreg import CubicWebVRegistry
def _pkg_name(cube, module):
@@ -19,7 +19,7 @@
return module
return 'cubes.%s.%s' % (cube, module)
-class GAERegistry(CubicWebRegistry):
+class GAEVRegistry(CubicWebVRegistry):
def set_schema(self, schema):
"""disable reload hooks of cubicweb registry set_schema method"""
@@ -59,7 +59,7 @@
self.load_module(obj)
def _auto_load(self, path, loadschema, cube=None):
- vobjpath = self.config.cube_vobject_path
+ vobjpath = self.config.cube_appobject_path
for filename in listdir(path):
if filename[-3:] == '.py' and filename[:-3] in vobjpath:
self._import(_pkg_name(cube, filename[:-3]))
--- a/goa/skel/main.py Tue Aug 04 15:06:09 2009 +0200
+++ b/goa/skel/main.py Tue Aug 04 15:08:18 2009 +0200
@@ -22,8 +22,8 @@
config = GAEConfiguration('toto', APPLROOT)
# dynamic objects registry
-from cubicweb.goa.goavreg import GAERegistry
-vreg = GAERegistry(config, debug=goa.MODE == 'dev')
+from cubicweb.goa.goavreg import GAEVregistry
+vreg = GAEVregistry(config, debug=goa.MODE == 'dev')
# trigger automatic classes registration (metaclass magic), should be done
# before schema loading
--- a/goa/test/unittest_views.py Tue Aug 04 15:06:09 2009 +0200
+++ b/goa/test/unittest_views.py Tue Aug 04 15:08:18 2009 +0200
@@ -46,10 +46,10 @@
self.blog.put(self.req)
def test_hcal(self):
- self.vreg.render('views', 'hcal', self.req, rset=self.blog.rset)
+ self.vreg['views'].render('hcal', self.req, rset=self.blog.rset)
def test_django_index(self):
- self.vreg.render('views', 'index', self.req, rset=None)
+ self.vreg'views'].render('index', self.req, rset=None)
for vid in ('primary', 'oneline', 'incontext', 'outofcontext', 'text'):
setattr(SomeViewsTC, 'test_%s'%vid, lambda self, vid=vid: self.blog.view(vid))
--- a/goa/testlib.py Tue Aug 04 15:06:09 2009 +0200
+++ b/goa/testlib.py Tue Aug 04 15:08:18 2009 +0200
@@ -42,7 +42,7 @@
from cubicweb.devtools.fake import FakeRequest
-from cubicweb.goa.goavreg import GAERegistry
+from cubicweb.goa.goavreg import GAEVregistry
from cubicweb.goa.goaconfig import GAEConfiguration
from cubicweb.goa.dbinit import (create_user, create_groups, fix_entities,
init_persistent_schema, insert_versions)
@@ -115,7 +115,7 @@
self.config.init_log(logging.CRITICAL)
self.schema = self.config.load_schema(self.MODEL_CLASSES,
self.load_schema_hook)
- self.vreg = GAERegistry(self.config)
+ self.vreg = GAEVregistry(self.config)
self.vreg.schema = self.schema
self.vreg.load_module(db)
from cubicweb.goa.appobjects import sessions
--- a/goa/tools/laxctl.py Tue Aug 04 15:06:09 2009 +0200
+++ b/goa/tools/laxctl.py Tue Aug 04 15:08:18 2009 +0200
@@ -28,11 +28,11 @@
# apply monkey patches first
from cubicweb.goa import do_monkey_patch
do_monkey_patch()
- from cubicweb.goa.goavreg import GAERegistry
+ from cubicweb.goa.goavreg import GAEVregistry
from cubicweb.goa.goaconfig import GAEConfiguration
#WebConfiguration.ext_resources['JAVASCRIPTS'].append('DATADIR/goa.js')
config = GAEConfiguration('toto', applroot)
- vreg = GAERegistry(config)
+ vreg = GAEVregistry(config)
vreg.set_schema(config.load_schema())
return vreg
--- a/rset.py Tue Aug 04 15:06:09 2009 +0200
+++ b/rset.py Tue Aug 04 15:08:18 2009 +0200
@@ -83,8 +83,8 @@
try:
return self._rsetactions[key]
except KeyError:
- actions = self.vreg.possible_vobjects('actions', self.req,
- rset=self, **kwargs)
+ actions = self.vreg['actions'].possible_vobjects(
+ self.req, rset=self, **kwargs)
self._rsetactions[key] = actions
return actions
@@ -370,12 +370,21 @@
# XXX should we consider updating a cached entity with possible
# new attributes found in this resultset ?
try:
- return req.entity_cache(eid)
+ entity = req.entity_cache(eid)
+ if entity.rset is None:
+ # entity has no rset set, this means entity has been cached by
+ # the repository (req is a repository session) which had no rset
+ # info. Add id.
+ entity.rset = self
+ entity.row = row
+ entity.col = col
+ return entity
except KeyError:
pass
# build entity instance
etype = self.description[row][col]
- entity = self.vreg.etype_class(etype)(req, self, row, col)
+ entity = self.vreg['etypes'].etype_class(etype)(req, rset=self,
+ row=row, col=col)
entity.set_eid(eid)
# cache entity
req.set_entity_cache(entity)
--- a/schemas/base.py Tue Aug 04 15:06:09 2009 +0200
+++ b/schemas/base.py Tue Aug 04 15:08:18 2009 +0200
@@ -242,7 +242,7 @@
The target application is responsible for updating timestamp
when necessary to invalidate the cache (typically in hooks).
- Also, checkout the AppRsetObject.get_cache() method.
+ Also, checkout the AppObject.get_cache() method.
"""
permissions = {
'read': ('managers', 'users', 'guests'),
--- a/schemaviewer.py Tue Aug 04 15:06:09 2009 +0200
+++ b/schemaviewer.py Tue Aug 04 15:08:18 2009 +0200
@@ -19,7 +19,7 @@
self.req = req
if req is not None:
self.req.add_css('cubicweb.schema.css')
- self._possible_views = req.vreg.possible_views
+ self._possible_views = req.vreg['views'].possible_views
if not encoding:
encoding = req.encoding
else:
--- a/selectors.py Tue Aug 04 15:06:09 2009 +0200
+++ b/selectors.py Tue Aug 04 15:08:18 2009 +0200
@@ -53,8 +53,8 @@
from cubicweb import (Unauthorized, NoSelectableObject, NotAnEntity,
role, typed_eid)
-from cubicweb.vregistry import (NoSelectableObject, Selector,
- chainall, objectify_selector)
+# even if not used, let yes here so it's importable through this module
+from cubicweb.appobject import Selector, objectify_selector, yes
from cubicweb.cwconfig import CubicWebConfiguration
from cubicweb.schema import split_expression
@@ -165,7 +165,7 @@
if isinstance(iface, basestring):
# entity type
try:
- iface = vreg.etype_class(iface)
+ iface = vreg['etypes'].etype_class(iface)
except KeyError:
continue # entity type not in the schema
score += score_interface(cls_or_inst, cls, iface)
@@ -212,7 +212,7 @@
def score(self, cls, req, etype):
if etype in BASE_TYPES:
return 0
- return self.score_class(cls.vreg.etype_class(etype), req)
+ return self.score_class(cls.vreg['etypes'].etype_class(etype), req)
def score_class(self, eclass, req):
raise NotImplementedError()
@@ -274,17 +274,6 @@
# very basic selectors ########################################################
-class yes(Selector):
- """return arbitrary score
-
- default score of 0.5 so any other selector take precedence
- """
- def __init__(self, score=0.5):
- self.score = score
-
- def __call__(self, *args, **kwargs):
- return self.score
-
@objectify_selector
@lltrace
def none_rset(cls, req, rset=None, **kwargs):
@@ -570,9 +559,9 @@
self.registry = registry
self.oid = oid
- def __call__(self, cls, req, rset=None, *args, **kwargs):
+ def __call__(self, cls, req, **kwargs):
try:
- cls.vreg.select(self.registry, self.oid, req, rset=rset, **kwargs)
+ cls.vreg[self.registry].select(self.oid, req, **kwargs)
return 1
except NoSelectableObject:
return 0
@@ -630,7 +619,7 @@
req.form['etype'] = etype
except KeyError:
return 0
- return self.score_class(cls.vreg.etype_class(etype), req)
+ return self.score_class(cls.vreg['etypes'].etype_class(etype), req)
class entity_implements(ImplementsMixIn, EntitySelector):
@@ -975,6 +964,7 @@
# XXX DEPRECATED ##############################################################
+from cubicweb.vregistry import chainall
yes_selector = deprecated()(yes)
norset_selector = deprecated()(none_rset)
@@ -1040,7 +1030,7 @@
accept_selector = deprecated()(accept)
accept_one = deprecated()(chainall(one_line_rset, accept,
- name='accept_one'))
+ name='accept_one'))
accept_one_selector = deprecated()(accept_one)
--- a/server/repository.py Tue Aug 04 15:06:09 2009 +0200
+++ b/server/repository.py Tue Aug 04 15:08:18 2009 +0200
@@ -33,7 +33,7 @@
BadConnectionId, Unauthorized, ValidationError,
ExecutionError, typed_eid,
CW_MIGRATION_MAP)
-from cubicweb.cwvreg import CubicWebRegistry
+from cubicweb.cwvreg import CubicWebVRegistry
from cubicweb.schema import VIRTUAL_RTYPES, CubicWebSchema
from cubicweb import server
from cubicweb.server.utils import RepoThread, LoopTask
@@ -137,7 +137,7 @@
def __init__(self, config, vreg=None, debug=False):
self.config = config
if vreg is None:
- vreg = CubicWebRegistry(config, debug)
+ vreg = CubicWebVRegistry(config, debug)
self.vreg = vreg
self.pyro_registered = False
self.info('starting repository from %s', self.config.apphome)
@@ -428,7 +428,7 @@
def _build_user(self, session, eid):
"""return a CWUser entity for user with the given eid"""
- cls = self.vreg.etype_class('CWUser')
+ cls = self.vreg['etypes'].etype_class('CWUser')
rql = cls.fetch_rql(session.user, ['X eid %(x)s'])
rset = session.execute(rql, {'x': eid}, 'x')
assert len(rset) == 1, rset
@@ -532,7 +532,7 @@
{'login': login})):
raise ValidationError(None, {'login': errmsg % login})
# we have to create the user
- user = self.vreg.etype_class('CWUser')(session, None)
+ user = self.vreg['etypes'].etype_class('CWUser')(session, None)
if isinstance(password, unicode):
# password should *always* be utf8 encoded
password = password.encode('UTF8')
@@ -1038,13 +1038,15 @@
entity.eid, attr, value)
return entity.eid
- def glob_update_entity(self, session, entity):
+ def glob_update_entity(self, session, entity, edited_attributes):
"""replace an entity in the repository
the type and the eid of an entity must not be changed
"""
etype = str(entity.e_schema)
if server.DEBUG & server.DBG_REPO:
- print 'UPDATE entity', etype, entity.eid, dict(entity)
+ print 'UPDATE entity', etype, entity.eid, \
+ dict(entity), edited_attributes
+ entity.edited_attributes = edited_attributes
entity.check()
eschema = entity.e_schema
session.set_entity_cache(entity)
@@ -1164,36 +1166,16 @@
def pyro_register(self, host=''):
"""register the repository as a pyro object"""
- from Pyro import core
- port = self.config['pyro-port']
- nshost, nsgroup = self.config['pyro-ns-host'], self.config['pyro-ns-group']
- nsgroup = ':' + nsgroup
- core.initServer(banner=0)
- daemon = core.Daemon(host=host, port=port)
- daemon.useNameServer(self.pyro_nameserver(nshost, nsgroup))
- # use Delegation approach
- impl = core.ObjBase()
- impl.delegateTo(self)
- nsid = self.config['pyro-id'] or self.config.appid
- daemon.connect(impl, '%s.%s' % (nsgroup, nsid))
+ from logilab.common.pyro_ext import register_object
+ appid = self.config['pyro-id'] or self.config.appid
+ daemon = register_object(self, appid, self.config['pyro-ns-group'],
+ self.config['pyro-host'],
+ self.config['pyro-ns-host'])
msg = 'repository registered as a pyro object using group %s and id %s'
- self.info(msg, nsgroup, nsid)
+ self.info(msg, self.config['pyro-ns-group'], appid)
self.pyro_registered = True
return daemon
- def pyro_nameserver(self, host=None, group=None):
- """locate and bind the the name server to the daemon"""
- from Pyro import naming, errors
- # locate the name server
- nameserver = naming.NameServerLocator().getNS(host)
- if group is not None:
- # make sure our namespace group exists
- try:
- nameserver.createGroup(group)
- except errors.NamingError:
- pass
- return nameserver
-
# multi-sources planner helpers ###########################################
@cached
@@ -1217,21 +1199,9 @@
def pyro_unregister(config):
"""unregister the repository from the pyro name server"""
- nshost, nsgroup = config['pyro-ns-host'], config['pyro-ns-group']
+ from logilab.common.pyro_ext import ns_unregister
appid = config['pyro-id'] or config.appid
- from Pyro import core, naming, errors
- core.initClient(banner=False)
- try:
- nameserver = naming.NameServerLocator().getNS(nshost)
- except errors.PyroError, ex:
- # name server not responding
- config.error('can\'t locate pyro name server: %s', ex)
- return
- try:
- nameserver.unregister(':%s.%s' % (nsgroup, appid))
- config.info('%s unregistered from pyro name server', appid)
- except errors.NamingError:
- config.warning('%s already unregistered from pyro name server', appid)
+ ns_unregister(appid, config['pyro-ns-group'], config['pyro-ns-host'])
from logging import getLogger
--- a/server/serverconfig.py Tue Aug 04 15:06:09 2009 +0200
+++ b/server/serverconfig.py Tue Aug 04 15:08:18 2009 +0200
@@ -85,8 +85,8 @@
SCHEMAS_LIB_DIR = '/usr/share/cubicweb/schemas/'
BACKUP_DIR = '/var/lib/cubicweb/backup/'
- cubicweb_vobject_path = CubicWebConfiguration.cubicweb_vobject_path | set(['sobjects'])
- cube_vobject_path = CubicWebConfiguration.cube_vobject_path | set(['sobjects', 'hooks'])
+ cubicweb_appobject_path = CubicWebConfiguration.cubicweb_appobject_path | set(['sobjects'])
+ cube_appobject_path = CubicWebConfiguration.cube_appobject_path | set(['sobjects', 'hooks'])
options = merge_options((
# ctl configuration
@@ -165,10 +165,12 @@
'group': 'email', 'inputlevel': 2,
}),
# pyro server.serverconfig
- ('pyro-port',
+ ('pyro-host',
{'type' : 'int',
'default': None,
- 'help': 'Pyro server port. If not set, it will be choosen randomly',
+ 'help': 'Pyro server host, if not detectable correctly through \
+gethostname(). It may contains port information using <host>:<port> notation, \
+and if not set, it will be choosen randomly',
'group': 'pyro-server', 'inputlevel': 2,
}),
('pyro-id', # XXX reuse pyro-instance-id
@@ -265,7 +267,7 @@
def load_hooks(self, vreg):
hooks = {}
try:
- apphookdefs = vreg.registry_objects('hooks')
+ apphookdefs = vreg['hooks'].all_objects()
except RegistryNotFound:
return hooks
for hookdef in apphookdefs:
--- a/server/session.py Tue Aug 04 15:06:09 2009 +0200
+++ b/server/session.py Tue Aug 04 15:08:18 2009 +0200
@@ -142,10 +142,6 @@
"""return the original parent session if any, else self"""
return self
- def etype_class(self, etype):
- """return an entity class for the given entity type"""
- return self.vreg.etype_class(etype)
-
def system_sql(self, sql, args=None, rollback_on_failure=True):
"""return a sql cursor on the system database"""
if not sql.split(None, 1)[0].upper() == 'SELECT':
@@ -555,6 +551,11 @@
description.append(tuple(row_descr))
return description
+ @deprecated("use vreg['etypes'].etype_class(etype)")
+ def etype_class(self, etype):
+ """return an entity class for the given entity type"""
+ return self.vreg['etypes'].etype_class(etype)
+
@deprecated('use direct access to session.transaction_data')
def query_data(self, key, default=None, setdefault=False, pop=False):
if setdefault:
--- a/server/sources/__init__.py Tue Aug 04 15:06:09 2009 +0200
+++ b/server/sources/__init__.py Tue Aug 04 15:08:18 2009 +0200
@@ -325,7 +325,7 @@
This method must return the an Entity instance representation of this
entity.
"""
- entity = self.repo.vreg.etype_class(etype)(session, None)
+ entity = self.repo.vreg['etypes'].etype_class(etype)(session)
entity.set_eid(eid)
return entity
--- a/server/sources/pyrorql.py Tue Aug 04 15:06:09 2009 +0200
+++ b/server/sources/pyrorql.py Tue Aug 04 15:08:18 2009 +0200
@@ -79,14 +79,7 @@
{'type' : 'string',
'default': None,
'help': 'Pyro name server\'s host. If not set, default to the value \
-from all_in_one.conf.',
- 'group': 'pyro-source', 'inputlevel': 1,
- }),
- ('pyro-ns-port',
- {'type' : 'int',
- 'default': None,
- 'help': 'Pyro name server\'s listening port. If not set, default to \
-the value from all_in_one.conf.',
+from all_in_one.conf. It may contains port information using <host>:<port> notation.',
'group': 'pyro-source', 'inputlevel': 1,
}),
('pyro-ns-group',
@@ -214,13 +207,12 @@
def _get_connection(self):
"""open and return a connection to the source"""
nshost = self.config.get('pyro-ns-host') or self.repo.config['pyro-ns-host']
- nsport = self.config.get('pyro-ns-port') or self.repo.config['pyro-ns-port']
nsgroup = self.config.get('pyro-ns-group') or self.repo.config['pyro-ns-group']
#cnxprops = ConnectionProperties(cnxtype=self.config['cnx-type'])
return dbapi.connect(database=self.config['pyro-ns-id'],
login=self.config['cubicweb-user'],
password=self.config['cubicweb-password'],
- host=nshost, port=nsport, group=nsgroup,
+ host=nshost, group=nsgroup,
setvreg=False) #cnxprops=cnxprops)
def get_connection(self):
--- a/server/ssplanner.py Tue Aug 04 15:06:09 2009 +0200
+++ b/server/ssplanner.py Tue Aug 04 15:08:18 2009 +0200
@@ -114,9 +114,10 @@
# each variable in main variables is a new entity to insert
to_build = {}
session = plan.session
+ etype_class = session.vreg['etypes'].etype_class
for etype, var in rqlst.main_variables:
# need to do this since entity class is shared w. web client code !
- to_build[var.name] = session.etype_class(etype)(session, None, None)
+ to_build[var.name] = etype_class(etype)(session)
plan.add_entity_def(to_build[var.name])
# add constant values to entity def, mark variables to be selected
to_select = plan.relation_definitions(rqlst, to_build)
@@ -481,6 +482,7 @@
repo = session.repo
edefs = {}
# insert relations
+ attributes = [relation.r_type for relation in self.attribute_relations]
for row in self.execute_child():
for relation in self.attribute_relations:
lhs, rhs = relation.get_variable_parts()
@@ -488,7 +490,7 @@
try:
edef = edefs[eid]
except KeyError:
- edefs[eid] = edef = session.eid_rset(eid).get_entity(0, 0)
+ edefs[eid] = edef = session.entity_from_eid(eid)
if isinstance(rhs, Constant):
# add constant values to entity def
value = rhs.eval(plan.args)
@@ -502,6 +504,6 @@
# update entities
result = []
for eid, edef in edefs.iteritems():
- repo.glob_update_entity(session, edef)
+ repo.glob_update_entity(session, edef, attributes)
result.append( (eid,) )
return result
--- a/server/test/unittest_repository.py Tue Aug 04 15:06:09 2009 +0200
+++ b/server/test/unittest_repository.py Tue Aug 04 15:08:18 2009 +0200
@@ -20,7 +20,7 @@
from cubicweb import BadConnectionId, RepositoryError, ValidationError, UnknownEid, AuthenticationError
from cubicweb.schema import CubicWebSchema, RQLConstraint
-from cubicweb.dbapi import connect, repo_connect
+from cubicweb.dbapi import connect, repo_connect, multiple_connections_unfix
from cubicweb.devtools.apptest import RepositoryBasedTC
from cubicweb.devtools.repotest import tuplify
from cubicweb.server import repository
@@ -276,13 +276,17 @@
def _pyro_client(self, done):
cnx = connect(self.repo.config.appid, u'admin', 'gingkow')
- # check we can get the schema
- schema = cnx.get_schema()
- self.assertEquals(schema.__hashmode__, None)
- cu = cnx.cursor()
- rset = cu.execute('Any U,G WHERE U in_group G')
- cnx.close()
- done.append(True)
+ try:
+ # check we can get the schema
+ schema = cnx.get_schema()
+ self.assertEquals(schema.__hashmode__, None)
+ cu = cnx.cursor()
+ rset = cu.execute('Any U,G WHERE U in_group G')
+ cnx.close()
+ done.append(True)
+ finally:
+ # connect monkey path some method by default, remove them
+ multiple_connections_unfix()
def test_internal_api(self):
repo = self.repo
@@ -367,7 +371,7 @@
self.assertRaises(UnknownEid, self.repo.type_from_eid, -2, self.session)
def test_add_delete_info(self):
- entity = self.repo.vreg.etype_class('Personne')(self.session, None, None)
+ entity = self.repo.vreg['etypes'].etype_class('Personne')(self.session)
entity.eid = -1
entity.complete = lambda x: None
self.repo.add_info(self.session, entity, self.repo.sources_by_uri['system'])
--- a/sobjects/notification.py Tue Aug 04 15:06:09 2009 +0200
+++ b/sobjects/notification.py Tue Aug 04 15:08:18 2009 +0200
@@ -76,8 +76,8 @@
return
rset = entity.related('wf_info_for')
try:
- view = session.vreg.select('views', 'notif_status_change',
- session, rset=rset, row=0)
+ view = session.vreg['views'].select('notif_status_change', session,
+ rset=rset, row=0)
except RegistryException:
return
comment = entity.printable_value('comment', format='text/plain')
@@ -100,7 +100,7 @@
rset = session.eid_rset(fromeid)
vid = 'notif_%s_%s' % (self.event, rtype)
try:
- view = session.vreg.select('views', vid, session, rset=rset, row=0)
+ view = session.vreg['views'].select(vid, session, rset=rset, row=0)
except RegistryException:
return
RenderAndSendNotificationView(session, view=view)
@@ -117,7 +117,7 @@
rset = entity.as_rset()
vid = 'notif_%s' % self.event
try:
- view = session.vreg.select('views', vid, session, rset=rset, row=0)
+ view = session.vreg['views'].select(vid, session, rset=rset, row=0)
except RegistryException:
return
RenderAndSendNotificationView(session, view=view)
@@ -138,7 +138,7 @@
msgid_timestamp = True
def recipients(self):
- finder = self.vreg.select('components', 'recipients_finder', self.req,
+ finder = self.vreg['components'].select('recipients_finder', self.req,
rset=self.rset)
return finder.recipients()
--- a/sobjects/supervising.py Tue Aug 04 15:06:09 2009 +0200
+++ b/sobjects/supervising.py Tue Aug 04 15:08:18 2009 +0200
@@ -31,12 +31,16 @@
SupervisionMailOp(session)
def _call(self, *args):
- if self._event() == 'update_entity' and args[0].e_schema == 'CWUser':
- updated = set(args[0].iterkeys())
- if not (updated - frozenset(('eid', 'modification_date', 'last_login_time'))):
- # don't record last_login_time update which are done
- # automatically at login time
+ if self._event() == 'update_entity':
+ if args[0].eid in self.session.transaction_data.get('neweids', ()):
return False
+ if args[0].e_schema == 'CWUser':
+ updated = set(args[0].iterkeys())
+ if not (updated - frozenset(('eid', 'modification_date',
+ 'last_login_time'))):
+ # don't record last_login_time update which are done
+ # automatically at login time
+ return False
self.session.transaction_data.setdefault('pendingchanges', []).append(
(self._event(), args))
return True
@@ -218,8 +222,8 @@
of changes
"""
def _get_view(self):
- return self.session.vreg.select('components', 'supervision_notif',
- self.session)
+ return self.session.vreg['components'].select('supervision_notif',
+ self.session)
def _prepare_email(self):
session = self.session
--- a/sobjects/test/data/schema.py Tue Aug 04 15:06:09 2009 +0200
+++ b/sobjects/test/data/schema.py Tue Aug 04 15:08:18 2009 +0200
@@ -5,6 +5,8 @@
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
+from yams.buildobjs import RelationDefinition
+
class comments(RelationDefinition):
subject = 'Comment'
object = 'Card'
--- a/sobjects/test/unittest_notification.py Tue Aug 04 15:06:09 2009 +0200
+++ b/sobjects/test/unittest_notification.py Tue Aug 04 15:08:18 2009 +0200
@@ -56,8 +56,8 @@
self.execute('INSERT CWProperty X: X pkey "ui.language", X value "fr", X for_user U '
'WHERE U eid %(x)s', {'x': urset[0][0]})
self.commit() # commit so that admin get its properties updated
- finder = self.vreg.select('components', 'recipients_finder', self.request(),
- rset=urset)
+ finder = self.vreg['components'].select('recipients_finder',
+ self.request(), rset=urset)
self.set_option('default-recipients-mode', 'none')
self.assertEquals(finder.recipients(), [])
self.set_option('default-recipients-mode', 'users')
@@ -73,8 +73,9 @@
req = self.session()
u = self.create_user('toto', req=req)
assert u.req
+ assert u.rset
self.execute('SET X in_state S WHERE X eid %s, S name "deactivated"' % u.eid)
- v = self.vreg.select('views', 'notif_status_change', req, rset=u.rset, row=0)
+ v = self.vreg['views'].select('notif_status_change', req, rset=u.rset, row=0)
content = v.render(row=0, comment='yeah',
previous_state='activated',
current_state='deactivated')
--- a/test/unittest_entity.py Tue Aug 04 15:06:09 2009 +0200
+++ b/test/unittest_entity.py Tue Aug 04 15:08:18 2009 +0200
@@ -121,9 +121,9 @@
def test_fetch_rql(self):
user = self.user()
- Personne = self.vreg.etype_class('Personne')
- Societe = self.vreg.etype_class('Societe')
- Note = self.vreg.etype_class('Note')
+ Personne = self.vreg['etypes'].etype_class('Personne')
+ Societe = self.vreg['etypes'].etype_class('Societe')
+ Note = self.vreg['etypes'].etype_class('Note')
peschema = Personne.e_schema
seschema = Societe.e_schema
peschema.subject_relation('travaille').set_rproperty(peschema, seschema, 'cardinality', '1*')
@@ -175,8 +175,8 @@
def test_related_rql(self):
from cubicweb.entities import fetch_config
- Personne = self.vreg.etype_class('Personne')
- Note = self.vreg.etype_class('Note')
+ Personne = self.vreg['etypes'].etype_class('Personne')
+ Note = self.vreg['etypes'].etype_class('Note')
Personne.fetch_attrs, Personne.fetch_order = fetch_config(('nom', 'type'))
Note.fetch_attrs, Note.fetch_order = fetch_config(('type',))
aff = self.add_entity('Personne', nom=u'pouet')
--- a/test/unittest_rtags.py Tue Aug 04 15:06:09 2009 +0200
+++ b/test/unittest_rtags.py Tue Aug 04 15:08:18 2009 +0200
@@ -39,7 +39,7 @@
# __rtags__ = {
# ('evaluee', 'Note', 'subject') : set(('inlineview',)),
# }
-# self.vreg.register_vobject_class(Personne2)
+# self.vreg.register_appobject_class(Personne2)
# rtags = Personne2.rtags
# self.assertEquals(rtags.rtag('evaluee', 'Note', 'subject'), set(('inlineview', 'link')))
# self.assertEquals(rtags.is_inlined('evaluee', 'Note', 'subject'), True)
--- a/test/unittest_selectors.py Tue Aug 04 15:06:09 2009 +0200
+++ b/test/unittest_selectors.py Tue Aug 04 15:08:18 2009 +0200
@@ -9,7 +9,7 @@
from logilab.common.testlib import TestCase, unittest_main
from cubicweb.devtools.testlib import EnvBasedTC
-from cubicweb.vregistry import Selector, AndSelector, OrSelector
+from cubicweb.appobject import Selector, AndSelector, OrSelector
from cubicweb.selectors import implements, match_user_groups
from cubicweb.interfaces import IDownloadable
from cubicweb.web import action
@@ -91,7 +91,7 @@
class ImplementsSelectorTC(EnvBasedTC):
def test_etype_priority(self):
req = self.request()
- cls = self.vreg.etype_class('File')
+ cls = self.vreg['etypes'].etype_class('File')
anyscore = implements('Any').score_class(cls, req)
idownscore = implements(IDownloadable).score_class(cls, req)
self.failUnless(idownscore > anyscore, (idownscore, anyscore))
@@ -99,7 +99,7 @@
self.failUnless(filescore > idownscore, (filescore, idownscore))
def test_etype_inheritance_no_yams_inheritance(self):
- cls = self.vreg.etype_class('Personne')
+ cls = self.vreg['etypes'].etype_class('Personne')
self.failIf(implements('Societe').score_class(cls, self.request()))
@@ -111,7 +111,7 @@
category = 'foo'
__select__ = match_user_groups('owners')
self.vreg._loadedmods[__name__] = {}
- self.vreg.register_vobject_class(SomeAction)
+ self.vreg.register_appobject_class(SomeAction)
self.failUnless(SomeAction in self.vreg['actions']['yo'], self.vreg['actions'])
try:
# login as a simple user
--- a/test/unittest_vregistry.py Tue Aug 04 15:06:09 2009 +0200
+++ b/test/unittest_vregistry.py Tue Aug 04 15:08:18 2009 +0200
@@ -10,8 +10,8 @@
from os.path import join
from cubicweb import CW_SOFTWARE_ROOT as BASE
-from cubicweb.vregistry import VObject
-from cubicweb.cwvreg import CubicWebRegistry, UnknownProperty
+from cubicweb.appobject import AppObject
+from cubicweb.cwvreg import CubicWebVRegistry, UnknownProperty
from cubicweb.devtools import TestServerConfiguration
from cubicweb.interfaces import IMileStone
@@ -27,7 +27,7 @@
def setUp(self):
config = TestServerConfiguration('data')
- self.vreg = CubicWebRegistry(config)
+ self.vreg = CubicWebVRegistry(config)
config.bootstrap_cubes()
self.vreg.schema = config.load_schema()
@@ -43,7 +43,7 @@
def test___selectors__compat(self):
myselector1 = lambda *args: 1
myselector2 = lambda *args: 1
- class AnAppObject(VObject):
+ class AnAppObject(AppObject):
__selectors__ = (myselector1, myselector2)
AnAppObject.build___select__()
self.assertEquals(AnAppObject.__select__(AnAppObject), 2)
@@ -53,7 +53,7 @@
self.failUnless(self.vreg.property_info('system.version.cubicweb'))
self.assertRaises(UnknownProperty, self.vreg.property_info, 'a.non.existent.key')
- def test_load_subinterface_based_vobjects(self):
+ def test_load_subinterface_based_appobjects(self):
self.vreg.reset()
self.vreg.register_objects([join(BASE, 'web', 'views', 'iprogress.py')])
# check progressbar was kicked
@@ -62,7 +62,7 @@
__implements__ = (IMileStone,)
self.vreg.reset()
self.vreg._loadedmods[__name__] = {}
- self.vreg.register_vobject_class(MyCard)
+ self.vreg.register_appobject_class(MyCard)
self.vreg.register_objects([join(BASE, 'entities', '__init__.py'),
join(BASE, 'web', 'views', 'iprogress.py')])
# check progressbar isn't kicked
--- a/utils.py Tue Aug 04 15:06:09 2009 +0200
+++ b/utils.py Tue Aug 04 15:08:18 2009 +0200
@@ -321,7 +321,7 @@
class AcceptMixIn(object):
- """Mixin class for vobjects defining the 'accepts' attribute describing
+ """Mixin class for appobjects defining the 'accepts' attribute describing
a set of supported entity type (Any by default).
"""
# XXX deprecated, no more necessary
--- a/view.py Tue Aug 04 15:06:09 2009 +0200
+++ b/view.py Tue Aug 04 15:08:18 2009 +0200
@@ -18,7 +18,7 @@
from cubicweb import NotAnEntity
from cubicweb.selectors import yes, non_final_entity, nonempty_rset, none_rset
from cubicweb.selectors import require_group_compat, accepts_compat
-from cubicweb.appobject import AppRsetObject
+from cubicweb.appobject import AppObject
from cubicweb.utils import UStringIO, HTMLStream
from cubicweb.schema import display_name
@@ -73,7 +73,7 @@
# base view object ############################################################
-class View(AppRsetObject):
+class View(AppObject):
"""abstract view class, used as base for every renderable object such
as views, templates, some components...web
@@ -93,7 +93,7 @@
time to a write function to use.
"""
__registry__ = 'views'
- registered = require_group_compat(AppRsetObject.registered)
+ registered = require_group_compat(AppObject.registered)
templatable = True
need_navigation = True
--- a/vregistry.py Tue Aug 04 15:06:09 2009 +0200
+++ b/vregistry.py Tue Aug 04 15:08:18 2009 +0200
@@ -5,13 +5,13 @@
according to a context
* to interact with the vregistry, objects should inherit from the
- VObject abstract class
+ AppObject abstract class
* the selection procedure has been generalized by delegating to a
- selector, which is responsible to score the vobject according to the
+ selector, which is responsible to score the appobject according to the
current state (req, rset, row, col). At the end of the selection, if
- a vobject class has been found, an instance of this class is
- returned. The selector is instantiated at vobject registration
+ a appobject class has been found, an instance of this class is
+ returned. The selector is instantiated at appobject registration
:organization: Logilab
@@ -22,15 +22,18 @@
__docformat__ = "restructuredtext en"
import sys
-import types
from os import listdir, stat
from os.path import dirname, join, realpath, split, isdir, exists
from logging import getLogger
from warnings import warn
-from cubicweb import CW_SOFTWARE_ROOT, set_log_methods
+from logilab.common.deprecation import deprecated, class_moved
+from logilab.common.logging_ext import set_log_methods
+
+from cubicweb import CW_SOFTWARE_ROOT
from cubicweb import (RegistryNotFound, ObjectNotFound, NoSelectableObject,
RegistryOutOfDate)
+from cubicweb.appobject import AppObject
# XXX depending on cubicweb.web is ugly, we should deal with uicfg
# reset with a good old event / callback system
@@ -58,179 +61,117 @@
return _toload
-class VObject(object):
- """visual object, use to be handled somehow by the visual components
- registry.
-
- The following attributes should be set on concret vobject subclasses:
-
- :__registry__:
- name of the registry for this object (string like 'views',
- 'templates'...)
- :id:
- object's identifier in the registry (string like 'main',
- 'primary', 'folder_box')
- :__select__:
- class'selector
-
- Moreover, the `__abstract__` attribute may be set to True to indicate
- that a vobject is abstract and should not be registered
- """
- # necessary attributes to interact with the registry
- id = None
- __registry__ = None
- __select__ = None
-
- @classmethod
- def registered(cls, registry):
- """called by the registry when the vobject has been registered.
-
- It must return the object that will be actually registered (this
- may be the right hook to create an instance for example). By
- default the vobject is returned without any transformation.
- """
- cls.build___select__()
- return cls
-
- @classmethod
- def selected(cls, *args, **kwargs):
- """called by the registry when the vobject has been selected.
-
- It must return the object that will be actually returned by the
- .select method (this may be the right hook to create an
- instance for example). By default the selected object is
- returned without any transformation.
- """
- return cls
-
- @classmethod
- def classid(cls):
- """returns a unique identifier for the vobject"""
- return '%s.%s' % (cls.__module__, cls.__name__)
+class Registry(dict):
- # XXX bw compat code
- @classmethod
- def build___select__(cls):
- for klass in cls.mro():
- if klass.__name__ == 'AppRsetObject':
- continue # the bw compat __selector__ is there
- klassdict = klass.__dict__
- if ('__select__' in klassdict and '__selectors__' in klassdict
- and '__selgenerated__' not in klassdict):
- raise TypeError("__select__ and __selectors__ can't be used together on class %s" % cls)
- if '__selectors__' in klassdict and '__selgenerated__' not in klassdict:
- cls.__selgenerated__ = True
- # case where __selectors__ is defined locally (but __select__
- # is in a parent class)
- selectors = klassdict['__selectors__']
- if len(selectors) == 1:
- # micro optimization: don't bother with AndSelector if there's
- # only one selector
- select = _instantiate_selector(selectors[0])
- else:
- select = AndSelector(*selectors)
- cls.__select__ = select
-
+ def __init__(self, config):
+ super(Registry, self).__init__()
+ self.config = config
-class VRegistry(object):
- """class responsible to register, propose and select the various
- elements used to build the web interface. Currently, we have templates,
- views, actions and components.
- """
-
- def __init__(self, config):#, cache_size=1000):
- self.config = config
- # dictionnary of registry (themself dictionnary) by name
- self._registries = {}
- self._lastmodifs = {}
-
- def reset(self):
- self._registries = {}
- self._lastmodifs = {}
- if uicfg is not None:
- reload(uicfg)
-
- def __getitem__(self, key):
- return self._registries[key]
-
- def get(self, key, default=None):
- return self._registries.get(key, default)
-
- def items(self):
- return self._registries.items()
-
- def values(self):
- return self._registries.values()
-
- def __contains__(self, key):
- return key in self._registries
-
- def registry(self, name):
+ def __getitem__(self, name):
"""return the registry (dictionary of class objects) associated to
this name
"""
try:
- return self._registries[name]
+ return super(Registry, self).__getitem__(name)
except KeyError:
- raise RegistryNotFound(name), None, sys.exc_info()[-1]
+ raise ObjectNotFound(name), None, sys.exc_info()[-1]
+
+ def register(self, obj, oid=None, clear=False):
+ """base method to add an object in the registry"""
+ assert not '__abstract__' in obj.__dict__
+ oid = oid or obj.id
+ assert oid
+ if clear:
+ appobjects = self[oid] = []
+ else:
+ appobjects = self.setdefault(oid, [])
+ # registered() is technically a classmethod but is not declared
+ # as such because we need to compose registered in some cases
+ appobject = obj.registered.im_func(obj, self)
+ assert not appobject in appobjects, \
+ 'object %s is already registered' % appobject
+ assert callable(appobject.__select__), appobject
+ appobjects.append(appobject)
- def registry_objects(self, name, oid=None):
- """returns objects registered with the given oid in the given registry.
- If no oid is given, return all objects in this registry
+ def register_and_replace(self, obj, replaced):
+ # XXXFIXME this is a duplication of unregister()
+ # remove register_and_replace in favor of unregister + register
+ # or simplify by calling unregister then register here
+ if hasattr(replaced, 'classid'):
+ replaced = replaced.classid()
+ registered_objs = self.get(obj.id, ())
+ for index, registered in enumerate(registered_objs):
+ if registered.classid() == replaced:
+ del registered_objs[index]
+ break
+ else:
+ self.warning('trying to replace an unregistered view %s by %s',
+ replaced, obj)
+ self.register(obj)
+
+ def unregister(self, obj):
+ oid = obj.classid()
+ for registered in self.get(obj.id, ()):
+ # use classid() to compare classes because vreg will probably
+ # have its own version of the class, loaded through execfile
+ if registered.classid() == oid:
+ # XXX automatic reloading management
+ self[obj.id].remove(registered)
+ break
+ else:
+ self.warning('can\'t remove %s, no id %s in the registry',
+ oid, obj.id)
+
+ def all_objects(self):
+ """return a list containing all objects in this registry.
"""
- registry = self.registry(name)
- if oid is not None:
- try:
- return registry[oid]
- except KeyError:
- raise ObjectNotFound(oid), None, sys.exc_info()[-1]
result = []
- for objs in registry.values():
+ for objs in self.values():
result += objs
return result
# dynamic selection methods ################################################
- def object_by_id(self, registry, oid, *args, **kwargs):
- """return object in <registry>.<oid>
+ def object_by_id(self, oid, *args, **kwargs):
+ """return object with the given oid. Only one object is expected to be
+ found.
raise `ObjectNotFound` if not object with id <oid> in <registry>
raise `AssertionError` if there is more than one object there
"""
- objects = self.registry_objects(registry, oid)
+ objects = self[oid]
assert len(objects) == 1, objects
- return objects[0].selected(*args, **kwargs)
+ return objects[0](*args, **kwargs)
- def select(self, registry, oid, *args, **kwargs):
- """return the most specific object in <registry>.<oid> according to
- the given context
+ def select(self, oid, *args, **kwargs):
+ """return the most specific object among those with the given oid
+ according to the given context.
raise `ObjectNotFound` if not object with id <oid> in <registry>
raise `NoSelectableObject` if not object apply
"""
- return self.select_best(self.registry_objects(registry, oid),
- *args, **kwargs)
+ return self.select_best(self[oid], *args, **kwargs)
- def select_object(self, registry, oid, *args, **kwargs):
- """return the most specific object in <registry>.<oid> according to
- the given context, or None if no object apply
+ def select_object(self, oid, *args, **kwargs):
+ """return the most specific object among those with the given oid
+ according to the given context, or None if no object applies.
"""
try:
- return self.select(registry, oid, *args, **kwargs)
+ return self.select(oid, *args, **kwargs)
except (NoSelectableObject, ObjectNotFound):
return None
- def possible_objects(self, registry, *args, **kwargs):
- """return an iterator on possible objects in <registry> for the given
+ def possible_objects(self, *args, **kwargs):
+ """return an iterator on possible objects in this registry for the given
context
"""
- for vobjects in self.registry(registry).itervalues():
+ for appobjects in self.itervalues():
try:
- yield self.select_best(vobjects, *args, **kwargs)
+ yield self.select_best(appobjects, *args, **kwargs)
except NoSelectableObject:
continue
- def select_best(self, vobjects, *args, **kwargs):
+ def select_best(self, appobjects, *args, **kwargs):
"""return an instance of the most specific object according
to parameters
@@ -240,16 +181,16 @@
warn('only the request param can not be named when calling select',
DeprecationWarning, stacklevel=3)
score, winners = 0, []
- for vobject in vobjects:
- vobjectscore = vobject.__select__(vobject, *args, **kwargs)
- if vobjectscore > score:
- score, winners = vobjectscore, [vobject]
- elif vobjectscore > 0 and vobjectscore == score:
- winners.append(vobject)
+ for appobject in appobjects:
+ appobjectscore = appobject.__select__(appobject, *args, **kwargs)
+ if appobjectscore > score:
+ score, winners = appobjectscore, [appobject]
+ elif appobjectscore > 0 and appobjectscore == score:
+ winners.append(appobject)
if not winners:
raise NoSelectableObject('args: %s\nkwargs: %s %s'
% (args, kwargs.keys(),
- [repr(v) for v in vobjects]))
+ [repr(v) for v in appobjects]))
if len(winners) > 1:
if self.config.mode == 'installed':
self.error('select ambiguity, args: %s\nkwargs: %s %s',
@@ -258,11 +199,92 @@
raise Exception('select ambiguity, args: %s\nkwargs: %s %s'
% (args, kwargs.keys(),
[repr(v) for v in winners]))
- # return the result of the .selected method of the vobject
- return winners[0].selected(*args, **kwargs)
+ # return the result of calling the appobject
+ return winners[0](*args, **kwargs)
+
+
+class VRegistry(dict):
+ """class responsible to register, propose and select the various
+ elements used to build the web interface. Currently, we have templates,
+ views, actions and components.
+ """
+
+ def __init__(self, config):
+ super(VRegistry, self).__init__()
+ self.config = config
+
+ def reset(self, force_reload=None):
+ self.clear()
+ self._lastmodifs = {}
+ # don't reload uicfg when appobjects modules won't be reloaded as well
+ if uicfg is not None:
+ if force_reload is None:
+ force_reload = self.config.mode == 'dev'
+ if force_reload:
+ reload(uicfg)
+
+ def __getitem__(self, name):
+ """return the registry (dictionary of class objects) associated to
+ this name
+ """
+ try:
+ return super(VRegistry, self).__getitem__(name)
+ except KeyError:
+ raise RegistryNotFound(name), None, sys.exc_info()[-1]
+
+ # dynamic selection methods ################################################
+
+ @deprecated('use vreg[registry].object_by_id(oid, *args, **kwargs)')
+ def object_by_id(self, registry, oid, *args, **kwargs):
+ """return object in <registry>.<oid>
+
+ raise `ObjectNotFound` if not object with id <oid> in <registry>
+ raise `AssertionError` if there is more than one object there
+ """
+ return self[registry].object_by_id(oid)
+
+ @deprecated('use vreg[registry].select(oid, *args, **kwargs)')
+ def select(self, registry, oid, *args, **kwargs):
+ """return the most specific object in <registry>.<oid> according to
+ the given context
+
+ raise `ObjectNotFound` if not object with id <oid> in <registry>
+ raise `NoSelectableObject` if not object apply
+ """
+ return self[registry].select(oid, *args, **kwargs)
+
+ @deprecated('use vreg[registry].select_object(oid, *args, **kwargs)')
+ def select_object(self, registry, oid, *args, **kwargs):
+ """return the most specific object in <registry>.<oid> according to
+ the given context, or None if no object apply
+ """
+ return self[registry].select_object(oid, *args, **kwargs)
+
+ @deprecated('use vreg[registry].possible_objects(*args, **kwargs)')
+ def possible_objects(self, registry, *args, **kwargs):
+ """return an iterator on possible objects in <registry> for the given
+ context
+ """
+ return self[registry].possible_objects(*args, **kwargs)
# methods for explicit (un)registration ###################################
+ # default class, when no specific class set
+ REGISTRY_FACTORY = {None: Registry}
+
+ def registry_class(self, regid):
+ try:
+ return self.REGISTRY_FACTORY[regid]
+ except KeyError:
+ return self.REGISTRY_FACTORY[None]
+
+ def setdefault(self, regid):
+ try:
+ return self[regid]
+ except KeyError:
+ self[regid] = self.registry_class(regid)(self.config)
+ return self[regid]
+
# def clear(self, key):
# regname, oid = key.split('.')
# self[regname].pop(oid, None)
@@ -282,62 +304,23 @@
"""base method to add an object in the registry"""
assert not '__abstract__' in obj.__dict__
registryname = registryname or obj.__registry__
- oid = oid or obj.id
- assert oid
- registry = self._registries.setdefault(registryname, {})
- if clear:
- vobjects = registry[oid] = []
- else:
- vobjects = registry.setdefault(oid, [])
- # registered() is technically a classmethod but is not declared
- # as such because we need to compose registered in some cases
- vobject = obj.registered.im_func(obj, self)
- assert not vobject in vobjects, \
- 'object %s is already registered' % vobject
- assert callable(vobject.__select__), vobject
- vobjects.append(vobject)
+ registry = self.setdefault(registryname)
+ registry.register(obj, oid=oid, clear=clear)
try:
- vname = vobject.__name__
+ vname = obj.__name__
except AttributeError:
- vname = vobject.__class__.__name__
- self.debug('registered vobject %s in registry %s with id %s',
+ vname = obj.__class__.__name__
+ self.debug('registered appobject %s in registry %s with id %s',
vname, registryname, oid)
self._loadedmods[obj.__module__]['%s.%s' % (obj.__module__, oid)] = obj
def unregister(self, obj, registryname=None):
- registryname = registryname or obj.__registry__
- registry = self.registry(registryname)
- removed_id = obj.classid()
- for registered in registry.get(obj.id, ()):
- # use classid() to compare classes because vreg will probably
- # have its own version of the class, loaded through execfile
- if registered.classid() == removed_id:
- # XXX automatic reloading management
- registry[obj.id].remove(registered)
- break
- else:
- self.warning('can\'t remove %s, no id %s in the %s registry',
- removed_id, obj.id, registryname)
+ self[registryname or obj.__registry__].unregister(obj)
def register_and_replace(self, obj, replaced, registryname=None):
- # XXXFIXME this is a duplication of unregister()
- # remove register_and_replace in favor of unregister + register
- # or simplify by calling unregister then register here
- if hasattr(replaced, 'classid'):
- replaced = replaced.classid()
- registryname = registryname or obj.__registry__
- registry = self.registry(registryname)
- registered_objs = registry.get(obj.id, ())
- for index, registered in enumerate(registered_objs):
- if registered.classid() == replaced:
- del registry[obj.id][index]
- break
- else:
- self.warning('trying to replace an unregistered view %s by %s',
- replaced, obj)
- self.register(obj, registryname=registryname)
+ self[registryname or obj.__registry__].register_and_replace(obj, replaced)
- # intialization methods ###################################################
+ # initialization methods ###################################################
def init_registration(self, path, extrapath=None):
# compute list of all modules that have to be loaded
@@ -421,7 +404,7 @@
return
# skip non registerable object
try:
- if not issubclass(obj, VObject):
+ if not issubclass(obj, AppObject):
return
except TypeError:
return
@@ -435,20 +418,20 @@
def load_object(self, obj):
try:
- self.register_vobject_class(obj)
+ self.register_appobject_class(obj)
except Exception, ex:
if self.config.mode in ('test', 'dev'):
raise
- self.exception('vobject %s registration failed: %s', obj, ex)
+ self.exception('appobject %s registration failed: %s', obj, ex)
# old automatic registration XXX deprecated ###############################
- def register_vobject_class(self, cls):
- """handle vobject class registration
+ def register_appobject_class(self, cls):
+ """handle appobject class registration
- vobject class with __abstract__ == True in their local dictionnary or
+ appobject class with __abstract__ == True in their local dictionnary or
with a name starting starting by an underscore are not registered.
- Also a vobject class needs to have __registry__ and id attributes set
+ Also a appobject class needs to have __registry__ and id attributes set
to a non empty string to be registered.
"""
if (cls.__dict__.get('__abstract__') or cls.__name__[0] == '_'
@@ -460,169 +443,19 @@
self.register(cls)
# init logging
-set_log_methods(VObject, getLogger('cubicweb'))
-set_log_methods(VRegistry, getLogger('cubicweb.registry'))
-
-
-# selector base classes and operations ########################################
-
-class Selector(object):
- """base class for selector classes providing implementation
- for operators ``&`` and ``|``
-
- This class is only here to give access to binary operators, the
- selector logic itself should be implemented in the __call__ method
-
-
- a selector is called to help choosing the correct object for a
- particular context by returning a score (`int`) telling how well
- the class given as first argument apply to the given context.
-
- 0 score means that the class doesn't apply.
- """
-
- @property
- def func_name(self):
- # backward compatibility
- return self.__class__.__name__
-
- def search_selector(self, selector):
- """search for the given selector or selector instance in the selectors
- tree. Return it of None if not found
- """
- if self is selector:
- return self
- if isinstance(selector, type) and isinstance(self, selector):
- return self
- return None
-
- def __str__(self):
- return self.__class__.__name__
-
- def __and__(self, other):
- return AndSelector(self, other)
- def __rand__(self, other):
- return AndSelector(other, self)
-
- def __or__(self, other):
- return OrSelector(self, other)
- def __ror__(self, other):
- return OrSelector(other, self)
-
- def __invert__(self):
- return NotSelector(self)
-
- # XXX (function | function) or (function & function) not managed yet
-
- def __call__(self, cls, *args, **kwargs):
- return NotImplementedError("selector %s must implement its logic "
- "in its __call__ method" % self.__class__)
-
-class MultiSelector(Selector):
- """base class for compound selector classes"""
-
- def __init__(self, *selectors):
- self.selectors = self.merge_selectors(selectors)
-
- def __str__(self):
- return '%s(%s)' % (self.__class__.__name__,
- ','.join(str(s) for s in self.selectors))
-
- @classmethod
- def merge_selectors(cls, selectors):
- """deal with selector instanciation when necessary and merge
- multi-selectors if possible:
-
- AndSelector(AndSelector(sel1, sel2), AndSelector(sel3, sel4))
- ==> AndSelector(sel1, sel2, sel3, sel4)
- """
- merged_selectors = []
- for selector in selectors:
- try:
- selector = _instantiate_selector(selector)
- except:
- pass
- #assert isinstance(selector, Selector), selector
- if isinstance(selector, cls):
- merged_selectors += selector.selectors
- else:
- merged_selectors.append(selector)
- return merged_selectors
-
- def search_selector(self, selector):
- """search for the given selector or selector instance in the selectors
- tree. Return it of None if not found
- """
- for childselector in self.selectors:
- if childselector is selector:
- return childselector
- found = childselector.search_selector(selector)
- if found is not None:
- return found
- return None
-
-
-def objectify_selector(selector_func):
- """convenience decorator for simple selectors where a class definition
- would be overkill::
-
- @objectify_selector
- def yes(cls, *args, **kwargs):
- return 1
-
- """
- return type(selector_func.__name__, (Selector,),
- {'__call__': lambda self, *args, **kwargs: selector_func(*args, **kwargs)})
-
-def _instantiate_selector(selector):
- """ensures `selector` is a `Selector` instance
-
- NOTE: This should only be used locally in build___select__()
- XXX: then, why not do it ??
- """
- if isinstance(selector, types.FunctionType):
- return objectify_selector(selector)()
- if isinstance(selector, type) and issubclass(selector, Selector):
- return selector()
- return selector
-
-
-class AndSelector(MultiSelector):
- """and-chained selectors (formerly known as chainall)"""
- def __call__(self, cls, *args, **kwargs):
- score = 0
- for selector in self.selectors:
- partscore = selector(cls, *args, **kwargs)
- if not partscore:
- return 0
- score += partscore
- return score
-
-
-class OrSelector(MultiSelector):
- """or-chained selectors (formerly known as chainfirst)"""
- def __call__(self, cls, *args, **kwargs):
- for selector in self.selectors:
- partscore = selector(cls, *args, **kwargs)
- if partscore:
- return partscore
- return 0
-
-class NotSelector(Selector):
- """negation selector"""
- def __init__(self, selector):
- self.selector = selector
-
- def __call__(self, cls, *args, **kwargs):
- score = self.selector(cls, *args, **kwargs)
- return int(not score)
-
- def __str__(self):
- return 'NOT(%s)' % super(NotSelector, self).__str__()
+set_log_methods(VRegistry, getLogger('cubicweb.vreg'))
+set_log_methods(Registry, getLogger('cubicweb.registry'))
# XXX bw compat functions #####################################################
+from cubicweb.appobject import objectify_selector, AndSelector, OrSelector, Selector
+
+objectify_selector = deprecated('objectify_selector has been moved to appobject module')(objectify_selector)
+
+Selector = class_moved(Selector)
+
+@deprecated('use & operator (binary and)')
def chainall(*selectors, **kwargs):
"""return a selector chaining given selectors. If one of
the selectors fail, selection will fail, else the returned score
@@ -635,6 +468,7 @@
selector.__name__ = kwargs['name']
return selector
+@deprecated('use | operator (binary or)')
def chainfirst(*selectors, **kwargs):
"""return a selector chaining given selectors. If all
the selectors fail, selection will fail, else the returned score
--- a/web/action.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/action.py Tue Aug 04 15:08:18 2009 +0200
@@ -11,12 +11,12 @@
from cubicweb.selectors import (partial_relation_possible, match_search_state,
one_line_rset, partial_may_add_relation, yes,
accepts_compat, condition_compat, deprecate)
-from cubicweb.appobject import AppRsetObject
+from cubicweb.appobject import AppObject
_ = unicode
-class Action(AppRsetObject):
+class Action(AppObject):
"""abstract action. Handle the .search_states attribute to match
request search state.
"""
--- a/web/application.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/application.py Tue Aug 04 15:08:18 2009 +0200
@@ -41,7 +41,7 @@
if self.session_time:
assert self.cleanup_session_time < self.session_time
assert self.cleanup_anon_session_time < self.session_time
- self.authmanager = self.vreg.select('components', 'authmanager')
+ self.authmanager = self.vreg['components'].select('authmanager')
def clean_sessions(self):
"""cleanup sessions which has not been unused since a given amount of
@@ -112,7 +112,7 @@
SESSION_VAR = '__session'
def __init__(self, appli):
- self.session_manager = appli.vreg.select('components', 'sessionmanager')
+ self.session_manager = appli.vreg['components'].select('sessionmanager')
global SESSION_MANAGER
SESSION_MANAGER = self.session_manager
if not 'last_login_time' in appli.vreg.schema:
@@ -220,7 +220,7 @@
super(CubicWebPublisher, self).__init__()
# connect to the repository and get instance's schema
if vreg is None:
- vreg = cwvreg.CubicWebRegistry(config, debug=debug)
+ vreg = cwvreg.CubicWebVRegistry(config, debug=debug)
self.vreg = vreg
self.info('starting web instance from %s', config.apphome)
self.repo = config.repository(vreg)
@@ -239,7 +239,7 @@
self.publish = self.main_publish
# instantiate session and url resolving helpers
self.session_handler = session_handler_fact(self)
- self.url_resolver = vreg.select('components', 'urlpublisher')
+ self.url_resolver = vreg['components'].select('urlpublisher')
def connect(self, req):
"""return a connection for a logged user object according to existing
@@ -275,7 +275,7 @@
@deprecated("use vreg.select('controllers', ...)")
def select_controller(self, oid, req):
try:
- return self.vreg.select('controllers', oid, req=req, appli=self)
+ return self.vreg['controllers'].select(oid, req=req, appli=self)
except NoSelectableObject:
raise Unauthorized(req._('not authorized'))
@@ -304,8 +304,8 @@
try:
ctrlid, rset = self.url_resolver.process(req, path)
try:
- controller = self.vreg.select('controllers', ctrlid, req,
- appli=self)
+ controller = self.vreg['controllers'].select(ctrlid, req,
+ appli=self)
except NoSelectableObject:
raise Unauthorized(req._('not authorized'))
req.update_search_state()
@@ -375,28 +375,28 @@
if tb:
req.data['excinfo'] = excinfo
req.form['vid'] = 'error'
- errview = self.vreg.select('views', 'error', req)
+ errview = self.vreg['views'].select('error', req)
template = self.main_template_id(req)
- content = self.vreg.main_template(req, template, view=errview)
+ content = self.vreg['views'].main_template(req, template, view=errview)
except:
- content = self.vreg.main_template(req, 'error-template')
+ content = self.vreg['views'].main_template(req, 'error-template')
raise StatusResponse(500, content)
def need_login_content(self, req):
- return self.vreg.main_template(req, 'login')
+ return self.vreg['views'].main_template(req, 'login')
def loggedout_content(self, req):
- return self.vreg.main_template(req, 'loggedout')
+ return self.vreg['views'].main_template(req, 'loggedout')
def notfound_content(self, req):
req.form['vid'] = '404'
- view = self.vreg.select('views', '404', req)
+ view = self.vreg['views'].select('404', req)
template = self.main_template_id(req)
- return self.vreg.main_template(req, template, view=view)
+ return self.vreg['views'].main_template(req, template, view=view)
def main_template_id(self, req):
template = req.form.get('__template', req.property_value('ui.main-template'))
- if template not in self.vreg.registry('views'):
+ if template not in self.vreg['views']:
template = 'main-template'
return template
--- a/web/controller.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/controller.py Tue Aug 04 15:08:18 2009 +0200
@@ -71,6 +71,7 @@
registered = require_group_compat(AppObject.registered)
def __init__(self, *args, **kwargs):
+ self.appli = kwargs.pop('appli', None)
super(Controller, self).__init__(*args, **kwargs)
# attributes use to control after edition redirection
self._after_deletion_path = None
@@ -92,7 +93,7 @@
self.ensure_ro_rql(rql)
if not isinstance(rql, unicode):
rql = unicode(rql, self.req.encoding)
- pp = self.vreg.select_object('components', 'magicsearch', self.req)
+ pp = self.vreg['components'].select_object('magicsearch', self.req)
if pp is not None:
self.rset = pp.process_query(rql, self.req)
return self.rset
--- a/web/facet.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/facet.py Tue Aug 04 15:08:18 2009 +0200
@@ -24,7 +24,7 @@
from cubicweb.schema import display_name
from cubicweb.utils import datetime2ticks, make_uid, ustrftime
from cubicweb.selectors import match_context_prop, partial_relation_possible
-from cubicweb.appobject import AppRsetObject
+from cubicweb.appobject import AppObject
from cubicweb.web.htmlwidgets import HTMLWidget
## rqlst manipulation functions used by facets ################################
@@ -64,8 +64,8 @@
def get_facet(req, facetid, rqlst, mainvar):
- return req.vreg.object_by_id('facets', facetid, req, rqlst=rqlst,
- filtered_variable=mainvar)
+ return req.vreg['facets'].object_by_id(facetid, req, rqlst=rqlst,
+ filtered_variable=mainvar)
def filter_hiddens(w, **kwargs):
@@ -241,7 +241,7 @@
## base facet classes #########################################################
-class AbstractFacet(AppRsetObject):
+class AbstractFacet(AppObject):
__abstract__ = True
__registry__ = 'facets'
property_defs = {
@@ -259,22 +259,18 @@
needs_update = False
start_unfolded = True
- @classmethod
- def selected(cls, req, rset=None, rqlst=None, context=None,
- filtered_variable=None):
+ def __init__(self, req, rset=None, rqlst=None, filtered_variable=None,
+ **kwargs):
+ super(AbstractFacet, self).__init__(req, rset, **kwargs)
assert rset is not None or rqlst is not None
assert filtered_variable
- instance = super(AbstractFacet, cls).selected(req, rset)
- #instance = AppRsetObject.selected(req, rset)
- #instance.__class__ = cls
# facet retreived using `object_by_id` from an ajax call
if rset is None:
- instance.init_from_form(rqlst=rqlst)
+ self.init_from_form(rqlst=rqlst)
# facet retreived from `select` using the result set to filter
else:
- instance.init_from_rset()
- instance.filtered_variable = filtered_variable
- return instance
+ self.init_from_rset()
+ self.filtered_variable = filtered_variable
def init_from_rset(self):
self.rqlst = self.rset.syntax_tree().children[0]
--- a/web/form.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/form.py Tue Aug 04 15:08:18 2009 +0200
@@ -7,7 +7,7 @@
"""
__docformat__ = "restructuredtext en"
-from cubicweb.appobject import AppRsetObject
+from cubicweb.appobject import AppObject
from cubicweb.view import NOINDEX, NOFOLLOW
from cubicweb.common import tags
from cubicweb.web import stdmsgs, httpcache, formfields
@@ -202,6 +202,6 @@
found
"""
-class Form(FormMixIn, AppRsetObject):
+class Form(FormMixIn, AppObject):
__metaclass__ = metafieldsform
__registry__ = 'forms'
--- a/web/request.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/request.py Tue Aug 04 15:08:18 2009 +0200
@@ -539,8 +539,7 @@
def from_controller(self):
"""return the id (string) of the controller issuing the request"""
controller = self.relative_path(False).split('/', 1)[0]
- registered_controllers = (ctrl.id for ctrl in
- self.vreg.registry_objects('controllers'))
+ registered_controllers = self.vreg['controllers'].keys()
if controller in registered_controllers:
return controller
return 'view'
--- a/web/test/test_views.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/test_views.py Tue Aug 04 15:08:18 2009 +0200
@@ -52,7 +52,7 @@
def test_js_added_only_once(self):
self.vreg._loadedmods[__name__] = {}
- self.vreg.register_vobject_class(SomeView)
+ self.vreg.register_appobject_class(SomeView)
rset = self.execute('CWUser X')
source = self.view('someview', rset).source
self.assertEquals(source.count('spam.js'), 1)
--- a/web/test/unittest_application.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_application.py Tue Aug 04 15:08:18 2009 +0200
@@ -7,16 +7,17 @@
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
-from logilab.common.testlib import TestCase, unittest_main
import base64, Cookie
-
import sys
from urllib import unquote
+
+from logilab.common.testlib import TestCase, unittest_main
from logilab.common.decorators import clear_cache
+from cubicweb.devtools.apptest import EnvBasedTC
+from cubicweb.devtools.fake import FakeRequest
from cubicweb.web import Redirect, AuthenticationError, ExplicitLogin, INTERNAL_FIELD_VALUE
from cubicweb.web.views.basecontrollers import ViewController
-from cubicweb.devtools._apptest import FakeRequest
class FakeMapping:
"""emulates a mapping module"""
@@ -133,9 +134,6 @@
for i in (12, 13, 14)])
-from cubicweb.devtools.apptest import EnvBasedTC
-
-
class ApplicationTC(EnvBasedTC):
def publish(self, req, path='view'):
--- a/web/test/unittest_form.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_form.py Tue Aug 04 15:08:18 2009 +0200
@@ -91,7 +91,7 @@
e.req = self.req
geid = self.execute('CWGroup X WHERE X name "users"')[0][0]
self.req.form['__linkto'] = 'in_group:%s:subject' % geid
- form = self.vreg.select('forms', 'edition', self.req, entity=e)
+ form = self.vreg['forms'].select('edition', self.req, entity=e)
form.content_type = 'text/html'
pageinfo = self._check_html(form.form_render(), form, template=None)
inputs = pageinfo.find_tag('select', False)
@@ -101,8 +101,8 @@
def test_reledit_composite_field(self):
rset = self.execute('INSERT BlogEntry X: X title "cubicweb.org", X content "hop"')
- form = self.vreg.select_object('views', 'reledit', self.request(),
- rset=rset, row=0, rtype='content')
+ form = self.vreg['views'].select('reledit', self.request(),
+ rset=rset, row=0, rtype='content')
data = form.render(row=0, rtype='content')
self.failUnless('edits-content' in data)
self.failUnless('edits-content_format' in data)
--- a/web/test/unittest_magicsearch.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_magicsearch.py Tue Aug 04 15:08:18 2009 +0200
@@ -44,7 +44,7 @@
super(QueryTranslatorTC, self).setUp()
self.req = self.env.create_request()
self.vreg.config.translations = {'en': _translate}
- proc = self.vreg.select('components', 'magicsearch', self.req)
+ proc = self.vreg['components'].select('magicsearch', self.req)
self.proc = [p for p in proc.processors if isinstance(p, QueryTranslator)][0]
def test_basic_translations(self):
@@ -69,7 +69,7 @@
super(QSPreProcessorTC, self).setUp()
self.vreg.config.translations = {'en': _translate}
self.req = self.request()
- proc = self.vreg.select('components', 'magicsearch', self.req)
+ proc = self.vreg['components'].select('magicsearch', self.req)
self.proc = [p for p in proc.processors if isinstance(p, QSPreProcessor)][0]
self.proc.req = self.req
@@ -187,7 +187,7 @@
super(ProcessorChainTC, self).setUp()
self.vreg.config.translations = {'en': _translate}
self.req = self.request()
- self.proc = self.vreg.select('components', 'magicsearch', self.req)
+ self.proc = self.vreg['components'].select('magicsearch', self.req)
def test_main_preprocessor_chain(self):
"""tests QUERY_PROCESSOR"""
--- a/web/test/unittest_views_actions.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_views_actions.py Tue Aug 04 15:08:18 2009 +0200
@@ -13,19 +13,19 @@
def test_view_action(self):
req = self.request(__message='bla bla bla', vid='rss', rql='CWUser X')
rset = self.execute('CWUser X')
- vaction = [action for action in self.vreg.possible_vobjects('actions', req, rset=rset)
+ vaction = [action for action in self.vreg['actions'].possible_vobjects(req, rset=rset)
if action.id == 'view'][0]
self.assertEquals(vaction.url(), 'http://testing.fr/cubicweb/view?rql=CWUser%20X')
def test_sendmail_action(self):
req = self.request()
rset = self.execute('Any X WHERE X login "admin"', req=req)
- self.failUnless([action for action in self.vreg.possible_vobjects('actions', req, rset=rset)
+ self.failUnless([action for action in self.vreg['actions'].possible_vobjects(req, rset=rset)
if action.id == 'sendemail'])
self.login('anon')
req = self.request()
rset = self.execute('Any X WHERE X login "anon"', req=req)
- self.failIf([action for action in self.vreg.possible_vobjects('actions', req, rset=rset)
+ self.failIf([action for action in self.vreg['actions'].possible_vobjects(req, rset=rset)
if action.id == 'sendemail'])
if __name__ == '__main__':
--- a/web/test/unittest_views_basecontrollers.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_views_basecontrollers.py Tue Aug 04 15:08:18 2009 +0200
@@ -496,7 +496,7 @@
# updated (which is what happened before this test)
req = self.request()
req.form['url'] = 'http://intranet.logilab.fr/'
- controller = self.vreg.select('controllers', 'embed', req)
+ controller = self.vreg['controllers'].select('embed', req)
result = controller.publish(rset=None)
@@ -504,7 +504,7 @@
def test_usable_by_guets(self):
req = self.request()
- self.vreg.select('controllers', 'reportbug', req)
+ self.vreg['controllers'].select('reportbug', req)
class SendMailControllerTC(EnvBasedTC):
@@ -512,7 +512,7 @@
def test_not_usable_by_guets(self):
self.login('anon')
req = self.request()
- self.assertRaises(NoSelectableObject, self.env.vreg.select, 'controllers', 'sendmail', req)
+ self.assertRaises(NoSelectableObject, self.env.vreg['controllers'].select, 'sendmail', req)
@@ -520,7 +520,7 @@
def ctrl(self, req=None):
req = req or self.request(url='http://whatever.fr/')
- return self.vreg.select('controllers', 'json', req)
+ return self.vreg['controllers'].select('json', req)
def setup_database(self):
self.pytag = self.add_entity('Tag', name=u'python')
--- a/web/test/unittest_views_basetemplates.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_views_basetemplates.py Tue Aug 04 15:08:18 2009 +0200
@@ -13,7 +13,7 @@
def _login_labels(self):
valid = self.content_type_validators.get('text/html', DTDValidator)()
- page = valid.parse_string(self.vreg.main_template(self.request(), 'login'))
+ page = valid.parse_string(self.vreg['views'].main_template(self.request(), 'login'))
return page.find_tag('label')
def test_label(self):
--- a/web/test/unittest_views_baseviews.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_views_baseviews.py Tue Aug 04 15:08:18 2009 +0200
@@ -91,7 +91,7 @@
rset = self.execute('Any X, D, CD, NOW - CD WHERE X is State, X description D, X creation_date CD, X eid %(x)s',
{'x': e.eid}, 'x')
req = self.request()
- view = self.vreg.select('views', 'table', req, rset=rset)
+ view = self.vreg['views'].select('table', req, rset=rset)
return e, rset, view
def test_headers(self):
--- a/web/test/unittest_views_editforms.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_views_editforms.py Tue Aug 04 15:08:18 2009 +0200
@@ -18,8 +18,8 @@
def test_custom_widget(self):
AEF.rfields_kwargs.tag_subject_of(('CWUser', 'login', '*'),
{'widget': AutoCompletionWidget(autocomplete_initfunc='get_logins')})
- form = self.vreg.select('forms', 'edition', self.request(),
- entity=self.user())
+ form = self.vreg['forms'].select('edition', self.request(),
+ entity=self.user())
field = form.field_by_name('login')
self.assertIsInstance(field.widget, AutoCompletionWidget)
AEF.rfields_kwargs.del_rtag('CWUser', 'login', '*', 'subject')
@@ -116,10 +116,10 @@
def test_edition_form(self):
rset = self.execute('CWUser X LIMIT 1')
- form = self.vreg.select('forms', 'edition', rset.req, rset=rset,
+ form = self.vreg['forms'].select('edition', rset.req, rset=rset,
row=0, col=0)
# should be also selectable by specifying entity
- self.vreg.select('forms', 'edition', rset.req,
+ self.vreg['forms'].select('edition', rset.req,
entity=rset.get_entity(0, 0))
self.failIf(any(f for f in form.fields if f is None))
--- a/web/test/unittest_views_navigation.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_views_navigation.py Tue Aug 04 15:08:18 2009 +0200
@@ -19,31 +19,31 @@
def test_navigation_selection(self):
rset = self.execute('Any X,N WHERE X name N')
req = self.request()
- navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
self.assertIsInstance(navcomp, PageNavigation)
req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
self.assertIsInstance(navcomp, PageNavigation)
req.set_search_state('normal')
rset = self.execute('Any X,N ORDERBY N WHERE X name N')
- navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
self.assertIsInstance(navcomp, SortedNavigation)
req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
self.assertIsInstance(navcomp, SortedNavigation)
req.set_search_state('normal')
rset = self.execute('Any X,N LIMIT 10 WHERE X name N')
- navcomp = self.vreg.select_object('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select_object('navigation', req, rset=rset)
self.assertEquals(navcomp, None)
req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg.select_object('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select_object('navigation', req, rset=rset)
self.assertEquals(navcomp, None)
req.set_search_state('normal')
rset = self.execute('Any N, COUNT(RDEF) GROUPBY N ORDERBY N WHERE RDEF relation_type RT, RT name N')
- navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
self.assertIsInstance(navcomp, SortedNavigation)
req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
self.assertIsInstance(navcomp, SortedNavigation)
@@ -51,22 +51,22 @@
rset = self.execute('Any X,N ORDERBY N WHERE X name N')
req = self.request()
req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg.select('components', 'navigation', rset.req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', rset.req, rset=rset)
html = navcomp.render()
rset = self.execute('Any RDEF ORDERBY RT WHERE RDEF relation_type RT')
- navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
html = navcomp.render()
rset = self.execute('Any RDEF ORDERBY RDEF WHERE RDEF relation_type RT')
- navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
html = navcomp.render()
rset = self.execute('CWAttribute RDEF ORDERBY RDEF')
- navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
html = navcomp.render()
rset = self.execute('Any RDEF ORDERBY N WHERE RDEF relation_type RT, RT name N')
- navcomp = self.vreg.select('components', 'navigation', req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
html = navcomp.render()
rset = self.execute('Any N, COUNT(RDEF) GROUPBY N ORDERBY N WHERE RDEF relation_type RT, RT name N')
- navcomp = self.vreg.select('components', 'navigation', rset.req, rset=rset)
+ navcomp = self.vreg['components'].select('navigation', rset.req, rset=rset)
html = navcomp.render()
@@ -77,12 +77,12 @@
view = mock_object(is_primary=lambda x: True)
rset = self.execute('CWUser X LIMIT 1')
req = self.request()
- objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset,
+ objs = self.vreg['contentnavigation'].possible_vobjects(req, rset=rset,
view=view, context='navtop')
# breadcrumbs should be in headers by default
clsids = set(obj.id for obj in objs)
self.failUnless('breadcrumbs' in clsids)
- objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset,
+ objs = self.vreg['contentnavigation'].possible_vobjects(req, rset=rset,
view=view, context='navbottom')
# breadcrumbs should _NOT_ be in footers by default
clsids = set(obj.id for obj in objs)
@@ -91,12 +91,12 @@
'P value "navbottom"')
# breadcrumbs should now be in footers
req.cnx.commit()
- objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset,
+ objs = self.vreg['contentnavigation'].possible_vobjects(req, rset=rset,
view=view, context='navbottom')
clsids = [obj.id for obj in objs]
self.failUnless('breadcrumbs' in clsids)
- objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset,
+ objs = self.vreg['contentnavigation'].possible_vobjects(req, rset=rset,
view=view, context='navtop')
clsids = [obj.id for obj in objs]
--- a/web/test/unittest_views_pyviews.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_views_pyviews.py Tue Aug 04 15:08:18 2009 +0200
@@ -4,9 +4,9 @@
class PyViewsTC(EnvBasedTC):
def test_pyvaltable(self):
- content = self.vreg.render('pyvaltable', self.request(),
- pyvalue=[[1, 'a'], [2, 'b']],
- headers=['num', 'char'])
+ content = self.vreg['views'].render('pyvaltable', self.request(),
+ pyvalue=[[1, 'a'], [2, 'b']],
+ headers=['num', 'char'])
self.assertEquals(content.strip(), '''<table class="listing">
<tr><th>num</th><th>char</th></tr>
<tr><td>1</td><td>a</td></tr>
@@ -14,8 +14,8 @@
</table>''')
def test_pyvallist(self):
- content = self.vreg.render('pyvallist', self.request(),
- pyvalue=[1, 'a'])
+ content = self.vreg['views'].render('pyvallist', self.request(),
+ pyvalue=[1, 'a'])
self.assertEquals(content.strip(), '''<ul>
<li>1</li>
<li>a</li>
--- a/web/test/unittest_viewselector.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/test/unittest_viewselector.py Tue Aug 04 15:08:18 2009 +0200
@@ -35,7 +35,7 @@
self.add_entity('Tag', name=u'x')
def pactions(self, req, rset):
- resdict = self.vreg.possible_actions(req, rset)
+ resdict = self.vreg['actions'].possible_actions(req, rset)
for cat, actions in resdict.items():
resdict[cat] = [(a.id, a.__class__) for a in actions]
return resdict
@@ -132,26 +132,26 @@
assert self.vreg['views']['propertiesform']
rset1, req1 = self.env.get_rset_and_req('CWUser X WHERE X login "admin"')
rset2, req2 = self.env.get_rset_and_req('CWUser X WHERE X login "anon"')
- self.failUnless(self.vreg.select('views', 'propertiesform', req1, rset=None))
- self.failUnless(self.vreg.select('views', 'propertiesform', req1, rset=rset1))
- self.failUnless(self.vreg.select('views', 'propertiesform', req2, rset=rset2))
+ self.failUnless(self.vreg['views'].select('propertiesform', req1, rset=None))
+ self.failUnless(self.vreg['views'].select('propertiesform', req1, rset=rset1))
+ self.failUnless(self.vreg['views'].select('propertiesform', req2, rset=rset2))
def test_propertiesform_anon(self):
self.login('anon')
rset1, req1 = self.env.get_rset_and_req('CWUser X WHERE X login "admin"')
rset2, req2 = self.env.get_rset_and_req('CWUser X WHERE X login "anon"')
- self.assertRaises(NoSelectableObject, self.vreg.select, 'views', 'propertiesform', req1, rset=None)
- self.assertRaises(NoSelectableObject, self.vreg.select, 'views', 'propertiesform', req1, rset=rset1)
- self.assertRaises(NoSelectableObject, self.vreg.select, 'views', 'propertiesform', req1, rset=rset2)
+ self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req1, rset=None)
+ self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req1, rset=rset1)
+ self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req1, rset=rset2)
def test_propertiesform_jdoe(self):
self.create_user('jdoe')
self.login('jdoe')
rset1, req1 = self.env.get_rset_and_req('CWUser X WHERE X login "admin"')
rset2, req2 = self.env.get_rset_and_req('CWUser X WHERE X login "jdoe"')
- self.failUnless(self.vreg.select('views', 'propertiesform', req1, rset=None))
- self.assertRaises(NoSelectableObject, self.vreg.select, 'views', 'propertiesform', req1, rset=rset1)
- self.failUnless(self.vreg.select('views', 'propertiesform', req2, rset=rset2))
+ self.failUnless(self.vreg['views'].select('propertiesform', req1, rset=None))
+ self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req1, rset=rset1)
+ self.failUnless(self.vreg['views'].select('propertiesform', req2, rset=rset2))
def test_possible_views_multiple_different_types(self):
rset, req = self.env.get_rset_and_req('Any X')
@@ -267,103 +267,103 @@
req = self.request()
# creation form
req.form['etype'] = 'CWGroup'
- self.assertIsInstance(self.vreg.select('views', 'creation', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('creation', req, rset=rset),
editforms.CreationFormView)
del req.form['etype']
# custom creation form
class CWUserCreationForm(editforms.CreationFormView):
__select__ = specified_etype_implements('CWUser')
self.vreg._loadedmods[__name__] = {}
- self.vreg.register_vobject_class(CWUserCreationForm)
+ self.vreg.register_appobject_class(CWUserCreationForm)
req.form['etype'] = 'CWUser'
- self.assertIsInstance(self.vreg.select('views', 'creation', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('creation', req, rset=rset),
CWUserCreationForm)
def test_select_view(self):
# no entity
rset = None
req = self.request()
- self.assertIsInstance(self.vreg.select('views', 'index', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('index', req, rset=rset),
startup.IndexView)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'primary', req, rset=rset)
+ self.vreg['views'].select, 'primary', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'table', req, rset=rset)
+ self.vreg['views'].select, 'table', req, rset=rset)
# no entity
rset, req = self.env.get_rset_and_req('Any X WHERE X eid 999999')
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'index', req, rset=rset)
+ self.vreg['views'].select, 'index', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'creation', req, rset=rset)
+ self.vreg['views'].select, 'creation', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'primary', req, rset=rset)
+ self.vreg['views'].select, 'primary', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'table', req, rset=rset)
+ self.vreg['views'].select, 'table', req, rset=rset)
# one entity
rset, req = self.env.get_rset_and_req('CWGroup X WHERE X name "managers"')
- self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
primary.PrimaryView)
- self.assertIsInstance(self.vreg.select('views', 'list', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('list', req, rset=rset),
baseviews.ListView)
- self.assertIsInstance(self.vreg.select('views', 'edition', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('edition', req, rset=rset),
editforms.EditionFormView)
- self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
tableview.TableView)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'creation', req, rset=rset)
+ self.vreg['views'].select, 'creation', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'index', req, rset=rset)
+ self.vreg['views'].select, 'index', req, rset=rset)
# list of entities of the same type
rset, req = self.env.get_rset_and_req('CWGroup X')
- self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
primary.PrimaryView)
- self.assertIsInstance(self.vreg.select('views', 'list', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('list', req, rset=rset),
baseviews.ListView)
- self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
tableview.TableView)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'creation', req, rset=rset)
+ self.vreg['views'].select, 'creation', req, rset=rset)
# list of entities of different types
rset, req = self.env.get_rset_and_req('Any X')
- self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
primary.PrimaryView)
- self.assertIsInstance(self.vreg.select('views', 'list', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('list', req, rset=rset),
baseviews.ListView)
- self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
tableview.TableView)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'creation', req, rset=rset)
+ self.vreg['views'].select, 'creation', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'index', req, rset=rset)
+ self.vreg['views'].select, 'index', req, rset=rset)
# whatever
rset, req = self.env.get_rset_and_req('Any N, X WHERE X in_group Y, Y name N')
- self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
tableview.TableView)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'index', req, rset=rset)
+ self.vreg['views'].select, 'index', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'creation', req, rset=rset)
+ self.vreg['views'].select, 'creation', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'primary', req, rset=rset)
+ self.vreg['views'].select, 'primary', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'list', req, rset=rset)
+ self.vreg['views'].select, 'list', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'edition', req, rset=rset)
+ self.vreg['views'].select, 'edition', req, rset=rset)
# mixed query
rset, req = self.env.get_rset_and_req('Any U,G WHERE U is CWUser, G is CWGroup')
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'edition', req, rset=rset)
+ self.vreg['views'].select, 'edition', req, rset=rset)
self.failUnlessRaises(NoSelectableObject,
- self.vreg.select, 'views', 'creation', req, rset=rset)
- self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset),
+ self.vreg['views'].select, 'creation', req, rset=rset)
+ self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
tableview.TableView)
def test_interface_selector(self):
image = self.add_entity('Image', name=u'bim.png', data=Binary('bim'))
# image primary view priority
rset, req = self.env.get_rset_and_req('Image X WHERE X name "bim.png"')
- self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
idownloadable.IDownloadablePrimaryView)
@@ -371,12 +371,12 @@
image = self.add_entity('Image', name=u'bim.png', data=Binary('bim'))
# image primary view priority
rset, req = self.env.get_rset_and_req('Image X WHERE X name "bim.png"')
- self.assertIsInstance(self.vreg.select('views', 'image', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('image', req, rset=rset),
idownloadable.ImageView)
fileobj = self.add_entity('File', name=u'bim.txt', data=Binary('bim'))
# image primary view priority
rset, req = self.env.get_rset_and_req('File X WHERE X name "bim.txt"')
- self.assertRaises(NoSelectableObject, self.vreg.select, 'views', 'image', req, rset=rset)
+ self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'image', req, rset=rset)
@@ -387,7 +387,7 @@
else:
rset, req = self.env.get_rset_and_req(rql)
try:
- self.vreg.render(vid, req, rset=rset, **args)
+ self.vreg['views'].render(vid, req, rset=rset, **args)
except:
print vid, rset, args
raise
@@ -431,11 +431,11 @@
def setUp(self):
super(RQLActionTC, self).setUp()
self.vreg._loadedmods[__name__] = {}
- self.vreg.register_vobject_class(CWETypeRQLAction)
+ self.vreg.register_appobject_class(CWETypeRQLAction)
def tearDown(self):
super(RQLActionTC, self).tearDown()
- del self.vreg._registries['actions']['testaction']
+ del self.vreg['actions']['testaction']
def test(self):
rset, req = self.env.get_rset_and_req('CWEType X WHERE X name "CWEType"')
--- a/web/views/actions.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/actions.py Tue Aug 04 15:08:18 2009 +0200
@@ -8,7 +8,7 @@
__docformat__ = "restructuredtext en"
_ = unicode
-from cubicweb.vregistry import objectify_selector
+from cubicweb.appobject import objectify_selector
from cubicweb.selectors import (EntitySelector,
one_line_rset, two_lines_rset, one_etype_rset, relation_possible,
nonempty_rset, non_final_entity,
--- a/web/views/basecomponents.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/basecomponents.py Tue Aug 04 15:08:18 2009 +0200
@@ -90,7 +90,7 @@
def call(self):
if not self.req.cnx.anonymous_connection:
# display useractions and siteactions
- actions = self.vreg.possible_actions(self.req, self.rset)
+ actions = self.vreg['actions'].possible_actions(self.req, rset=self.rset)
box = MenuWidget('', 'userActionsBox', _class='', islist=False)
menu = PopupBoxMenu(self.req.user.login, isitem=False)
box.append(menu)
--- a/web/views/basecontrollers.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/basecontrollers.py Tue Aug 04 15:08:18 2009 +0200
@@ -100,7 +100,8 @@
self.add_to_breadcrumbs(view)
self.validate_cache(view)
template = self.appli.main_template_id(self.req)
- return self.vreg.main_template(self.req, template, rset=rset, view=view)
+ return self.vreg['views'].main_template(self.req, template,
+ rset=rset, view=view)
def _select_view_and_rset(self, rset):
req = self.req
@@ -119,12 +120,12 @@
req.set_message(req._("error while handling __method: %s") % req._(ex))
vid = req.form.get('vid') or vid_from_rset(req, rset, self.schema)
try:
- view = self.vreg.select('views', vid, req, rset=rset)
+ view = self.vreg['views'].select(vid, req, rset=rset)
except ObjectNotFound:
self.warning("the view %s could not be found", vid)
req.set_message(req._("The view %s could not be found") % vid)
vid = vid_from_rset(req, rset, self.schema)
- view = self.vreg.select('views', vid, req, rset=rset)
+ view = self.vreg['views'].select(vid, req, rset=rset)
except NoSelectableObject:
if rset:
req.set_message(req._("The view %s can not be applied to this query") % vid)
@@ -132,7 +133,7 @@
req.set_message(req._("You have no access to this view or it's not applyable to current data"))
self.warning("the view %s can not be applied to this query", vid)
vid = vid_from_rset(req, rset, self.schema)
- view = self.vreg.select('views', vid, req, rset=rset)
+ view = self.vreg['views'].select(vid, req, rset=rset)
return view, rset
def add_to_breadcrumbs(self, view):
@@ -183,7 +184,7 @@
def _validate_form(req, vreg):
# XXX should use the `RemoteCallFailed` mechanism
try:
- ctrl = vreg.select('controllers', 'edit', req=req)
+ ctrl = vreg['controllers'].select('edit', req=req)
except NoSelectableObject:
return (False, {None: req._('not authorized')})
try:
@@ -309,10 +310,10 @@
rset = None
vid = req.form.get('vid') or vid_from_rset(req, rset, self.schema)
try:
- view = self.vreg.select('views', vid, req, rset=rset)
+ view = self.vreg['views'].select(vid, req, rset=rset)
except NoSelectableObject:
vid = req.form.get('fallbackvid', 'noresult')
- view = self.vreg.select('views', vid, req, rset=rset)
+ view = self.vreg['views'].select(vid, req, rset=rset)
divid = req.form.get('divid', 'pageContent')
# we need to call pagination before with the stream set
stream = view.set_stream()
@@ -339,10 +340,10 @@
@xhtmlize
def js_prop_widget(self, propkey, varname, tabindex=None):
"""specific method for CWProperty handling"""
- entity = self.vreg.etype_class('CWProperty')(self.req, None, None)
+ entity = self.vreg['etypes'].etype_class('CWProperty')(self.req)
entity.eid = varname
entity['pkey'] = propkey
- form = self.vreg.select('forms', 'edition', self.req, entity=entity)
+ form = self.vreg['forms'].select('edition', self.req, entity=entity)
form.form_build_context()
vfield = form.field_by_name('value')
renderer = FormRenderer(self.req)
@@ -355,7 +356,7 @@
rset = self._exec(rql)
else:
rset = None
- comp = self.vreg.select(registry, compid, self.req, rset=rset)
+ comp = self.vreg[registry].select(compid, self.req, rset=rset)
if extraargs is None:
extraargs = {}
else: # we receive unicode keys which is not supported by the **syntax
@@ -367,8 +368,9 @@
@check_pageid
@xhtmlize
def js_inline_creation_form(self, peid, ttype, rtype, role):
- view = self.vreg.select('views', 'inline-creation', self.req,
- etype=ttype, peid=peid, rtype=rtype, role=role)
+ view = self.vreg['views'].select('inline-creation', self.req,
+ etype=ttype, peid=peid, rtype=rtype,
+ role=role)
return view.render(etype=ttype, peid=peid, rtype=rtype, role=role)
@jsonize
--- a/web/views/basetemplates.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/basetemplates.py Tue Aug 04 15:08:18 2009 +0200
@@ -10,7 +10,7 @@
from logilab.mtconverter import xml_escape
-from cubicweb.vregistry import objectify_selector
+from cubicweb.appobject import objectify_selector
from cubicweb.selectors import match_kwargs
from cubicweb.view import View, MainTemplate, NOINDEX, NOFOLLOW
from cubicweb.utils import make_uid, UStringIO
@@ -113,8 +113,8 @@
if vtitle:
w(u'<h1 class="vtitle">%s</h1>\n' % xml_escape(vtitle))
# display entity type restriction component
- etypefilter = self.vreg.select_vobject('components', 'etypenavigation',
- self.req, rset=self.rset)
+ etypefilter = self.vreg['components'].select_vobject(
+ 'etypenavigation', self.req, rset=self.rset)
if etypefilter:
etypefilter.render(w=w)
self.nav_html = UStringIO()
@@ -154,12 +154,12 @@
w(u'<div id="page"><table width="100%" border="0" id="mainLayout"><tr>\n')
self.nav_column(view, 'left')
w(u'<td id="contentcol">\n')
- rqlcomp = self.vreg.select_object('components', 'rqlinput', self.req,
- rset=self.rset)
+ rqlcomp = self.vreg['components'].select_object('rqlinput', self.req,
+ rset=self.rset)
if rqlcomp:
rqlcomp.render(w=self.w, view=view)
- msgcomp = self.vreg.select_object('components', 'applmessages',
- self.req, rset=self.rset)
+ msgcomp = self.vreg['components'].select_object('applmessages',
+ self.req, rset=self.rset)
if msgcomp:
msgcomp.render(w=self.w)
self.content_header(view)
@@ -173,8 +173,8 @@
self.w(u'</body>')
def nav_column(self, view, context):
- boxes = list(self.vreg.possible_vobjects('boxes', self.req, rset=self.rset,
- view=view, context=context))
+ boxes = list(self.vreg['boxes'].possible_vobjects(
+ self.req, rset=self.rset, view=view, context=context))
if boxes:
self.w(u'<td class="navcol"><div class="navboxes">\n')
for box in boxes:
@@ -200,7 +200,7 @@
"""display an unexpected error"""
self.set_request_content_type()
self.req.reset_headers()
- view = self.vreg.select('views', 'error', self.req, rset=self.rset)
+ view = self.vreg['views'].select('error', self.req, rset=self.rset)
self.template_header(self.content_type, view, self.req._('an error occured'),
[NOINDEX, NOFOLLOW])
view.render(w=self.w)
@@ -242,8 +242,8 @@
w(u'<table width="100%" height="100%" border="0"><tr>\n')
w(u'<td class="navcol">\n')
self.topleft_header()
- boxes = list(self.vreg.possible_vobjects('boxes', self.req, rset=self.rset,
- view=view, context='left'))
+ boxes = list(self.vreg['boxes'].possible_vobjects(
+ self.req, rset=self.rset, view=view, context='left'))
if boxes:
w(u'<div class="navboxes">\n')
for box in boxes:
@@ -257,8 +257,8 @@
w(u'<h1 class="vtitle">%s</h1>' % xml_escape(vtitle))
def topleft_header(self):
- logo = self.vreg.select_vobject('components', 'logo', self.req,
- rset=self.rset)
+ logo = self.vreg['components'].select_vobject('logo', self.req,
+ rset=self.rset)
if logo:
self.w(u'<table id="header"><tr>\n')
self.w(u'<td>')
@@ -299,7 +299,7 @@
self.req.add_js(jscript, localfile=False)
def alternates(self):
- urlgetter = self.vreg.select_object('components', 'rss_feed_url',
+ urlgetter = self.vreg['components'].select_object('rss_feed_url',
self.req, rset=self.rset)
if urlgetter is not None:
self.whead(u'<link rel="alternate" type="application/rss+xml" title="RSS feed" href="%s"/>\n'
@@ -329,28 +329,28 @@
"""build the top menu with authentification info and the rql box"""
self.w(u'<table id="header"><tr>\n')
self.w(u'<td id="firstcolumn">')
- logo = self.vreg.select_vobject('components', 'logo',
- self.req, rset=self.rset)
+ logo = self.vreg['components'].select_vobject(
+ 'logo', self.req, rset=self.rset)
if logo:
logo.render(w=self.w)
self.w(u'</td>\n')
# appliname and breadcrumbs
self.w(u'<td id="headtext">')
for cid in ('appliname', 'breadcrumbs'):
- comp = self.vreg.select_vobject('components', cid,
- self.req, rset=self.rset)
+ comp = self.vreg['components'].select_vobject(
+ cid, self.req, rset=self.rset)
if comp:
comp.render(w=self.w)
self.w(u'</td>')
# logged user and help
self.w(u'<td>\n')
- comp = self.vreg.select_vobject('components', 'loggeduserlink',
- self.req, rset=self.rset)
+ comp = self.vreg['components'].select_vobject(
+ 'loggeduserlink', self.req, rset=self.rset)
if comp:
comp.render(w=self.w)
self.w(u'</td><td>')
- helpcomp = self.vreg.select_vobject('components', 'help',
- self.req, rset=self.rset)
+ helpcomp = self.vreg['components'].select_vobject(
+ 'help', self.req, rset=self.rset)
if helpcomp:
helpcomp.render(w=self.w)
self.w(u'</td>')
@@ -405,9 +405,8 @@
def call(self, view, **kwargs):
"""by default, display informal messages in content header"""
- components = self.vreg.possible_vobjects('contentnavigation',
- self.req, rset=self.rset,
- view=view, context='navtop')
+ components = self.vreg['contentnavigation'].possible_vobjects(
+ self.req, rset=self.rset, view=view, context='navtop')
if components:
self.w(u'<div id="contentheader">')
for comp in components:
@@ -422,9 +421,8 @@
id = 'contentfooter'
def call(self, view, **kwargs):
- components = self.vreg.possible_vobjects('contentnavigation',
- self.req, rset=self.rset,
- view=view, context='navbottom')
+ components = self.vreg['contentnavigation'].possible_vobjects(
+ self.req, rset=self.rset, view=view, context='navbottom')
if components:
self.w(u'<div id="contentfooter">')
for comp in components:
--- a/web/views/boxes.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/boxes.py Tue Aug 04 15:08:18 2009 +0200
@@ -51,7 +51,8 @@
title = u'%s - %s' % (title, etypelabel.lower())
box = BoxWidget(title, self.id, _class="greyBoxFrame")
# build list of actions
- actions = self.vreg.possible_actions(self.req, self.rset, view=view)
+ actions = self.vreg['actions'].possible_actions(self.req, self.rset,
+ view=view)
add_menu = BoxMenu(_('add')) # 'addrelated' category
other_menu = BoxMenu(_('more actions')) # 'moreactions' category
searchstate = self.req.search_state[0]
@@ -207,7 +208,8 @@
def call(self, **kwargs):
box = BoxWidget(self.req._(self.title), self.id)
- views = [v for v in self.vreg.possible_views(self.req, self.rset)
+ views = [v for v in self.vreg['views'].possible_views(self.req,
+ rset=self.rset)
if v.category != 'startupview']
for category, views in self.sort_actions(views):
menu = BoxMenu(category)
@@ -227,7 +229,7 @@
def call(self, **kwargs):
box = BoxWidget(self.req._(self.title), self.id)
- for view in self.vreg.possible_views(self.req, None):
+ for view in self.vreg['views'].possible_views(self.req, None):
if view.category == 'startupview':
box.append(self.box_action(view))
--- a/web/views/cwproperties.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/cwproperties.py Tue Aug 04 15:08:18 2009 +0200
@@ -180,7 +180,7 @@
if key in values:
entity = self.cwprops_rset.get_entity(values[key], 0)
else:
- entity = self.vreg.etype_class('CWProperty')(self.req, None, None)
+ entity = self.vreg['etypes'].etype_class('CWProperty')(self.req)
entity.eid = self.req.varmaker.next()
entity['pkey'] = key
entity['value'] = self.vreg.property_value(key)
@@ -188,11 +188,11 @@
def form(self, formid, keys, splitlabel=False):
buttons = [SubmitButton()]
- form = self.vreg.select('forms', 'composite', self.req,
- domid=formid, action=self.build_url(),
- form_buttons=buttons,
- onsubmit="return validatePrefsForm('%s')" % formid,
- submitmsg=self.req._('changes applied'))
+ form = self.vreg['forms'].select(
+ 'composite', self.req, domid=formid, action=self.build_url(),
+ form_buttons=buttons,
+ onsubmit="return validatePrefsForm('%s')" % formid,
+ submitmsg=self.req._('changes applied'))
path = self.req.relative_path()
if '?' in path:
path, params = path.split('?', 1)
@@ -200,8 +200,8 @@
form.form_add_hidden('__redirectpath', path)
for key in keys:
self.form_row(form, key, splitlabel)
- renderer = self.vreg.select('formrenderers', 'cwproperties', self.req,
- display_progress_div=False)
+ renderer = self.vreg['formrenderers'].select('cwproperties', self.req,
+ display_progress_div=False)
return form.form_render(renderer=renderer)
def form_row(self, form, key, splitlabel):
@@ -210,8 +210,8 @@
label = key.split('.')[-1]
else:
label = key
- subform = self.vreg.select('forms', 'base', self.req, entity=entity,
- mainform=False)
+ subform = self.vreg['forms'].select('base', self.req, entity=entity,
+ mainform=False)
subform.append_field(PropertyValueField(name='value', label=label,
eidparam=True))
subform.vreg = self.vreg
--- a/web/views/editcontroller.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/editcontroller.py Tue Aug 04 15:08:18 2009 +0200
@@ -81,7 +81,7 @@
def edit_entity(self, formparams, multiple=False):
"""edit / create / copy an entity and return its eid"""
etype = formparams['__type']
- entity = self.vreg.etype_class(etype)(self.req, None, None)
+ entity = self.vreg['etypes'].etype_class(etype)(self.req)
entity.eid = eid = self._get_eid(formparams['eid'])
edited = self.req.form.get('__maineid') == formparams['eid']
# let a chance to do some entity specific stuff.
--- a/web/views/editforms.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/editforms.py Tue Aug 04 15:08:18 2009 +0200
@@ -62,8 +62,8 @@
if entity.eid in done:
continue
done.add(entity.eid)
- subform = self.vreg.select('forms', 'base', self.req, entity=entity,
- mainform=False)
+ subform = self.vreg['forms'].select('base', self.req, entity=entity,
+ mainform=False)
self.form_add_subform(subform)
@@ -83,8 +83,8 @@
% _('this action is not reversible!'))
# XXX above message should have style of a warning
w(u'<h4>%s</h4>\n' % _('Do you want to delete the following element(s) ?'))
- form = self.vreg.select('forms', self.id, req, rset=self.rset,
- onsubmit=onsubmit)
+ form = self.vreg['forms'].select(self.id, req, rset=self.rset,
+ onsubmit=onsubmit)
w(u'<ul>\n')
for entity in self.rset.entities():
# don't use outofcontext view or any other that may contain inline edition form
@@ -127,12 +127,10 @@
return lzone or self._defaultlandingzone % {'msg' : xml_escape(self.req._(self._landingzonemsg))}
def _build_renderer(self, entity, rtype, role):
- return self.vreg.select_object('formrenderers', 'base', self.req,
- entity=entity,
- display_label=False, display_help=False,
- display_fields=[(rtype, role)],
- table_class='', button_bar_class='buttonbar',
- display_progress_div=False)
+ return self.vreg['formrenderers'].select(
+ 'base', self.req, entity=entity, display_label=False,
+ display_help=False, display_fields=[(rtype, role)], table_class='',
+ button_bar_class='buttonbar', display_progress_div=False)
def cell_call(self, row, col, rtype=None, role='subject',
reload=False, # controls reloading the whole page after change
@@ -207,12 +205,12 @@
% event_data)
cancelclick = "hideInlineEdit(%s,\'%s\',\'%s\')" % (
entity.eid, rtype, divid)
- form = self.vreg.select('forms', 'base', self.req, entity=entity,
- domid='%s-form' % divid, cssstyle='display: none',
- onsubmit=onsubmit, action='#',
- form_buttons=[SubmitButton(),
- Button(stdmsgs.BUTTON_CANCEL,
- onclick=cancelclick)])
+ form = self.vreg['forms'].select('base', self.req, entity=entity,
+ domid='%s-form' % divid, cssstyle='display: none',
+ onsubmit=onsubmit, action='#',
+ form_buttons=[SubmitButton(),
+ Button(stdmsgs.BUTTON_CANCEL,
+ onclick=cancelclick)])
field = guess_field(entity.e_schema, entity.schema.rschema(rtype), role)
form.append_field(field)
w = self.w
@@ -243,12 +241,12 @@
Button(stdmsgs.BUTTON_CANCEL,
onclick="hideInlineEdit(%s,\'%s\',\'%s\')" % (
eid, rtype, divid))]
- form = self.vreg.select('forms', 'edition', self.req, rset=self.rset,
- row=row, col=col, form_buttons=buttons,
- attrcategories=self.attrcategories,
- domid='%s-form' % divid, action='#',
- cssstyle='display: none',
- onsubmit=onsubmit % event_data)
+ form = self.vreg['forms'].select('edition', self.req, rset=self.rset,
+ row=row, col=col, form_buttons=buttons,
+ attrcategories=self.attrcategories,
+ domid='%s-form' % divid, action='#',
+ cssstyle='display: none',
+ onsubmit=onsubmit % event_data)
try:
field = form.field_by_name(rtype, role)
except FieldNotFound:
@@ -283,9 +281,9 @@
def render_form(self, entity):
"""fetch and render the form"""
self.form_title(entity)
- form = self.vreg.select('forms', 'edition', self.req, rset=entity.rset,
- row=entity.row, col=entity.col, entity=entity,
- submitmsg=self.submited_message())
+ form = self.vreg['forms'].select('edition', self.req, rset=entity.rset,
+ row=entity.row, col=entity.col, entity=entity,
+ submitmsg=self.submited_message())
self.init_form(form, entity)
self.w(form.form_render(formvid=u'edition'))
@@ -315,7 +313,7 @@
"""creation view for an entity"""
etype = kwargs.pop('etype', self.req.form.get('etype'))
try:
- entity = self.vreg.etype_class(etype)(self.req)
+ entity = self.vreg['etypes'].etype_class(etype)(self.req)
except:
self.w(self.req._('no such entity type %s') % etype)
else:
@@ -402,9 +400,10 @@
kwargs.setdefault('__redirectrql', rset.printable_rql())
super(TableEditForm, self).__init__(req, rset, **kwargs)
for row in xrange(len(self.rset)):
- form = self.vreg.select('forms', 'edition', self.req, rset=self.rset,
- row=row, attrcategories=('primary',),
- mainform=False)
+ form = self.vreg['forms'].select('edition', self.req,
+ rset=self.rset, row=row,
+ attrcategories=('primary',),
+ mainform=False)
# XXX rely on the EntityCompositeFormRenderer to put the eid input
form.remove_field(form.field_by_name('eid'))
self.form_add_subform(form)
@@ -420,7 +419,7 @@
should be the eid
"""
#self.form_title(entity)
- form = self.vreg.select('forms', self.id, self.req, rset=self.rset)
+ form = self.vreg['forms'].select(self.id, self.req, rset=self.rset)
self.w(form.form_render())
@@ -451,9 +450,9 @@
def render_form(self, entity, peid, rtype, role, **kwargs):
"""fetch and render the form"""
- form = self.vreg.select('forms', 'edition', self.req, entity=entity,
- form_renderer_id='inline', mainform=False,
- copy_nav_params=False)
+ form = self.vreg['forms'].select('edition', self.req, entity=entity,
+ form_renderer_id='inline',
+ mainform=False, copy_nav_params=False)
self.add_hiddens(form, entity, peid, rtype, role)
divid = '%s-%s-%s' % (peid, rtype, entity.eid)
title = self.schema.rschema(rtype).display_name(self.req, role)
@@ -503,7 +502,7 @@
:param role: the role played by the `peid` in the relation
"""
try:
- entity = self.vreg.etype_class(etype)(self.req, None, None)
+ entity = self.vreg['etypes'].etype_class(etype)(self.req, None, None)
except:
self.w(self.req._('no such entity type %s') % etype)
return
--- a/web/views/editviews.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/editviews.py Tue Aug 04 15:08:18 2009 +0200
@@ -120,7 +120,7 @@
eid = entity.eid
pending_inserts = self.req.get_pending_inserts(eid)
rtype = rschema.type
- form = self.vreg.select('forms', 'edition', self.req, entity=entity)
+ form = self.vreg['forms'].select('edition', self.req, entity=entity)
field = form.field_by_name(rschema, target, entity.e_schema)
limit = self.req.property_value('navigation.combobox-limit')
for eview, reid in form.form_field_vocabulary(field, limit):
--- a/web/views/embedding.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/embedding.py Tue Aug 04 15:08:18 2009 +0200
@@ -73,7 +73,8 @@
body = '<h2>%s</h2><h3>%s</h3>' % (
_('error while embedding page'), err)
self.process_rql(req.form.get('rql'))
- return self.vreg.main_template(req, self.template, rset=self.rset, body=body)
+ return self.vreg['views'].main_template(req, self.template,
+ rset=self.rset, body=body)
def entity_has_embedable_url(entity):
--- a/web/views/facets.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/facets.py Tue Aug 04 15:08:18 2009 +0200
@@ -11,7 +11,7 @@
from logilab.mtconverter import xml_escape
-from cubicweb.vregistry import objectify_selector
+from cubicweb.appobject import objectify_selector
from cubicweb.selectors import (non_final_entity, two_lines_rset,
match_context_prop, yes, relation_possible)
from cubicweb.web.box import BoxTemplate
@@ -118,9 +118,9 @@
self.w(self.bk_linkbox_template % bk_link)
def get_facets(self, rset, mainvar):
- return self.vreg.possible_vobjects('facets', self.req, rset=rset,
- context='facetbox',
- filtered_variable=mainvar)
+ return self.vreg['facets'].possible_vobjects(self.req, rset=rset,
+ context='facetbox',
+ filtered_variable=mainvar)
# facets ######################################################################
--- a/web/views/formrenderers.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/formrenderers.py Tue Aug 04 15:08:18 2009 +0200
@@ -13,7 +13,7 @@
from simplejson import dumps
from cubicweb.common import tags
-from cubicweb.appobject import AppRsetObject
+from cubicweb.appobject import AppObject
from cubicweb.selectors import entity_implements, yes
from cubicweb.web import eid_param
from cubicweb.web import formwidgets as fwdgs
@@ -21,7 +21,7 @@
from cubicweb.web.formfields import HiddenInitialValueField
-class FormRenderer(AppRsetObject):
+class FormRenderer(AppObject):
"""basic renderer displaying fields in a two columns table label | value
+--------------+--------------+
--- a/web/views/forms.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/forms.py Tue Aug 04 15:08:18 2009 +0200
@@ -179,9 +179,9 @@
return renderer.render(self, values)
def form_default_renderer(self):
- return self.vreg.select('formrenderers', self.form_renderer_id,
- self.req, rset=self.rset,
- row=self.row, col=self.col)
+ return self.vreg['formrenderers'].select(self.form_renderer_id,
+ self.req, rset=self.rset,
+ row=self.row, col=self.col)
def form_build_context(self, rendervalues=None):
"""build form context values (the .context attribute which is a
@@ -288,7 +288,8 @@
class EntityFieldsForm(FieldsForm):
id = 'base'
- __select__ = (match_kwargs('entity') | (one_line_rset & non_final_entity()))
+ __select__ = (match_kwargs('entity')
+ | (one_line_rset() & non_final_entity()))
internal_fields = FieldsForm.internal_fields + ('__type', 'eid', '__maineid')
domid = 'entityForm'
@@ -366,9 +367,9 @@
return value
def form_default_renderer(self):
- return self.vreg.select('formrenderers', self.form_renderer_id,
- self.req, rset=self.rset, row=self.row,
- col=self.col, entity=self.edited_entity)
+ return self.vreg['formrenderers'].select(
+ self.form_renderer_id, self.req, rset=self.rset, row=self.row,
+ col=self.col, entity=self.edited_entity)
def form_build_context(self, values=None):
"""overriden to add edit[s|o] hidden fields and to ensure schema fields
--- a/web/views/iprogress.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/iprogress.py Tue Aug 04 15:08:18 2009 +0200
@@ -48,7 +48,7 @@
self.req.add_css('cubicweb.iprogress.css')
_ = self.req._
self.columns = columns or self.columns
- ecls = self.vreg.etype_class(self.rset.description[0][0])
+ ecls = self.vreg['etypes'].etype_class(self.rset.description[0][0])
self.w(u'<table class="progress">')
self.table_header(ecls)
self.w(u'<tbody>')
@@ -168,8 +168,8 @@
id = 'ic_progress_table_view'
def call(self):
- view = self.vreg.select('views', 'progress_table_view', self.req,
- rset=self.rset)
+ view = self.vreg['views'].select('progress_table_view', self.req,
+ rset=self.rset)
columns = list(view.columns)
try:
columns.remove('project')
--- a/web/views/magicsearch.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/magicsearch.py Tue Aug 04 15:08:18 2009 +0200
@@ -348,8 +348,7 @@
super(MagicSearchComponent, self).__init__(req, rset)
processors = []
self.by_name = {}
- for processorcls in self.vreg.registry_objects('components',
- 'magicsearch_processor'):
+ for processorcls in self.vreg['components']['magicsearch_processor']:
# instantiation needed
processor = processorcls()
processors.append(processor)
--- a/web/views/management.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/management.py Tue Aug 04 15:08:18 2009 +0200
@@ -107,12 +107,12 @@
def owned_by_edit_form(self, entity):
self.w('<h3>%s</h3>' % self.req._('ownership'))
msg = self.req._('ownerships have been changed')
- form = self.vreg.select('forms', 'base', self.req, entity=entity,
- form_renderer_id='base', submitmsg=msg,
- form_buttons=[wdgs.SubmitButton()],
- domid='ownership%s' % entity.eid,
- __redirectvid='security',
- __redirectpath=entity.rest_path())
+ form = self.vreg['forms'].select('base', self.req, entity=entity,
+ form_renderer_id='base', submitmsg=msg,
+ form_buttons=[wdgs.SubmitButton()],
+ domid='ownership%s' % entity.eid,
+ __redirectvid='security',
+ __redirectpath=entity.rest_path())
field = guess_field(entity.e_schema, self.schema.rschema('owned_by'))
form.append_field(field)
self.w(form.form_render(display_progress_div=False))
@@ -160,14 +160,14 @@
self.w(self.req._('no associated permissions'))
def require_permission_edit_form(self, entity):
- newperm = self.vreg.etype_class('CWPermission')(self.req, None)
+ newperm = self.vreg['etypes'].etype_class('CWPermission')(self.req)
newperm.eid = self.req.varmaker.next()
self.w(u'<p>%s</p>' % self.req._('add a new permission'))
- form = self.vreg.select('forms', 'base', self.req, entity=newperm,
- form_buttons=[wdgs.SubmitButton()],
- domid='reqperm%s' % entity.eid,
- __redirectvid='security',
- __redirectpath=entity.rest_path())
+ form = self.vreg['forms'].select('base', self.req, entity=newperm,
+ form_buttons=[wdgs.SubmitButton()],
+ domid='reqperm%s' % entity.eid,
+ __redirectvid='security',
+ __redirectpath=entity.rest_path())
form.form_add_hidden('require_permission', entity.eid, role='object',
eidparam=True)
permnames = getattr(entity, '__permissions__', None)
@@ -183,8 +183,8 @@
form.append_field(field)
field = guess_field(cwpermschema, self.schema.rschema('require_group'))
form.append_field(field)
- renderer = self.vreg.select('formrenderers', 'htable', self.req,
- rset=None, display_progress_div=False)
+ renderer = self.vreg['formrenderers'].select(
+ 'htable', self.req, rset=None, display_progress_div=False)
self.w(form.form_render(renderer=renderer))
@@ -241,8 +241,8 @@
submiturl = self.config['submit-url']
submitmail = self.config['submit-mail']
if submiturl or submitmail:
- form = self.vreg.select('forms', 'base', self.req, rset=None,
- mainform=False)
+ form = self.vreg['forms'].select('base', self.req, rset=None,
+ mainform=False)
binfo = text_error_description(ex, excinfo, req, eversion, cversions)
form.form_add_hidden('description', binfo,
# we must use a text area to keep line breaks
--- a/web/views/massmailing.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/massmailing.py Tue Aug 04 15:08:18 2009 +0200
@@ -68,7 +68,7 @@
def get_allowed_substitutions(self):
attrs = []
for coltype in self.rset.column_types(0):
- eclass = self.vreg.etype_class(coltype)
+ eclass = self.vreg['etypes'].etype_class(coltype)
attrs.append(eclass.allowed_massmail_keys())
return sorted(reduce(operator.and_, attrs))
@@ -126,6 +126,6 @@
req.add_js('cubicweb.widgets.js', 'cubicweb.massmailing.js')
req.add_css('cubicweb.mailform.css')
from_addr = '%s <%s>' % (req.user.dc_title(), req.user.get_email())
- form = self.vreg.select('forms', 'massmailing', self.req, rset=self.rset,
+ form = self.vreg['forms'].select('massmailing', self.req, rset=self.rset,
action='sendmail', domid='sendmail')
self.w(form.form_render(sender=from_addr))
--- a/web/views/navigation.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/navigation.py Tue Aug 04 15:08:18 2009 +0200
@@ -149,7 +149,7 @@
def limit_rset_using_paged_nav(self, req, rset, w, forcedisplay=False,
show_all_option=True, page_size=None):
if not (forcedisplay or req.form.get('__force_display') is not None):
- nav = self.vreg.select_object('components', 'navigation', req,
+ nav = self.vreg['components'].select_object('navigation', req,
rset=rset, page_size=page_size)
if nav:
# get boundaries before component rendering
--- a/web/views/plots.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/plots.py Tue Aug 04 15:08:18 2009 +0200
@@ -16,7 +16,7 @@
from logilab.mtconverter import xml_escape
from cubicweb.utils import make_uid, UStringIO, datetime2ticks
-from cubicweb.vregistry import objectify_selector
+from cubicweb.appobject import objectify_selector
from cubicweb.web.views import baseviews
@objectify_selector
--- a/web/views/primary.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/primary.py Tue Aug 04 15:08:18 2009 +0200
@@ -71,9 +71,8 @@
def content_navigation_components(self, context):
self.w(u'<div class="%s">' % context)
- for comp in self.vreg.possible_vobjects('contentnavigation', self.req,
- rset=self.rset, row=self.row,
- view=self, context=context):
+ for comp in self.vreg['contentnavigation'].possible_vobjects(
+ self.req, rset=self.rset, row=self.row, view=self, context=context):
try:
comp.render(w=self.w, row=self.row, view=self)
except NotImplementedError:
@@ -148,9 +147,9 @@
label = display_name(self.req, rschema.type, role)
vid = dispctrl.get('vid', 'sidebox')
sideboxes.append( (label, rset, vid) )
- sideboxes += self.vreg.possible_vobjects('boxes', self.req, rset=self.rset,
- row=self.row, view=self,
- context='incontext')
+ sideboxes += self.vreg['boxes'].possible_vobjects(
+ self.req, rset=self.rset, row=self.row, view=self,
+ context='incontext')
return sideboxes
def _section_def(self, entity, where):
--- a/web/views/startup.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/startup.py Tue Aug 04 15:08:18 2009 +0200
@@ -83,7 +83,7 @@
self.startupviews_table()
def startupviews_table(self):
- for v in self.vreg.possible_views(self.req, None):
+ for v in self.vreg['views'].possible_views(self.req, None):
if v.category != 'startupview' or v.id in ('index', 'tree', 'manage'):
continue
self.w('<p><a href="%s">%s</a></p>' % (
--- a/web/views/tableview.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/tableview.py Tue Aug 04 15:08:18 2009 +0200
@@ -34,8 +34,8 @@
return ()
rqlst.save_state()
mainvar, baserql = prepare_facets_rqlst(rqlst, self.rset.args)
- wdgs = [facet.get_widget() for facet in self.vreg.possible_vobjects(
- 'facets', self.req, rset=self.rset, context='tablefilter',
+ wdgs = [facet.get_widget() for facet in self.vreg['facets'].possible_vobjects(
+ self.req, rset=self.rset, context='tablefilter',
filtered_variable=mainvar)]
wdgs = [wdg for wdg in wdgs if wdg is not None]
rqlst.recover()
--- a/web/views/tabs.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/tabs.py Tue Aug 04 15:08:18 2009 +0200
@@ -86,7 +86,7 @@
selected_tabs = []
for tab in tabs:
try:
- self.vreg.select('views', tab, self.req, rset=self.rset)
+ self.vreg['views'].select(tab, self.req, rset=self.rset)
selected_tabs.append(tab)
except NoSelectableObject:
continue
--- a/web/views/urlpublishing.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/urlpublishing.py Tue Aug 04 15:08:18 2009 +0200
@@ -56,8 +56,7 @@
super(URLPublisherComponent, self).__init__()
self.default_method = default_method
evaluators = []
- for evaluatorcls in self.vreg.registry_objects('components',
- 'urlpathevaluator'):
+ for evaluatorcls in self.vreg['components']['urlpathevaluator']:
# instantiation needed
evaluator = evaluatorcls(self)
evaluators.append(evaluator)
@@ -83,7 +82,7 @@
parts = [part for part in path.split('/')
if part != ''] or (self.default_method,)
if req.form.get('rql'):
- if parts[0] in self.vreg.registry('controllers'):
+ if parts[0] in self.vreg['controllers']:
return parts[0], None
return 'view', None
for evaluator in self.evaluators:
@@ -114,7 +113,7 @@
"""
priority = 0
def evaluate_path(self, req, parts):
- if len(parts) == 1 and parts[0] in self.vreg.registry('controllers'):
+ if len(parts) == 1 and parts[0] in self.vreg['controllers']:
return parts[0], None
raise PathDontMatch()
@@ -152,7 +151,7 @@
etype = self.vreg.case_insensitive_etypes[parts.pop(0).lower()]
except KeyError:
raise PathDontMatch()
- cls = self.vreg.etype_class(etype)
+ cls = self.vreg['etypes'].etype_class(etype)
if parts:
if len(parts) == 2:
attrname = parts.pop(0).lower()
@@ -195,10 +194,9 @@
def evaluate_path(self, req, parts):
# uri <=> req._twreq.path or req._twreq.uri
uri = req.url_unquote('/' + '/'.join(parts))
- vobjects = sorted(self.vreg.registry_objects('urlrewriting'),
- key=lambda x: x.priority,
- reverse=True)
- for rewritercls in vobjects:
+ evaluators = sorted(self.vreg['urlrewriting'].all_objects(),
+ key=lambda x: x.priority, reverse=True)
+ for rewritercls in evaluators:
rewriter = rewritercls()
try:
# XXX we might want to chain url rewrites
@@ -220,8 +218,9 @@
# remove last part and see if this is something like an actions
# if so, call
try:
+ actionsreg = self.vreg['actions']
requested = parts.pop(-1)
- actions = self.vreg.registry_objects('actions', requested)
+ actions = actionsreg[requested]
except RegistryException:
raise PathDontMatch()
for evaluator in self.urlpublisher.evaluators:
@@ -233,9 +232,9 @@
continue
else:
try:
- action = self.vreg.select_best(actions, req, rset=rset)
+ action = actionsreg.select_best(actions, req, rset=rset)
except RegistryException:
- raise PathDontMatch()
+ continue
else:
# XXX avoid redirect
raise Redirect(action.url())
--- a/web/views/urlrewrite.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/urlrewrite.py Tue Aug 04 15:08:18 2009 +0200
@@ -54,8 +54,6 @@
__metaclass__ = metarewriter
__registry__ = 'urlrewriting'
__abstract__ = True
-
- id = 'urlrewriting'
priority = 1
def rewrite(self, req, uri):
--- a/web/views/xmlrss.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/views/xmlrss.py Tue Aug 04 15:08:18 2009 +0200
@@ -135,8 +135,8 @@
except KeyError:
self.error('missing RSS_LOGO external resource')
return
- urlgetter = self.vreg.select('components', 'rss_feed_url',
- self.req, rset=self.rset)
+ urlgetter = self.vreg['components'].select('rss_feed_url', self.req,
+ rset=self.rset)
url = urlgetter.feed_url()
self.w(u'<a href="%s"><img src="%s" alt="rss"/></a>\n' % (xml_escape(url), rss))
--- a/web/webconfig.py Tue Aug 04 15:06:09 2009 +0200
+++ b/web/webconfig.py Tue Aug 04 15:08:18 2009 +0200
@@ -63,8 +63,8 @@
"""the WebConfiguration is a singleton object handling instance's
configuration and preferences
"""
- cubicweb_vobject_path = CubicWebConfiguration.cubicweb_vobject_path | set(['web/views'])
- cube_vobject_path = CubicWebConfiguration.cube_vobject_path | set(['views'])
+ cubicweb_appobject_path = CubicWebConfiguration.cubicweb_appobject_path | set(['web/views'])
+ cube_appobject_path = CubicWebConfiguration.cube_appobject_path | set(['views'])
options = merge_options(CubicWebConfiguration.options + (
('anonymous-user',