selectors.py
author Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
Wed, 23 Sep 2009 09:52:09 +0200
changeset 3393 58a62864bae4
parent 3369 7b88d12b4ee2
child 3396 fb261afd49cd
permissions -rw-r--r--
[selectors] cls.vreg is not usable anymore, use req.vreg instead
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
     1
"""This file contains some basic selectors required by application objects.
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
     2
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
     3
A selector is responsible to score how well an object may be used with a
718
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
     4
given context by returning a score.
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
     5
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
     6
In CubicWeb Usually the context consists for a request object, a result set
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
     7
or None, a specific row/col in the result set, etc...
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
     8
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
     9
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    10
If you have trouble with selectors, especially if the objet (typically
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    11
a view or a component) you want to use is not selected and you want to
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    12
know which one(s) of its selectors fail (e.g. returns 0), you can use
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    13
`traced_selection` or even direclty `TRACED_OIDS`.
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    14
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    15
`TRACED_OIDS` is a tuple of traced object ids. The special value
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    16
'all' may be used to log selectors for all objects.
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    17
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    18
For instance, say that the following code yields a `NoSelectableObject`
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    19
exception::
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    20
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    21
    self.view('calendar', myrset)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    22
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    23
You can log the selectors involved for *calendar* by replacing the line
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    24
above by::
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    25
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    26
    # in Python2.5
692
800592b8d39b replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 660
diff changeset
    27
    from cubicweb.selectors import traced_selection
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    28
    with traced_selection():
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    29
        self.view('calendar', myrset)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    30
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    31
    # in Python2.4
692
800592b8d39b replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 660
diff changeset
    32
    from cubicweb import selectors
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    33
    selectors.TRACED_OIDS = ('calendar',)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    34
    self.view('calendar', myrset)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    35
    selectors.TRACED_OIDS = ()
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
    36
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    37
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    38
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1909
diff changeset
    39
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    40
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1909
diff changeset
    41
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    42
"""
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    43
__docformat__ = "restructuredtext en"
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    44
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    45
import logging
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    46
from warnings import warn
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    47
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    48
from logilab.common.compat import all
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    49
from logilab.common.interface import implements as implements_iface
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    50
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    51
from yams import BASE_TYPES
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    52
1503
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
    53
from cubicweb import (Unauthorized, NoSelectableObject, NotAnEntity,
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
    54
                      role, typed_eid)
2657
de974465d381 [appobject] kill VObject class, move base selector classes to appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
    55
# even if not used, let yes here so it's importable through this module
de974465d381 [appobject] kill VObject class, move base selector classes to appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
    56
from cubicweb.appobject import Selector, objectify_selector, yes
2834
7df3494ae657 [vreg appobject] use class_regid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2822
diff changeset
    57
from cubicweb.vregistry import class_regid
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    58
from cubicweb.cwconfig import CubicWebConfiguration
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    59
from cubicweb.schema import split_expression
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    60
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    61
# helpers for debugging selectors
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    62
SELECTOR_LOGGER = logging.getLogger('cubicweb.selectors')
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    63
TRACED_OIDS = ()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    64
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    65
def lltrace(selector):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    66
    # don't wrap selectors if not in development mode
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    67
    if CubicWebConfiguration.mode == 'installed':
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    68
        return selector
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    69
    def traced(cls, *args, **kwargs):
752
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    70
        # /!\ lltrace decorates pure function or __call__ method, this
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    71
        #     means argument order may be different
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    72
        if isinstance(cls, Selector):
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
    73
            selname = str(cls)
752
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    74
            vobj = args[0]
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    75
        else:
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    76
            selname = selector.__name__
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    77
            vobj = cls
2834
7df3494ae657 [vreg appobject] use class_regid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2822
diff changeset
    78
        oid = class_regid(vobj)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    79
        ret = selector(cls, *args, **kwargs)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    80
        if TRACED_OIDS == 'all' or oid in TRACED_OIDS:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    81
            #SELECTOR_LOGGER.warning('selector %s returned %s for %s', selname, ret, cls)
2308
b478c3a8ad2a typos, cleanup, lighter traced seletion output
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2274
diff changeset
    82
            print '%s -> %s for %s' % (selname, ret, vobj)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    83
        return ret
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    84
    traced.__name__ = selector.__name__
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    85
    return traced
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    86
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    87
class traced_selection(object):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    88
    """selector debugging helper.
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    89
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    90
    Typical usage is :
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    91
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    92
    >>> with traced_selection():
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    93
    ...     # some code in which you want to debug selectors
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    94
    ...     # for all objects
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    95
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    96
    or
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    97
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    98
    >>> with traced_selection( ('oid1', 'oid2') ):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    99
    ...     # some code in which you want to debug selectors
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   100
    ...     # for objects with id 'oid1' and 'oid2'
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   101
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   102
    """
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   103
    def __init__(self, traced='all'):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   104
        self.traced = traced
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   105
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   106
    def __enter__(self):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   107
        global TRACED_OIDS
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   108
        TRACED_OIDS = self.traced
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   109
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   110
    def __exit__(self, exctype, exc, traceback):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   111
        global TRACED_OIDS
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   112
        TRACED_OIDS = ()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   113
        return traceback is None
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   114
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   115
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   116
def score_interface(etypesreg, cls_or_inst, cls, iface):
1907
0f3363d24239 dubious docstring; hard-to-understand function
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1784
diff changeset
   117
    """Return XXX if the give object (maybe an instance or class) implements
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   118
    the interface.
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   119
    """
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   120
    if getattr(iface, '__registry__', None) == 'etypes':
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   121
        # adjust score if the interface is an entity class
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   122
        parents = etypesreg.parent_classes(cls_or_inst.id)
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   123
        if iface is cls:
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   124
            return len(parents) + 4
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   125
        if iface is parents[-1]: # Any
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   126
            return 1
