merge
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 13 Aug 2009 11:07:25 +0200
changeset 2815 ced3daf78e24
parent 2812 b260ed87a650 (diff)
parent 2814 112742b3bbe1 (current diff)
child 2816 85f7502d32be
merge
cwvreg.py
--- a/__init__.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/__init__.py	Thu Aug 13 11:07:25 2009 +0200
@@ -18,7 +18,6 @@
 
 import sys, os, logging
 from StringIO import StringIO
-from urllib import quote as urlquote, unquote as urlunquote
 
 from logilab.common.logging_ext import set_log_methods
 
--- a/appobject.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/appobject.py	Thu Aug 13 11:07:25 2009 +0200
@@ -277,37 +277,13 @@
         """
         cls.build___select__()
         cls.vreg = registry.vreg
-        cls.register_properties()
-        return cls
-
-    @classmethod
-    def vreg_initialization_completed(cls):
-        pass
-
-    # properties definition:
-    # key: id of the property (the actual CWProperty key is build using
-    #      <registry name>.<obj id>.<property id>
-    # value: tuple (property type, vocabfunc, default value, property description)
-    #        possible types are those used by `logilab.common.configuration`
-    #
-    # notice that when it exists multiple objects with the same id (adaptation,
-    # overriding) only the first encountered definition is considered, so those
-    # objects can't try to have different default values for instance.
-
-    property_defs = {}
-
-    @classmethod
-    def register_properties(cls):
-        for propid, pdef in cls.property_defs.items():
+        pdefs = getattr(cls, 'cw_property_defs', {})
+        for propid, pdef in pdefs.items():
             pdef = pdef.copy() # may be shared
             pdef['default'] = getattr(cls, propid, pdef['default'])
             pdef['sitewide'] = getattr(cls, 'site_wide', pdef.get('sitewide'))
-            cls.vreg.register_property(cls.propkey(propid), **pdef)
-
-    @classmethod
-    def propkey(cls, propid):
-        return '%s.%s.%s' % (cls.__registry__, cls.id, propid)
-
+            registry.vreg.register_property(cls._cwpropkey(propid), **pdef)
+        return cls
 
     def __init__(self, req=None, rset=None, row=None, col=None, **extra):
         super(AppObject, self).__init__()
@@ -317,16 +293,43 @@
         self.col = col
         self.extra_kwargs = extra
 
-    def propval(self, propid):
-        assert self.req
-        return self.req.property_value(self.propkey(propid))
-
     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[__registry].render(__vid, self.req, __fallback_oid,
                                             rset=rset, **kwargs)
 
+    # persistent class properties ##############################################
+    #
+    # optional `cw_property_defs` dict on a class defines available persistent
+    # properties for this class:
+    #
+    # * key: id of the property (the actual CWProperty key is build using
+    #        <registry name>.<obj id>.<property id>
+    # * value: tuple (property type, vocabfunc, default value, property description)
+    #         possible types are those used by `logilab.common.configuration`
+    #
+    # notice that when it exists multiple objects with the same id (adaptation,
+    # overriding) only the first encountered definition is considered, so those
+    # objects can't try to have different default values for instance.
+    #
+    # you can then access to a property value using self.propval, where self is
+    # an instance of class
+
+    @classmethod
+    def _cwpropkey(cls, propid):
+        """return cw property key for the property of the given id for this
+        class
+        """
+        return '%s.%s.%s' % (cls.__registry__, cls.id, propid)
+
+    def cw_propval(self, propid):
+        """return cw property value associated to key
+
+        <cls.__registry__>.<cls.id>.<propid>
+        """
+        return self.req.property_value(self._cwpropkey(propid))
+
     # deprecated ###############################################################
 
     @classproperty
@@ -339,15 +342,20 @@
             selector = (selector,)
         return selector
 
-    @classmethod
-    @deprecated('[3.5] use vreg.schema')
-    def schema(cls):
-        return cls.vreg.schema
+    @property
+    @deprecated('[3.5] use req.vreg')
+    def vreg(self):
+        return self.req.vreg
 
-    @classmethod
-    @deprecated('[3.5] use vreg.config')
-    def schema(cls):
-        return cls.vreg.config
+    @property
+    @deprecated('[3.5] use req.vreg.schema')
+    def schema(self):
+        return self.req.vreg.schema
+
+    @property
+    @deprecated('[3.5] use req.vreg.config')
+    def config(self):
+        return self.req.vreg.config
 
     @deprecated('[3.5] use req.varmaker')
     def initialize_varmaker(self):
@@ -397,4 +405,8 @@
     def parse_datetime(self, value, etype='Datetime'):
         return self.req.parse_datetime(value, etype)
 
+    @deprecated('[3.5] use self.cw_propval')
+    def propval(self, propid):
+        return self.req.property_value(self._cwpropkey(propid))
+
 set_log_methods(AppObject, getLogger('cubicweb.appobject'))
--- a/common/uilib.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/common/uilib.py	Thu Aug 13 11:07:25 2009 +0200
@@ -12,7 +12,6 @@
 
 import csv
 import re
-from urllib import quote as urlquote
 from StringIO import StringIO
 
 from logilab.mtconverter import xml_escape, html_unescape
--- a/cwvreg.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/cwvreg.py	Thu Aug 13 11:07:25 2009 +0200
@@ -50,11 +50,7 @@
         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()
+        pass
 
     @deprecated('[3.5] select object, then use obj.render()')
     def render(self, __oid, req, __fallback_oid=None, rset=None, **kwargs):
@@ -143,11 +139,11 @@
             assert len(objects) == 1, objects
             cls = objects[0]
         if cls.id == etype:
-            cls.__initialize__()
+            cls.__initialize__(self.schema)
             return cls
         cls = dump_class(cls, etype)
         cls.id = etype
-        cls.__initialize__()
+        cls.__initialize__(self.schema)
         return cls
 
 VRegistry.REGISTRY_FACTORY['etypes'] = ETypeRegistry
--- a/devtools/devctl.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/devtools/devctl.py	Thu Aug 13 11:07:25 2009 +0200
@@ -205,7 +205,7 @@
                 objid = '%s_%s' % (reg, obj.id)
                 if objid in done:
                     break
-                if obj.property_defs:
+                if obj.cw_property_defs:
                     yield objid
                     done.add(objid)
                     break
--- a/entity.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/entity.py	Thu Aug 13 11:07:25 2009 +0200
@@ -170,13 +170,13 @@
     MODE_TAGS = set(('link', 'create'))
     CATEGORY_TAGS = set(('primary', 'secondary', 'generic', 'generated')) # , 'metadata'))
     @classmethod
-    def __initialize__(cls):
+    def __initialize__(cls, schema):
         """initialize a specific entity class by adding descriptors to access
         entity type's attributes and relations
         """
         etype = cls.id
         assert etype != 'Any', etype
-        cls.e_schema = eschema = cls.schema.eschema(etype)
+        cls.e_schema = eschema = schema.eschema(etype)
         for rschema, _ in eschema.attribute_definitions():
             if rschema.type == 'eid':
                 continue
--- a/req.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/req.py	Thu Aug 13 11:07:25 2009 +0200
@@ -7,6 +7,7 @@
 """
 __docformat__ = "restructuredtext en"
 
