cwvreg.py
author sylvain.thenault@logilab.fr
Tue, 12 May 2009 18:15:49 +0200
branchtls-sprint
changeset 1752 4b0b912ff5b7
parent 1723 30c3a713ab61
child 1769 fb91d2b8a441
permissions -rw-r--r--
fix rtags initialization: do it at the registry level to avoid multiple initialization of the same rtag
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""extend the generic VRegistry with some cubicweb specific stuff
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
:organization: Logilab
1123
a8e2838f174a catch UnknownEid and set empty solutions on select nodes
sylvain.thenault@logilab.fr
parents: 395
diff changeset
     4
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     6
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
from logilab.common.decorators import cached, clear_cache
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
from rql import RQLHelper
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    12
1123
a8e2838f174a catch UnknownEid and set empty solutions on select nodes
sylvain.thenault@logilab.fr
parents: 395
diff changeset
    13
from cubicweb import Binary, UnknownProperty, UnknownEid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
from cubicweb.vregistry import VRegistry, ObjectNotFound, NoSelectableObject
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
_ = unicode
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    17
776
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    18
def use_interfaces(obj):
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1044
diff changeset
    19
    """return interfaces used by the given object by searchinf for implements
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1044
diff changeset
    20
    selectors, with a bw compat fallback to accepts_interfaces attribute
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1044
diff changeset
    21
    """
776
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    22
    from cubicweb.selectors import implements
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    23
    try:
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    24
        # XXX deprecated
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
    25
        return sorted(obj.accepts_interfaces)
776
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    26
    except AttributeError:
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    27
        try:
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    28
            impl = obj.__select__.search_selector(implements)
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    29
            if impl:
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    30
                return sorted(impl.expected_ifaces)
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    31
        except AttributeError:
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    32
            pass # old-style vobject classes with no accepts_interfaces
1044
3672a7c86784 print message to help debugging selector on error
sylvain.thenault@logilab.fr
parents: 1037
diff changeset
    33
        except:
3672a7c86784 print message to help debugging selector on error
sylvain.thenault@logilab.fr
parents: 1037
diff changeset
    34
            print 'bad selector %s on %s' % (obj.__select__, obj)
3672a7c86784 print message to help debugging selector on error
sylvain.thenault@logilab.fr
parents: 1037
diff changeset
    35
            raise
776
29ba95ea7e7d no more used
sylvain.thenault@logilab.fr
parents: 717
diff changeset
    36
        return ()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
class CubicWebRegistry(VRegistry):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
    """extend the generic VRegistry with some cubicweb specific stuff"""
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
    41
169
0e031b66cb0b don't systematically init_log, it may breaks client log configuration
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
    42
    def __init__(self, config, debug=None, initlog=True):
0e031b66cb0b don't systematically init_log, it may breaks client log configuration
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
    43
        if initlog:
0e031b66cb0b don't systematically init_log, it may breaks client log configuration
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
    44
            # first init log service