1784
f0fb914e57db already a class
sylvain.thenault@logilab.fr
parents: 1694
diff changeset
   127
        for index, basecls in enumerate(reversed(parents[:-1])):
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   128
            if iface is basecls:
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   129
                return index + 3
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   130
        return 0
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   131
    if implements_iface(cls_or_inst, iface):
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   132
        # implenting an interface takes precedence other special Any interface
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   133
        return 2
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   134
    return 0
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   135
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   136
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   137
# abstract selectors ##########################################################
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   138
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   139
class PartialSelectorMixIn(object):
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   140
    """convenience mix-in for selectors that will look into the containing
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   141
    class to find missing information.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   142
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   143
    cf. `cubicweb.web.action.LinkToEntityAction` for instance
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   144
    """
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   145
    def __call__(self, cls, *args, **kwargs):
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   146
        self.complete(cls)
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   147
        return super(PartialSelectorMixIn, self).__call__(cls, *args, **kwargs)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   148
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   149
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   150
class ImplementsMixIn(object):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   151
    """mix-in class for selectors checking implemented interfaces of something
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   152
    """
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   153
    def __init__(self, *expected_ifaces):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   154
        super(ImplementsMixIn, self).__init__()
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   155
        self.expected_ifaces = expected_ifaces
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   156
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   157
    def __str__(self):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   158
        return '%s(%s)' % (self.__class__.__name__,
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   159
                           ','.join(str(s) for s in self.expected_ifaces))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   160
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   161
    def score_interfaces(self, req, cls_or_inst, cls):
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   162
        score = 0
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   163
        etypesreg = req.vreg['etypes']
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   164
        eschema = cls_or_inst.e_schema
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   165
        for iface in self.expected_ifaces:
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   166
            if isinstance(iface, basestring):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   167
                # entity type
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   168
                try:
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   169
                    iface = etypesreg.etype_class(iface)
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   170
                except KeyError:
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   171
                    continue # entity type not in the schema
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   172
            score += score_interface(etypesreg, cls_or_inst, cls, iface)
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   173
        return score
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   174
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   175
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   176
class EClassSelector(Selector):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   177
    """abstract class for selectors working on the entity classes of the result
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   178
    set. Its __call__ method has the following behaviour:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   179
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   180
    * if row is specified, return the score returned by the score_class method
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   181
      called with the entity class found in the specified cell
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   182
    * else return the sum of score returned by the score_class method for each
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   183
      entity type found in the specified column, unless:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   184
      - `once_is_enough` is True, in which case the first non-zero score is
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   185
        returned
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   186
      - `once_is_enough` is False, in which case if score_class return 0, 0 is
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   187
        returned
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   188
    """
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   189
    def __init__(self, once_is_enough=False):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   190
        self.once_is_enough = once_is_enough
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   191
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   192
    @lltrace