+from urllib import quote as urlquote, unquote as urlunquote
 from datetime import time, datetime, timedelta
 
 from logilab.common.decorators import cached
--- a/server/hooksmanager.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/server/hooksmanager.py	Thu Aug 13 11:07:25 2009 +0200
@@ -90,7 +90,7 @@
         class.
         """
         if isinstance(function_or_cls, type) and issubclass(function_or_cls, Hook):
-            for event, ertype in function_or_cls.register_to():
+            for event, ertype in function_or_cls.register_to(self.schema):
                 for hook in self._hooks[event][ertype]:
                     if getattr(hook, 'im_self', None).__class__ is function_or_cls:
                         self._hooks[event][ertype].remove(hook)
@@ -222,7 +222,7 @@
         return cls()
 
     @classmethod
-    def register_to(cls):
+    def register_to(cls, schema):
         if not cls.enabled:
             cls.warning('%s hook has been disabled', cls)
             return
@@ -241,7 +241,7 @@
                 yield event, ertype
                 done.add((event, ertype))
                 try:
-                    eschema = cls.schema.eschema(ertype)
+                    eschema = schema.eschema(ertype)
                 except KeyError:
                     # relation schema
                     pass
--- a/server/serverconfig.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/server/serverconfig.py	Thu Aug 13 11:07:25 2009 +0200
@@ -263,7 +263,9 @@
         except RegistryNotFound:
             return hooks
         for hookdef in apphookdefs:
-            for event, ertype in hookdef.register_to():
+            # XXX < 3.5 bw compat
+            hookdef.__dict__['config'] = self
+            for event, ertype in hookdef.register_to(vreg.schema):
                 if ertype == 'Any':
                     ertype = ''
                 cb = hookdef.make_callback(event)
--- a/server/test/unittest_hooksmanager.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/server/test/unittest_hooksmanager.py	Thu Aug 13 11:07:25 2009 +0200
@@ -170,7 +170,7 @@
 
 class HookTC(CubicWebTC):
     def test_inheritance(self):
-        self.assertEquals(list(MyHook.register_to()),
+        self.assertEquals(list(MyHook.register_to(self.schema)),
                           zip(repeat('whatever'), ('Societe', 'Division', 'SubDivision'))
                           + zip(repeat('another'), ('Societe', 'Division', 'SubDivision')))
 
--- a/sobjects/supervising.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/sobjects/supervising.py	Thu Aug 13 11:07:25 2009 +0200
@@ -23,7 +23,7 @@
     accepts = ('Any',)
 
     def call(self, session, *args):
-        dest = self.config['supervising-addrs']
+        dest = session.vreg.config['supervising-addrs']
         if not dest: # no supervisors, don't do this for nothing...
             return
         self.session = session
--- a/view.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/view.py	Thu Aug 13 11:07:25 2009 +0200
@@ -479,7 +479,6 @@
     """base class for components"""
     __registry__ = 'components'
     __select__ = yes()
-    property_defs = {}
 
     def div_class(self):
         return '%s %s' % (self.propval('htmlclass'), self.id)
--- a/web/__init__.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/__init__.py	Thu Aug 13 11:07:25 2009 +0200
@@ -13,10 +13,10 @@
 from decimal import Decimal
 from datetime import datetime, date, timedelta
 from simplejson import dumps
+from urllib import quote as urlquote
 
 from logilab.common.deprecation import deprecated
 
-from cubicweb.common.uilib import urlquote
 from cubicweb.web._exceptions import *
 
 
--- a/web/action.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/action.py	Thu Aug 13 11:07:25 2009 +0200
@@ -22,7 +22,7 @@
     __registry__ = 'actions'
     __select__ = match_search_state('normal')
 
-    property_defs = {
+    cw_property_defs = {
         'visible':  dict(type='Boolean', default=True,
                          help=_('display the action or not')),
         'order':    dict(type='Int', default=99,
--- a/web/box.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/box.py	Thu Aug 13 11:07:25 2009 +0200
@@ -42,7 +42,7 @@
     registered = classmethod(require_group_compat(View.registered))
 
     categories_in_order = ()
-    property_defs = {
+    cw_property_defs = {
         _('visible'): dict(type='Boolean', default=True,
                            help=_('display the box or not')),
         _('order'):   dict(type='Int', default=99,
--- a/web/component.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/component.py	Thu Aug 13 11:07:25 2009 +0200
@@ -35,7 +35,7 @@
     __select__ = one_line_rset() & primary_view() & match_context_prop()
     registered = accepts_compat(has_relation_compat(condition_compat(View.registered)))
 
-    property_defs = {
+    cw_property_defs = {
         _('visible'):  dict(type='Boolean', default=True,
                             help=_('display the component or not')),
         _('order'):    dict(type='Int', default=99,
@@ -63,7 +63,7 @@
     id = 'navigation'
     __select__ = paginated_rset()
 
-    property_defs = {
+    cw_property_defs = {
         _('visible'):  dict(type='Boolean', default=True,
                             help=_('display the component or not')),
         }
--- a/web/facet.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/facet.py	Thu Aug 13 11:07:25 2009 +0200
@@ -244,7 +244,7 @@
 class AbstractFacet(AppObject):
     __abstract__ = True
     __registry__ = 'facets'
-    property_defs = {
+    cw_property_defs = {
         _('visible'): dict(type='Boolean', default=True,
                            help=_('display the box or not')),
         _('order'):   dict(type='Int', default=99,
--- a/web/request.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/request.py	Thu Aug 13 11:07:25 2009 +0200
@@ -89,7 +89,7 @@
         self.datadir_url = self._datadir_url()
 
     @property
-    def varmaker(self)
+    def varmaker(self):
         varmaker = self.get_page_data('rql_varmaker')
         if varmaker is None:
             varmaker = rqlvar_maker()
--- a/web/uicfg.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/uicfg.py	Thu Aug 13 11:07:25 2009 +0200
@@ -69,7 +69,7 @@
 
 from cubicweb import neg_role, onevent
 from cubicweb.rtags import (RelationTags, RelationTagsBool,
-                            RelationTagsSet, RelationTagsDict)
+                            RelationTagsSet, RelationTagsDict, register_rtag)
 from cubicweb.web import formwidgets
 
 
@@ -151,12 +151,25 @@
 # * 'schema'
 # * 'subobject' (not displayed by default)
 
-indexview_etype_section = {'EmailAddress': 'subobject',
-                           'CWUser': 'system',
-                           'CWGroup': 'system',
-                           'CWPermission': 'system',
-                           }
+class InitializableDict(dict):
+    def __init__(self, *args, **kwargs):
+        super(InitializableDict, self).__init__(*args, **kwargs)
+        register_rtag(self)
 
+    def init(self, schema, check=True):
+        for eschema in schema.entities():
+            if eschema.schema_entity():
+                self.setdefault(eschema, 'schema')
+            elif eschema.is_subobject(strict=True):
+                self.setdefault(eschema, 'subobject')
+            else:
+                self.setdefault(eschema, 'application')
+
+indexview_etype_section = InitializableDict(EmailAddress='subobject',
+                                            CWUser='system',
+                                            CWGroup='system',
+                                            CWPermission='system',
+                                            )
 
 # autoform.AutomaticEntityForm configuration ##################################
 
--- a/web/views/ajaxedit.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/views/ajaxedit.py	Thu Aug 13 11:07:25 2009 +0200
@@ -21,7 +21,7 @@
     __registry__ = 'views'
     __select__ = (match_form_params('rtype', 'target')
                   | match_kwargs('rtype', 'target'))
-    property_defs = {} # don't want to inherit this from Box
+    cw_property_defs = {} # don't want to inherit this from Box
     id = 'xaddrelation'
     expected_kwargs = form_params = ('rtype', 'target')
 
--- a/web/views/basecomponents.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/views/basecomponents.py	Thu Aug 13 11:07:25 2009 +0200
@@ -29,7 +29,7 @@
 class RQLInputForm(component.Component):
     """build the rql input form, usually displayed in the header"""
     id = 'rqlinput'
-    property_defs = VISIBLE_PROP_DEF
+    cw_property_defs = VISIBLE_PROP_DEF
     visible = False
 
     def call(self, view=None):
@@ -59,7 +59,7 @@
 class ApplLogo(component.Component):
     """build the instance logo, usually displayed in the header"""
     id = 'logo'
-    property_defs = VISIBLE_PROP_DEF
+    cw_property_defs = VISIBLE_PROP_DEF
     # don't want user to hide this component using an cwproperty
     site_wide = True
 
@@ -71,7 +71,7 @@
 class ApplHelp(component.Component):
     """build the help button, usually displayed in the header"""
     id = 'help'
-    property_defs = VISIBLE_PROP_DEF
+    cw_property_defs = VISIBLE_PROP_DEF
     def call(self):
         self.w(u'<a href="%s" class="help" title="%s">&nbsp;</a>'
                % (self.build_url(_restpath='doc/main'),
@@ -82,7 +82,7 @@
     """if the user is the anonymous user, build a link to login
     else a link to the connected user object with a loggout link
     """
-    property_defs = VISIBLE_PROP_DEF
+    cw_property_defs = VISIBLE_PROP_DEF
     # don't want user to hide this component using an cwproperty
     site_wide = True
     id = 'loggeduserlink'
@@ -124,7 +124,7 @@
     __select__ = yes()
     id = 'applmessages'
     # don't want user to hide this component using an cwproperty
-    property_defs = {}
+    cw_property_defs = {}
 
     def call(self):
         msgs = [msg for msg in (self.req.get_shared_data('sources_error', pop=True),
@@ -140,7 +140,7 @@
 class ApplicationName(component.Component):
     """display the instance name"""
     id = 'appliname'
-    property_defs = VISIBLE_PROP_DEF
+    cw_property_defs = VISIBLE_PROP_DEF
     # don't want user to hide this component using an cwproperty
     site_wide = True
 
@@ -170,7 +170,7 @@
     id = 'etypenavigation'
     __select__ = two_etypes_rset() | match_form_params('__restrtype', '__restrtypes',
                                                        '__restrrql')
-    property_defs = VISIBLE_PROP_DEF
+    cw_property_defs = VISIBLE_PROP_DEF
     # don't want user to hide this component using an cwproperty
     site_wide = True
     visible = False # disabled by default
--- a/web/views/embedding.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/views/embedding.py	Thu Aug 13 11:07:25 2009 +0200
@@ -12,10 +12,10 @@
 import re
 from urlparse import urljoin
 from urllib2 import urlopen, Request, HTTPError
+from urllib import quote as urlquote # XXX should use view.url_quote method
 
 from logilab.mtconverter import guess_encoding
 
-from cubicweb import urlquote # XXX should use view.url_quote method
 from cubicweb.selectors import (one_line_rset, score_entity,
                                 match_search_state, implements)
 from cubicweb.interfaces import IEmbedable
--- a/web/views/startup.py	Thu Aug 13 11:01:32 2009 +0200
+++ b/web/views/startup.py	Thu Aug 13 11:07:25 2009 +0200
@@ -22,16 +22,6 @@
     title = _('manage')
     http_cache_manager = httpcache.EtagHTTPCacheManager
 
-    @classmethod
-    def vreg_initialization_completed(cls):
-        for eschema in cls.schema.entities():
-            if eschema.schema_entity():
-                uicfg.indexview_etype_section.setdefault(eschema, 'schema')
-            elif eschema.is_subobject(strict=True):
-                uicfg.indexview_etype_section.setdefault(eschema, 'subobject')
-            else:
-                uicfg.indexview_etype_section.setdefault(eschema, 'application')
-
     def display_folders(self):
         return False