0e031b66cb0b don't systematically init_log, it may breaks client log configuration
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
    45
            config.init_log(debug=debug)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
        super(CubicWebRegistry, self).__init__(config)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
        self.schema = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
        self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
        self.initialized = False
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
    50
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
    def items(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
        return [item for item in self._registries.items()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
                if not item[0] in ('propertydefs', 'propertyvalues')]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
    def values(self):
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1044
diff changeset
    56
        return [value for key, value in self._registries.items()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
                if not key in ('propertydefs', 'propertyvalues')]
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
    58
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
    def reset(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
        self._registries = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        self._lastmodifs = {}
666
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    62
        self._needs_iface = {}
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    63
        # two special registries, propertydefs which care all the property
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    64
        # definitions, and propertyvals which contains values for those
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    65
        # properties
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
        self._registries['propertydefs'] = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
        self._registries['propertyvalues'] = self.eprop_values = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
        for key, propdef in self.config.eproperty_definitions():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
            self.register_property(key, **propdef)
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
    70
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
    def set_schema(self, schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
        """set application'schema and load application objects"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
        self.schema = schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        clear_cache(self, 'rqlhelper')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        # now we can load application's web objects
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
        self.register_objects(self.config.vregistry_path())
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
    77
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
    def update_schema(self, schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
        """update .schema attribute on registered objects, necessary for some
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
        tests
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
        self.schema = schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
        for registry, regcontent in self._registries.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
            if registry in ('propertydefs', 'propertyvalues'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
            for objects in regcontent.values():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
                for obj in objects:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
                    obj.schema = schema
666
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    89
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    90
    def register_if_interface_found(self, obj, ifaces, **kwargs):
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    91
        """register an object but remove it if no entity class implements one of
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    92
        the given interfaces
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    93
        """
785
e4f9fa3c891a more iface based cleanup fixes
sylvain.thenault@logilab.fr
parents: 777
diff changeset
    94
        self.register(obj, **kwargs)
666
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    95
        if not isinstance(ifaces,  (tuple, list)):
785
e4f9fa3c891a more iface based cleanup fixes
sylvain.thenault@logilab.fr
parents: 777
diff changeset
    96
            self._needs_iface[obj] = (ifaces,)
666
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    97
        else:
785
e4f9fa3c891a more iface based cleanup fixes
sylvain.thenault@logilab.fr
parents: 777
diff changeset
    98
            self._needs_iface[obj] = ifaces
666
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    99
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   100
    def register(self, obj, **kwargs):
717
54b873918b48 kill id_registerer
sylvain.thenault@logilab.fr
parents: 666
diff changeset
   101
        if kwargs.get('registryname', obj.__registry__) == 'etypes':
1037
1f3fae8d82b2 don't fail if vobjects reference an unexistant class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   102
            if obj.id != 'Any' and not obj.id in self.schema:
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1044
diff changeset
   103
                self.error('don\'t register %s, %s type not defined in the '
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1044
diff changeset
   104
                           'schema', obj, obj.id)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
                return
717
54b873918b48 kill id_registerer
sylvain.thenault@logilab.fr
parents: 666
diff changeset
   106
            kwargs['clear'] = True
666
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   107
        super(CubicWebRegistry, self).register(obj, **kwargs)
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   108
        # XXX bw compat
777
39695e98ba35 test and fix interface based objects cleaning
sylvain.thenault@logilab.fr
parents: 776
diff changeset
   109
        ifaces = use_interfaces(obj)
666
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   110
        if ifaces:
785
e4f9fa3c891a more iface based cleanup fixes
sylvain.thenault@logilab.fr
parents: 777
diff changeset
   111
            self._needs_iface[obj] = ifaces
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   112
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
    def register_objects(self, path, force_reload=None):
666
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   114
        """overriden to remove objects requiring a missing interface"""
8ad9885ea45a interface handling should be done here
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   115
        if super(CubicWebRegistry, self).register_objects(path, force_reload):
1638
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   116
            self.initialization_completed()
1752
4b0b912ff5b7 fix rtags initialization: do it at the registry level to avoid multiple initialization of the same rtag
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   117
            # call vreg_initialization_completed on appobjects and print
4b0b912ff5b7 fix rtags initialization: do it at the registry level to avoid multiple initialization of the same rtag
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   118
            # registry content
1282
272d8ec6f308 * print vreg content once fully initialized (require move of print code from vregistry to cwvreg)
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   119
            for registry, objects in self.items():
272d8ec6f308 * print vreg content once fully initialized (require move of print code from vregistry to cwvreg)
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   120
                self.debug('available in registry %s: %s', registry,
272d8ec6f308 * print vreg content once fully initialized (require move of print code from vregistry to cwvreg)
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   121
                           sorted(objects))
272d8ec6f308 * print vreg content once fully initialized (require move of print code from vregistry to cwvreg)
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   122
                for appobjects in objects.itervalues():
272d8ec6f308 * print vreg content once fully initialized (require move of print code from vregistry to cwvreg)
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   123
                    for appobject in appobjects:
272d8ec6f308 * print vreg content once fully initialized (require move of print code from vregistry to cwvreg)
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   124
                        appobject.vreg_initialization_completed()
1752
4b0b912ff5b7 fix rtags initialization: do it at the registry level to avoid multiple initialization of the same rtag
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   125
            from cubicweb.rtags import RTAGS
4b0b912ff5b7 fix rtags initialization: do it at the registry level to avoid multiple initialization of the same rtag
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   126
            for rtag in RTAGS:
4b0b912ff5b7 fix rtags initialization: do it at the registry level to avoid multiple initialization of the same rtag
sylvain.thenault@logilab.fr
parents: 1723
diff changeset
   127
                rtag.init(self.schema)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
1638
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   129
    def initialization_completed(self):
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   130
        # clear etype cache if you don't want to run into deep weirdness
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   131
        clear_cache(self, 'etype_class')
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   132
        # we may want to keep interface dependent objects (e.g.for i18n
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   133
        # catalog generation)
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   134
        if self.config.cleanup_interface_sobjects:
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   135
            # remove vobjects that don't support any available interface
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   136
            implemented_interfaces = set()
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   137
            if 'Any' in self.get('etypes', ()):
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   138
                for etype in self.schema.entities():
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   139
                    cls = self.etype_class(etype)
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   140
                    for iface in cls.__implements__:
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   141
                        implemented_interfaces.update(iface.__mro__)
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   142
                    implemented_interfaces.update(cls.__mro__)
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   143
            for obj, ifaces in self._needs_iface.items():
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   144
                ifaces = frozenset(isinstance(iface, basestring)
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   145
                                   and iface in self.schema
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   146
                                   and self.etype_class(iface)
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   147
                                   or iface
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   148
                                   for iface in ifaces)
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   149
                if not ('Any' in ifaces or ifaces & implemented_interfaces):
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   150
                    self.debug('kicking vobject %s (no implemented '
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   151
                               'interface among %s)', obj, ifaces)
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   152
                    self.unregister(obj)
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   153
        # clear needs_iface so we don't try to remove some not-anymore-in
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   154
        # objects on automatic reloading
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   155
        self._needs_iface.clear()
6f9003a32ecc extract method
sylvain.thenault@logilab.fr
parents: 1513
diff changeset
   156
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
    def etype_class(self, etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
        """return an entity class for the given entity type.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
        Try to find out a specific class for this kind of entity or
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
        default to a dump of the class registered for 'Any'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
        etype = str(etype)
631
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   164
        if etype == 'Any':
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   165
            return self.select(self.registry_objects('etypes', 'Any'), 'Any')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
        eschema = self.schema.eschema(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
        baseschemas = [eschema] + eschema.ancestors()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
        # browse ancestors from most specific to most generic and
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
        # try to find an associated custom entity class
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
        for baseschema in baseschemas:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
            btype = str(baseschema)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
            try:
631
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   173
                cls = self.select(self.registry_objects('etypes', btype), etype)
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   174
                break
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
            except ObjectNotFound:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
                pass
631
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   177
        else:
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   178
            # no entity class for any of the ancestors, fallback to the default
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   179
            # one
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   180
            cls = self.select(self.registry_objects('etypes', 'Any'), etype)
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   181
        return cls
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
    def render(self, registry, oid, req, **context):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
        """select an object in a given registry and render it
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
        - registry: the registry's name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
        - oid : the view to call
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   188
        - req : the HTTP request
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
        objclss = self.registry_objects(registry, oid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
            rset = context.pop('rset')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
            rset = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
        selected = self.select(objclss, req, rset, **context)
1723
30c3a713ab61 View.dispatch -> View.render
sylvain.thenault@logilab.fr
parents: 1641
diff changeset
   196
        return selected.render(**context)
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   197
823
cb8ccbef8fa5 main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 816
diff changeset
   198
    def main_template(self, req, oid='main-template', **context):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        """display query by calling the given template (default to main),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
        and returning the output as a string instead of requiring the [w]rite
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
        method as argument
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
        """
816
9cd49a910fce kill Template class and 'templates' registry
sylvain.thenault@logilab.fr
parents: 785
diff changeset
   203
        res = self.render('views', oid, req, **context)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
        if isinstance(res, unicode):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
            return res.encode(req.encoding)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
        assert isinstance(res, str)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
        return res
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
    def possible_vobjects(self, registry, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        """return an ordered list of possible app objects in a given registry,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        supposing they support the 'visible' and 'order' properties (as most
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
        visualizable objects)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
        return [x for x in sorted(self.possible_objects(registry, *args, **kwargs),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
                                  key=lambda x: x.propval('order'))
213
6842c3dee34b adding files (formely appearing in jpl) specific to cubicweb
Laure Bourgois <Laure.Bourgois@logilab.fr>
parents: 169
diff changeset
   216
                if x.propval('visible')]
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   217
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
    def possible_actions(self, req, rset, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        if rset is None:
1381
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 1254
diff changeset
   220
            actions = self.possible_vobjects('actions', req, rset, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        else:
1381
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 1254
diff changeset
   222
            actions = rset.possible_actions(**kwargs) # cached implementation
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
        result = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
        for action in actions:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
            result.setdefault(action.category, []).append(action)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
        return result
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   227
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
    def possible_views(self, req, rset, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
        """return an iterator on possible views for this result set
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
        views returned are classes, not instances
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
        for vid, views in self.registry('views').items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
            if vid[0] == '_':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
                view = self.select(views, req, rset, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
                if view.linkable():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
                    yield view
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
            except NoSelectableObject:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
                continue
395
cce260264122 catch Exception in case there is some unexepected selector bug
sylvain.thenault@logilab.fr
parents: 355
diff changeset
   242
            except Exception:
cce260264122 catch Exception in case there is some unexepected selector bug
sylvain.thenault@logilab.fr
parents: 355
diff changeset
   243
                self.exception('error while trying to list possible %s views for %s',
cce260264122 catch Exception in case there is some unexepected selector bug
sylvain.thenault@logilab.fr
parents: 355
diff changeset
   244
                               vid, rset)
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   245
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
    def select_box(self, oid, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
        """return the most specific view according to the result set"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
            return self.select_object('boxes', oid, *args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
        except NoSelectableObject:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
    def select_action(self, oid, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
        """return the most specific view according to the result set"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
            return self.select_object('actions', oid, *args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
        except NoSelectableObject:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
            return
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   259
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
    def select_component(self, cid, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
        """return the most specific component according to the result set"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
            return self.select_object('components', cid, *args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
        except (NoSelectableObject, ObjectNotFound):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
    def select_view(self, __vid, req, rset, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
        """return the most specific view according to the result set"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
        views = self.registry_objects('views', __vid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
        return self.select(views, req, rset, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   272
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
    # properties handling #####################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   275
    def user_property_keys(self, withsitewide=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
        if withsitewide:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
            return sorted(self['propertydefs'])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   278
        return sorted(k for k, kd in self['propertydefs'].iteritems()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
                      if not kd['sitewide'])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
    def register_property(self, key, type, help, default=None, vocabulary=None,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
                          sitewide=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
        """register a given property"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
        properties = self._registries['propertydefs']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   285
        assert type in YAMS_TO_PY
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   286
        properties[key] = {'type': type, 'vocabulary': vocabulary,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
                           'default': default, 'help': help,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
                           'sitewide': sitewide}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   289
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
    def property_info(self, key):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   291
        """return dictionary containing description associated to the given
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   292
        property key (including type, defaut value, help and a site wide
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   293
        boolean)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   294
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   295
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   296
            return self._registries['propertydefs'][key]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   297
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
            if key.startswith('system.version.'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   299
                soft = key.split('.')[-1]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   300
                return {'type': 'String', 'sitewide': True,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
                        'default': None, 'vocabulary': None,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   302
                        'help': _('%s software version of the database') % soft}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   303
            raise UnknownProperty('unregistered property %r' % key)
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   304
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   305
    def property_value(self, key):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   306
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   307
            return self._registries['propertyvalues'][key]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
            return self._registries['propertydefs'][key]['default']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   310
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   311
    def typed_value(self, key, value):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   312
        """value is an unicode string, return it correctly typed. Let potential
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
        type error propagates.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
        pdef = self.property_info(key)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
            value = YAMS_TO_PY[pdef['type']](value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   318
        except (TypeError, ValueError):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
            raise ValueError(_('bad value'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   320
        vocab = pdef['vocabulary']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   321
        if vocab is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
            if callable(vocab):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
                vocab = vocab(key, None) # XXX need a req object
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
            if not value in vocab:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   325
                raise ValueError(_('unauthorized value'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
        return value
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   327
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   328
    def init_properties(self, propvalues):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
        """init the property values registry using the given set of couple (key, value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   330
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   331
        self.initialized = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   332
        values = self._registries['propertyvalues']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   333
        for key, val in propvalues:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   335
                values[key] = self.typed_value(key, val)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   336
            except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   337
                self.warning('%s (you should probably delete that property '
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
                             'from the database)', ex)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   339
            except UnknownProperty, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   340
                self.warning('%s (you should probably delete that property '
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   341
                             'from the database)', ex)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   343
    def parse(self, session, rql, args=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   344
        rqlst = self.rqlhelper.parse(rql)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   345
        def type_from_eid(eid, session=session):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   346
            return session.describe(eid)[0]
1123
a8e2838f174a catch UnknownEid and set empty solutions on select nodes
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   347
        try:
a8e2838f174a catch UnknownEid and set empty solutions on select nodes
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   348
            self.rqlhelper.compute_solutions(rqlst, {'eid': type_from_eid}, args)
a8e2838f174a catch UnknownEid and set empty solutions on select nodes
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   349
        except UnknownEid:
a8e2838f174a catch UnknownEid and set empty solutions on select nodes
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   350
            for select in rqlst.children:
a8e2838f174a catch UnknownEid and set empty solutions on select nodes
sylvain.thenault@logilab.fr
parents: 395
diff changeset
   351
                select.solutions = []
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   352
        return rqlst
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   353
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   354
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   355
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   356
    def rqlhelper(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   357
        return RQLHelper(self.schema,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
                         special_relations={'eid': 'uid', 'has_text': 'fti'})
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
169
0e031b66cb0b don't systematically init_log, it may breaks client log configuration
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
   360
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
class MulCnxCubicWebRegistry(CubicWebRegistry):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
    """special registry to be used when an application has to deal with
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   363
    connections to differents repository. This class add some additional wrapper
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   364
    trying to hide buggy class attributes since classes are not designed to be
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   365
    shared.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   366
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   367
    def etype_class(self, etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   368
        """return an entity class for the given entity type.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   369
        Try to find out a specific class for this kind of entity or
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   370
        default to a dump of the class registered for 'Any'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   371
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   372
        usercls = super(MulCnxCubicWebRegistry, self).etype_class(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   373
        usercls.e_schema = self.schema.eschema(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   374
        return usercls
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   375
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   376
    def select(self, vobjects, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   377
        """return an instance of the most specific object according
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   378
        to parameters
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   379
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
        raise NoSelectableObject if not object apply
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   381
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   382
        for vobject in vobjects:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   383
            vobject.vreg = self
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   384
            vobject.schema = self.schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
            vobject.config = self.config
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
        return super(MulCnxCubicWebRegistry, self).select(vobjects, *args, **kwargs)
1475
5c1ec97f317e should not be necessary anymore to add entity class to __implements__
sylvain.thenault@logilab.fr
parents: 1357
diff changeset
   387
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 823
diff changeset
   388
from datetime import datetime, date, time, timedelta
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   389
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
YAMS_TO_PY = {
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
    'Boolean':  bool,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   392
    'String' :  unicode,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   393
    'Password': str,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   394
    'Bytes':    Binary,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   395
    'Int':      int,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
    'Float':    float,
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 823
diff changeset
   397
    'Date':     date,
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 823
diff changeset
   398
    'Datetime': datetime,
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 823
diff changeset
   399
    'Time':     time,
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 823
diff changeset
   400
    'Interval': timedelta,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
    }
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   402