2161
200481e7b156 prepare time where it won't be mandatory to give rset to select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   193
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   194
        if not rset:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   195
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   196
        score = 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   197
        if row is None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   198
            for etype in rset.column_types(col):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   199
                if etype is None: # outer join
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   200
                    continue
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   201
                escore = self.score(cls, req, etype)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   202
                if not escore and not self.once_is_enough:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   203
                    return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   204
                elif self.once_is_enough:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   205
                    return escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   206
                score += escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   207
        else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   208
            etype = rset.description[row][col]
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   209
            if etype is not None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   210
                score = self.score(cls, req, etype)
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   211
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   212
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   213
    def score(self, cls, req, etype):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   214
        if etype in BASE_TYPES:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   215
            return 0
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   216
        return self.score_class(req.vreg['etypes'].etype_class(etype), req)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   217
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   218
    def score_class(self, eclass, req):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   219
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   220
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   221
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   222
class EntitySelector(EClassSelector):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   223
    """abstract class for selectors working on the entity instances of the
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   224
    result set. Its __call__ method has the following behaviour:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   225
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   226
    * if 'entity' find in kwargs, return the score returned by the score_entity
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   227
      method for this entity
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   228
    * if row is specified, return the score returned by the score_entity method
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   229
      called with the entity instance found in the specified cell
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   230
    * else return the sum of score returned by the score_entity method for each
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   231
      entity found in the specified column, unless:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   232
      - `once_is_enough` is True, in which case the first non-zero score is
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   233
        returned
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   234
      - `once_is_enough` is False, in which case if score_class return 0, 0 is
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   235
        returned
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   236
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   237
    note: None values (resulting from some outer join in the query) are not
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   238
          considered.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   239
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   240
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   241
    @lltrace
2161
200481e7b156 prepare time where it won't be mandatory to give rset to select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   242
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   243
        if not rset and not kwargs.get('entity'):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   244
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   245
        score = 0
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   246
        if kwargs.get('entity'):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   247
            score = self.score_entity(kwargs['entity'])
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   248
        elif row is None:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   249
            col = col or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   250
            for row, rowvalue in enumerate(rset.rows):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   251
                if rowvalue[col] is None: # outer join
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   252
                    continue
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 650
diff changeset
   253
                escore = self.score(req, rset, row, col)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   254
                if not escore and not self.once_is_enough:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   255
                    return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   256
                elif self.once_is_enough:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   257
                    return escore
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   258
                score += escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   259
        else:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   260
            col = col or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   261
            etype = rset.description[row][col]
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   262
            if etype is not None: # outer join
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   263
                score = self.score(req, rset, row, col)
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   264
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   265
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   266
    def score(self, req, rset, row, col):
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   267
        try:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   268
            return self.score_entity(rset.get_entity(row, col))
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   269
        except NotAnEntity:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   270
            return 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   271
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   272
    def score_entity(self, entity):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   273
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   274
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   275
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   276
# very basic selectors ########################################################
1138
22f634977c95 make pylint happy, fix some bugs on the way
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   277
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   278
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   279
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   280
def none_rset(cls, req, rset=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   281
    """accept no result set (e.g. given rset is None)"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   282
    if rset is None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   283
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   284
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   285
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   286
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   287
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   288
def any_rset(cls, req, rset=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   289
    """accept result set, whatever the number of result it contains"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   290
    if rset is not None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   291
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   292
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   293
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   294
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   295
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   296
def nonempty_rset(cls, req, rset=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   297
    """accept any non empty result set"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   298
    if rset is not None and rset.rowcount:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   299
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   300
    return 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   301
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   302
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   303
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   304
def empty_rset(cls, req, rset=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   305
    """accept empty result set"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   306
    if rset is not None and rset.rowcount == 0:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   307
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   308
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   309
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   310
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   311
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   312
def one_line_rset(cls, req, rset=None, row=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   313
    """if row is specified, accept result set with a single line of result,
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   314
    else accepts anyway
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   315
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   316
    if rset is not None and (row is not None or rset.rowcount == 1):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   317
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   318
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   319
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   320
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   321
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   322
def two_lines_rset(cls, req, rset=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   323
    """accept result set with *at least* two lines of result"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   324
    if rset is not None and rset.rowcount > 1:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   325
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   326
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   327
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   328
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   329
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   330
def two_cols_rset(cls, req, rset=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   331
    """accept result set with at least one line and two columns of result"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   332
    if rset is not None and rset.rowcount and len(rset.rows[0]) > 1:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   333
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   334
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   335
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   336
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   337
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   338
def paginated_rset(cls, req, rset=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   339
    """accept result set with more lines than the page size.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   340
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   341
    Page size is searched in (respecting order):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   342
    * a page_size argument
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   343
    * a page_size form parameters
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   344
    * the navigation.page-size property
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   345
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   346
    page_size = kwargs.get('page_size')
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   347
    if page_size is None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   348
        page_size = req.form.get('page_size')
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   349
        if page_size is None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   350
            page_size = req.property_value('navigation.page-size')
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   351
        else:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   352
            page_size = int(page_size)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   353
    if rset is None or rset.rowcount <= page_size:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   354
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   355
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   356
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   357
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   358
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   359
def sorted_rset(cls, req, rset=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   360
    """accept sorted result set"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   361
    rqlst = rset.syntax_tree()
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   362
    if len(rqlst.children) > 1 or not rqlst.children[0].orderby:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   363
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   364
    return 2
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   365
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   366
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   367
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   368
def one_etype_rset(cls, req, rset=None, col=0, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   369
    """accept result set where entities in the specified column (or 0) are all
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   370
    of the same type
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   371
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   372
    if rset is None:
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   373
        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   374
    if len(rset.column_types(col)) != 1:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   375
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   376
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   377
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   378
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   379
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   380
def two_etypes_rset(cls, req, rset=None, col=0, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   381
    """accept result set where entities in the specified column (or 0) are not
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   382
    of the same type
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   383
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   384
    if rset:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   385
        etypes = rset.column_types(col)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   386
        if len(etypes) > 1:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   387
            return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   388
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   389
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   390
class non_final_entity(EClassSelector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   391
    """accept if entity type found in the result set is non final.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   392
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   393
    See `EClassSelector` documentation for behaviour when row is not specified.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   394
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   395
    def score(self, cls, req, etype):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   396
        if etype in BASE_TYPES:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   397
            return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   398
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   399
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   400
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   401
@lltrace
828
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   402
def authenticated_user(cls, req, *args, **kwargs):
1492
sylvain.thenault@logilab.fr
parents: 1474
diff changeset
   403
    """accept if user is authenticated"""
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   404
    if req.cnx.anonymous_connection:
828
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   405
        return 0
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   406
    return 1
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   407
828
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   408
def anonymous_user():
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   409
    return ~ authenticated_user()
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   410
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   411
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   412
@lltrace
2161
200481e7b156 prepare time where it won't be mandatory to give rset to select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   413
def primary_view(cls, req, rset=None, row=None, col=0, view=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   414
    """accept if view given as named argument is a primary view, or if no view
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   415
    is given
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   416
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   417
    if view is not None and not view.is_primary():
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   418
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   419
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   420
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   421
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   422
@lltrace
2161
200481e7b156 prepare time where it won't be mandatory to give rset to select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   423
def match_context_prop(cls, req, rset=None, row=None, col=0, context=None,
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   424
                       **kwargs):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   425
    """accept if:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   426
    * no context given
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   427
    * context (`basestring`) is matching the context property value for the
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   428
      given cls
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   429
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   430
    propval = req.property_value('%s.%s.context' % (cls.__registry__, cls.id))
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   431
    if not propval:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   432
        propval = cls.context
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   433
    if context is not None and propval and context != propval:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   434
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   435
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   436
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   437
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   438
class match_search_state(Selector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   439
    """accept if the current request search state is in one of the expected
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   440
    states given to the initializer
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   441
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   442
    :param expected: either 'normal' or 'linksearch' (eg searching for an
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   443
                     object to create a relation with another)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   444
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   445
    def __init__(self, *expected):
774
48cb1f42e79c tell on which class the assertion's failed
sylvain.thenault@logilab.fr
parents: 770
diff changeset
   446
        assert expected, self
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   447
        self.expected = frozenset(expected)
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   448
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   449
    def __str__(self):
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   450
        return '%s(%s)' % (self.__class__.__name__,
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   451
                           ','.join(sorted(str(s) for s in self.expected)))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   452
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   453
    @lltrace
2161
200481e7b156 prepare time where it won't be mandatory to give rset to select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   454
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   455
        try:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   456
            if not req.search_state[0] in self.expected:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   457
                return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   458
        except AttributeError:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   459
            return 1 # class doesn't care about search state, accept it
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   460
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   461
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   462
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   463
class match_form_params(match_search_state):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   464
    """accept if parameters specified as initializer arguments are specified
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   465
    in request's form parameters
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   466
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   467
    :param *expected: parameters (eg `basestring`) which are expected to be
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   468
                      found in request's form parameters
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   469
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   470
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   471
    @lltrace
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   472
    def __call__(self, cls, req, *args, **kwargs):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   473
        score = 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   474
        for param in self.expected:
2254
f632b06058c4 fix match_form_params according to docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2161
diff changeset
   475
            if not param in req.form:
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   476
                return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   477
            score += 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   478
        return len(self.expected)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   479
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   480
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   481
class match_kwargs(match_search_state):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   482
    """accept if parameters specified as initializer arguments are specified
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   483
    in named arguments given to the selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   484
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   485
    :param *expected: parameters (eg `basestring`) which are expected to be
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   486
                      found in named arguments (kwargs)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   487
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   488
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   489
    @lltrace
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   490
    def __call__(self, cls, req, *args, **kwargs):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   491
        for arg in self.expected:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   492
            if not arg in kwargs:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   493
                return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   494
        return len(self.expected)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   495
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   496
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   497
class match_user_groups(match_search_state):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   498
    """accept if logged users is in at least one of the given groups. Returned
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   499
    score is the number of groups in which the user is.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   500
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   501
    If the special 'owners' group is given:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   502
    * if row is specified check the entity at the given row/col is owned by the
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   503
      logged user
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   504
    * if row is not specified check all entities in col are owned by the logged
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   505
      user
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   506
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   507
    :param *required_groups: name of groups (`basestring`) in which the logged
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   508
                             user should be
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   509
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   510
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   511
    @lltrace
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   512
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   513
        user = req.user
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   514
        if user is None:
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   515
            return int('guests' in self.expected)
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   516
        score = user.matching_groups(self.expected)
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   517
        if not score and 'owners' in self.expected and rset:
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   518
            if row is not None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   519
                if not user.owns(rset[row][col]):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   520
                    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   521
                score = 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   522
            else:
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   523
                score = all(user.owns(r[col]) for r in rset)
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   524
        return score
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   525
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   526
1503
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   527
class match_transition(match_search_state):
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   528
    @lltrace
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   529
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   530
        try:
3350
fa77640a9155 since we have the transition entity, give it directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3346
diff changeset
   531
            # XXX check this is a transition that apply to the object?
fa77640a9155 since we have the transition entity, give it directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3346
diff changeset
   532
            if not kwargs['transition'].name in self.expected:
fa77640a9155 since we have the transition entity, give it directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3346
diff changeset
   533
                return 0
fa77640a9155 since we have the transition entity, give it directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3346
diff changeset
   534
        except KeyError:
1503
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   535
            return 0
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   536
        return 1
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   537
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   538
1263
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   539
class match_view(match_search_state):
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   540
    """accept if the current view is in one of the expected vid given to the
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   541
    initializer
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   542
    """
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   543
    @lltrace
2161
200481e7b156 prepare time where it won't be mandatory to give rset to select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   544
    def __call__(self, cls, req, rset=None, row=None, col=0, view=None, **kwargs):
1263
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   545
        if view is None or not view.id in self.expected:
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   546
            return 0
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   547
        return 1
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   548
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   549
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   550
class appobject_selectable(Selector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   551
    """accept with another appobject is selectable using selector's input
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   552
    context.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   553
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   554
    :param registry: a registry name (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   555
    :param oid: an object identifier (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   556
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   557
    def __init__(self, registry, oid):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   558
        self.registry = registry
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   559
        self.oid = oid
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   560
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2613
diff changeset
   561
    def __call__(self, cls, req, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   562
        try:
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   563
            req.vreg[self.registry].select(self.oid, req, **kwargs)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   564
            return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   565
        except NoSelectableObject:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   566
            return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   567
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   568
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   569
# not so basic selectors ######################################################
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   570
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   571
class implements(ImplementsMixIn, EClassSelector):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   572
    """accept if entity classes found in the result set implements at least one
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   573
    of the interfaces given as argument. Returned score is the number of
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   574
    implemented interfaces.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   575
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   576
    See `EClassSelector` documentation for behaviour when row is not specified.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   577
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   578
    :param *expected_ifaces: expected interfaces. An interface may be a class
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   579
                             or an entity type (e.g. `basestring`) in which case
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   580
                             the associated class will be searched in the
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   581
                             registry (at selection time)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   582
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   583
    note: when interface is an entity class, the score will reflect class
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   584
          proximity so the most specific object'll be selected
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   585
    """
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   586
    def score_class(self, eclass, req):
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   587
        return self.score_interfaces(req, eclass, eclass)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   588
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   589
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   590
class specified_etype_implements(implements):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   591
    """accept if entity class specified using an 'etype' parameters in name
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   592
    argument or request form implements at least one of the interfaces given as
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   593
    argument. Returned score is the number of implemented interfaces.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   594
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   595
    :param *expected_ifaces: expected interfaces. An interface may be a class
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   596
                             or an entity type (e.g. `basestring`) in which case
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   597
                             the associated class will be searched in the
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   598
                             registry (at selection time)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   599
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   600
    note: when interface is an entity class, the score will reflect class
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   601
          proximity so the most specific object'll be selected
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   602
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   603
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   604
    @lltrace
789
sylvain.thenault@logilab.fr
parents: 788
diff changeset
   605
    def __call__(self, cls, req, *args, **kwargs):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   606
        try:
2514
c745dfb2734e [selectors] change specified_etype_implements: kwargs prevails on req.form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2381
diff changeset
   607
            etype = kwargs['etype']
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   608
        except KeyError:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   609
            try:
2514
c745dfb2734e [selectors] change specified_etype_implements: kwargs prevails on req.form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2381
diff changeset
   610
                etype = req.form['etype']
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   611
            except KeyError:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   612
                return 0
3346
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   613
            else:
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   614
                # only check this is a known type if etype comes from req.form,
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   615
                # else we want the error to propagate
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   616
                try:
3393
58a62864bae4 [selectors] cls.vreg is not usable anymore, use req.vreg instead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   617
                    etype = req.vreg.case_insensitive_etypes[etype.lower()]
3346
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   618
                    req.form['etype'] = etype
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   619
                except KeyError:
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   620
                    return 0
3393
58a62864bae4 [selectors] cls.vreg is not usable anymore, use req.vreg instead
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   621
        return self.score_class(req.vreg['etypes'].etype_class(etype), req)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   622
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   623
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   624
class entity_implements(ImplementsMixIn, EntitySelector):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   625
    """accept if entity instances found in the result set implements at least one
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   626
    of the interfaces given as argument. Returned score is the number of
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   627
    implemented interfaces.
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   628
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   629
    See `EntitySelector` documentation for behaviour when row is not specified.
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   630
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   631
    :param *expected_ifaces: expected interfaces. An interface may be a class
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   632
                             or an entity type (e.g. `basestring`) in which case
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   633
                             the associated class will be searched in the
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   634
                             registry (at selection time)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   635
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   636
    note: when interface is an entity class, the score will reflect class
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   637
          proximity so the most specific object'll be selected
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   638
    """
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   639
    def score_entity(self, entity):
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   640
        return self.score_interfaces(entity.req, entity, entity.__class__)
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   641
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   642
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   643
class relation_possible(EClassSelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   644
    """accept if entity class found in the result set support the relation.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   645
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   646
    See `EClassSelector` documentation for behaviour when row is not specified.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   647
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   648
    :param rtype: a relation type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   649
    :param role: the role of the result set entity in the relation. 'subject' or
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   650
                 'object', default to 'subject'.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   651
    :param target_type: if specified, check the relation's end may be of this
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   652
                        target type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   653
    :param action: a relation schema action (one of 'read', 'add', 'delete')
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   654
                   which must be granted to the logged user, else a 0 score will
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   655
                   be returned
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   656
    """
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   657
    def __init__(self, rtype, role='subject', target_etype=None,
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   658
                 action='read', once_is_enough=False):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   659
        super(relation_possible, self).__init__(once_is_enough)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   660
        self.rtype = rtype
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   661
        self.role = role
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   662
        self.target_etype = target_etype
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   663
        self.action = action
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   664
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   665
    @lltrace
657
fd019f41aa2f work in progress - fix deprecation of EntityAction - fix various selectors bugs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 656
diff changeset
   666
    def __call__(self, cls, req, *args, **kwargs):
2816
85f7502d32be access schema through req.vreg
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2797
diff changeset
   667
        rschema = req.vreg.schema.rschema(self.rtype)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   668
        if not (rschema.has_perm(req, self.action)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   669
                or rschema.has_local_role(self.action)):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   670
            return 0
3345
10ad3869fc92 [selector] check read perm if action is add/update/delete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3276
diff changeset
   671
        if self.action != 'read':
10ad3869fc92 [selector] check read perm if action is add/update/delete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3276
diff changeset
   672
            if not (rschema.has_perm(req, 'read')
10ad3869fc92 [selector] check read perm if action is add/update/delete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3276
diff changeset
   673
                    or rschema.has_local_role('read')):
10ad3869fc92 [selector] check read perm if action is add/update/delete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3276
diff changeset
   674
                return 0
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   675
        score = super(relation_possible, self).__call__(cls, req, *args, **kwargs)
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   676
        return score
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   677
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   678
    def score_class(self, eclass, req):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   679
        eschema = eclass.e_schema
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   680
        try:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   681
            if self.role == 'object':
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   682
                rschema = eschema.object_relation(self.rtype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   683
            else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   684
                rschema = eschema.subject_relation(self.rtype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   685
        except KeyError:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   686
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   687
        if self.target_etype is not None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   688
            try:
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   689
                if self.role == 'subject':
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   690
                    return int(self.target_etype in rschema.objects(eschema))
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   691
                else:
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   692
                    return int(self.target_etype in rschema.subjects(eschema))
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1037
diff changeset
   693
            except KeyError:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   694
                return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   695
        return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   696
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   697
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   698
class partial_relation_possible(PartialSelectorMixIn, relation_possible):
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   699
    """partial version of the relation_possible selector
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   700
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   701
    The selector will look for class attributes to find its missing
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   702
    information. The list of attributes required on the class
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   703
    for this selector are:
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   704
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   705
    - `rtype`: same as `rtype` parameter of the `relation_possible` selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   706
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   707
    - `role`: this attribute will be passed to the `cubicweb.role` function
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   708
      to determine the role of class in the relation
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   709
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   710
    - `etype` (optional): the entity type on the other side of the relation
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   711
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   712
    :param action: a relation schema action (one of 'read', 'add', 'delete')
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   713
                   which must be granted to the logged user, else a 0 score will
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   714
                   be returned
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   715
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   716
    def __init__(self, action='read', once_is_enough=False):
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   717
        super(partial_relation_possible, self).__init__(None, None, None,
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   718
                                                        action, once_is_enough)
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   719
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   720
    def complete(self, cls):
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   721
        self.rtype = cls.rtype
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   722
        self.role = role(cls)
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   723
        self.target_etype = getattr(cls, 'etype', None)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   724
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   725
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   726
class may_add_relation(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   727
    """accept if the relation can be added to an entity found in the result set
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   728
    by the logged user.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   729
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   730
    See `EntitySelector` documentation for behaviour when row is not specified.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   731
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   732
    :param rtype: a relation type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   733
    :param role: the role of the result set entity in the relation. 'subject' or
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   734
                 'object', default to 'subject'.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   735
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   736
770
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   737
    def __init__(self, rtype, role='subject', once_is_enough=False):
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   738
        super(may_add_relation, self).__init__(once_is_enough)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   739
        self.rtype = rtype
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   740
        self.role = role
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   741
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   742
    def score_entity(self, entity):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   743
        rschema = entity.schema.rschema(self.rtype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   744
        if self.role == 'subject':
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   745
            if not rschema.has_perm(entity.req, 'add', fromeid=entity.eid):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   746
                return 0
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   747
        elif not rschema.has_perm(entity.req, 'add', toeid=entity.eid):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   748
            return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   749
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   750
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   751
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   752
class partial_may_add_relation(PartialSelectorMixIn, may_add_relation):
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   753
    """partial version of the may_add_relation selector
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   754
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   755
    The selector will look for class attributes to find its missing
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   756
    information. The list of attributes required on the class
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   757
    for this selector are:
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   758
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   759
    - `rtype`: same as `rtype` parameter of the `relation_possible` selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   760
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   761
    - `role`: this attribute will be passed to the `cubicweb.role` function
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   762
      to determine the role of class in the relation.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   763
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   764
    :param action: a relation schema action (one of 'read', 'add', 'delete')
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   765
                   which must be granted to the logged user, else a 0 score will
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   766
                   be returned
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   767
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   768
    def __init__(self, once_is_enough=False):
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   769
        super(partial_may_add_relation, self).__init__(None, None, once_is_enough)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   770
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   771
    def complete(self, cls):
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   772
        self.rtype = cls.rtype
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   773
        self.role = role(cls)
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   774
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   775
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   776
class has_related_entities(EntitySelector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   777
    """accept if entity found in the result set has some linked entities using
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   778
    the specified relation (optionaly filtered according to the specified target
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   779
    type). Checks first if the relation is possible.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   780
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   781
    See `EntitySelector` documentation for behaviour when row is not specified.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   782
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   783
    :param rtype: a relation type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   784
    :param role: the role of the result set entity in the relation. 'subject' or
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   785
                 'object', default to 'subject'.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   786
    :param target_type: if specified, check the relation's end may be of this
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   787
                        target type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   788
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   789
    def __init__(self, rtype, role='subject', target_etype=None,
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   790
                 once_is_enough=False):
770
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   791
        super(has_related_entities, self).__init__(once_is_enough)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   792
        self.rtype = rtype
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   793
        self.role = role
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   794
        self.target_etype = target_etype
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   795
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   796
    def score_entity(self, entity):
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   797
        relpossel = relation_possible(self.rtype, self.role, self.target_etype)
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   798
        if not relpossel.score_class(entity.__class__, entity.req):
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   799
            return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   800
        rset = entity.related(self.rtype, self.role)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   801
        if self.target_etype:
1011
22812cfe36b4 fix w/ rset with more than one column
sylvain.thenault@logilab.fr
parents: 876
diff changeset
   802
            return any(r for r in rset.description if r[0] == self.target_etype)
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   803
        return rset and 1 or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   804
833
8c6bfd9158fb bw compat for selection for creation forms
sylvain.thenault@logilab.fr
parents: 828
diff changeset
   805
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   806
class partial_has_related_entities(PartialSelectorMixIn, has_related_entities):
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   807
    """partial version of the has_related_entities selector
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   808
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   809
    The selector will look for class attributes to find its missing
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   810
    information. The list of attributes required on the class
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   811
    for this selector are:
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   812
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   813
    - `rtype`: same as `rtype` parameter of the `relation_possible` selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   814
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   815
    - `role`: this attribute will be passed to the `cubicweb.role` function
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   816
      to determine the role of class in the relation.
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   817
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   818
    - `etype` (optional): the entity type on the other side of the relation
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   819
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   820
    :param action: a relation schema action (one of 'read', 'add', 'delete')
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   821
                   which must be granted to the logged user, else a 0 score will
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   822
                   be returned
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   823
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   824
    def __init__(self, once_is_enough=False):
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   825
        super(partial_has_related_entities, self).__init__(None, None,
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   826
                                                           None, once_is_enough)
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   827
    def complete(self, cls):
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   828
        self.rtype = cls.rtype
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   829
        self.role = role(cls)
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   830
        self.target_etype = getattr(cls, 'etype', None)
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   831
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   832
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   833
class has_permission(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   834
    """accept if user has the permission to do the requested action on a result
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   835
    set entity.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   836
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   837
    * if row is specified, return 1 if user has the permission on the entity
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   838
      instance found in the specified cell
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   839
    * else return a positive score if user has the permission for every entity
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   840
      in the found in the specified column
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   841
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   842
    note: None values (resulting from some outer join in the query) are not
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   843
          considered.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   844
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   845
    :param action: an entity schema action (eg 'read'/'add'/'delete'/'update')
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   846
    """
770
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   847
    def __init__(self, action, once_is_enough=False):
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   848
        super(has_permission, self).__init__(once_is_enough)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   849
        self.action = action
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   850
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   851
    @lltrace
2161
200481e7b156 prepare time where it won't be mandatory to give rset to select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   852
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
788
d62fb3e9797d protect against None rset
sylvain.thenault@logilab.fr
parents: 784
diff changeset
   853
        if rset is None:
d62fb3e9797d protect against None rset
sylvain.thenault@logilab.fr
parents: 784
diff changeset
   854
            return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   855
        user = req.user
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   856
        action = self.action
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   857
        if row is None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   858
            score = 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   859
            need_local_check = []
2816
85f7502d32be access schema through req.vreg
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2797
diff changeset
   860
            geteschema = req.vreg.schema.eschema
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   861
            for etype in rset.column_types(0):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   862
                if etype in BASE_TYPES:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   863
                    return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   864
                eschema = geteschema(etype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   865
                if not user.matching_groups(eschema.get_groups(action)):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   866
                    if eschema.has_local_role(action):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   867
                        # have to ckeck local roles
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   868
                        need_local_check.append(eschema)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   869
                        continue
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   870
                    else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   871
                        # even a local role won't be enough
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   872
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   873
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   874
            if need_local_check:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   875
                # check local role for entities of necessary types
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   876
                for i, row in enumerate(rset):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   877
                    if not rset.description[i][0] in need_local_check:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   878
                        continue
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 650
diff changeset
   879
                    if not self.score(req, rset, i, col):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   880
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   881
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   882
            return score
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   883
        return self.score(req, rset, row, col)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   884
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   885
    def score_entity(self, entity):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   886
        if entity.has_perm(self.action):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   887
            return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   888
        return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   889
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   890
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   891
class has_add_permission(EClassSelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   892
    """accept if logged user has the add permission on entity class found in the
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   893
    result set, and class is not a strict subobject.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   894
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   895
    See `EClassSelector` documentation for behaviour when row is not specified.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   896
    """
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   897
    def score(self, cls, req, etype):
2816
85f7502d32be access schema through req.vreg
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2797
diff changeset
   898
        eschema = req.vreg.schema.eschema(etype)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   899
        if not (eschema.is_final() or eschema.is_subobject(strict=True)) \
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   900
               and eschema.has_perm(req, 'add'):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   901
            return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   902
        return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   903
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   904
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   905
class rql_condition(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   906
    """accept if an arbitrary rql return some results for an eid found in the
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   907
    result set. Returned score is the number of items returned by the rql
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   908
    condition.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   909
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   910
    See `EntitySelector` documentation for behaviour when row is not specified.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   911
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   912
    :param expression: basestring containing an rql expression, which should use
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   913
                       X variable to represent the context entity and may use U
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   914
                       to represent the logged user
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   915
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   916
    return the sum of the number of items returned by the rql condition as score
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   917
    or 0 at the first entity scoring to zero.
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   918
    """
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   919
    def __init__(self, expression, once_is_enough=False):
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   920
        super(rql_condition, self).__init__(once_is_enough)
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   921
        if 'U' in frozenset(split_expression(expression)):
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   922
            rql = 'Any X WHERE X eid %%(x)s, U eid %%(u)s, %s' % expression
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   923
        else:
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   924
            rql = 'Any X WHERE X eid %%(x)s, %s' % expression
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   925
        self.rql = rql
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   926
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   927
    def score(self, req, rset, row, col):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   928
        try:
764
9de67b681624 some test fixes
sylvain.thenault@logilab.fr
parents: 759
diff changeset
   929
            return len(req.execute(self.rql, {'x': rset[row][col],
9de67b681624 some test fixes
sylvain.thenault@logilab.fr
parents: 759
diff changeset
   930
                                              'u': req.user.eid}, 'x'))
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   931
        except Unauthorized:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   932
            return 0
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   933
1887
7e19c94ce0d7 [selectors] provide a nicer representation of rql_condition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1784
diff changeset
   934
    def __repr__(self):
7e19c94ce0d7 [selectors] provide a nicer representation of rql_condition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1784
diff changeset
   935
        return u'<rql_condition "%s" at %x>' % (self.rql, id(self))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   936
2084
923788d1f9c6 optional rset, those prototype could be simplified once bw compat for non named rset will be dropped
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2082
diff changeset
   937
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   938
class but_etype(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   939
    """accept if the given entity types are not found in the result set.
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   940
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   941
    See `EntitySelector` documentation for behaviour when row is not specified.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   942
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   943
    :param *etypes: entity types (`basestring`) which should be refused
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   944
    """
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   945
    def __init__(self, *etypes):
770
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   946
        super(but_etype, self).__init__()
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   947
        self.but_etypes = etypes
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   948
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   949
    def score(self, req, rset, row, col):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   950
        if rset.description[row][col] in self.but_etypes:
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   951
            return 0
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   952
        return 1
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   953
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   954
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   955
class score_entity(EntitySelector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   956
    """accept if some arbitrary function return a positive score for an entity
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   957
    found in the result set.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   958
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   959
    See `EntitySelector` documentation for behaviour when row is not specified.
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   960
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   961
    :param scorefunc: callable expected to take an entity as argument and to
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   962
                      return a score >= 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   963
    """
764
9de67b681624 some test fixes
sylvain.thenault@logilab.fr
parents: 759
diff changeset
   964
    def __init__(self, scorefunc, once_is_enough=False):
1138
22f634977c95 make pylint happy, fix some bugs on the way
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   965
        super(score_entity, self).__init__(once_is_enough)
3276
4480887772a3 [selectors] score_entity selector now ensures an int score is returned
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2972
diff changeset
   966
        def intscore(*args, **kwargs):
4480887772a3 [selectors] score_entity selector now ensures an int score is returned
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2972
diff changeset
   967
            score = scorefunc(*args, **kwargs)
4480887772a3 [selectors] score_entity selector now ensures an int score is returned
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2972
diff changeset
   968
            if not score:
4480887772a3 [selectors] score_entity selector now ensures an int score is returned
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2972
diff changeset
   969
                return 0
4480887772a3 [selectors] score_entity selector now ensures an int score is returned
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2972
diff changeset
   970
            if isinstance(score, (int, long)):
4480887772a3 [selectors] score_entity selector now ensures an int score is returned
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2972
diff changeset
   971
                return score
4480887772a3 [selectors] score_entity selector now ensures an int score is returned
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2972
diff changeset
   972
            return 1
4480887772a3 [selectors] score_entity selector now ensures an int score is returned
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2972
diff changeset
   973
        self.score_entity = intscore