selectors.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 21 Jan 2010 17:38:31 +0100
changeset 4320 4efd4c306746
parent 4264 273307c54b4d
child 4327 e397b921c40f
permissions -rw-r--r--
closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named replaced by multi_lines_rset, multi_columns_rset, multi_etypes_rset, all taking optional 'nb' argument allowing to specify and exact count. Bw compat is kept, usage of deprecated function updated in cw itself. Also drop custom at_least_two_columns selector (in views.plots) since it was the same as multi_columns_rset. Hopefuly the renaming will help in avoid such pb... We should now decide if we want to deprecate one_* selector in favor of multi_*(nb=1). See note on this at then end of selectors.py
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
4212
ab6573088b4a update copyright: welcome 2010
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4148
diff changeset
    39
:copyright: 2001-2010 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
3650
012da21e43fe ignore some internal warnings
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 3638
diff changeset
    46
from warnings import warn, filterwarnings
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    47
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
    48
from logilab.common.deprecation import class_renamed
3757
122a01751d59 2.4 compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
    49
from logilab.common.compat import all, any
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    50
from logilab.common.interface import implements as implements_iface
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    51
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    52
from yams import BASE_TYPES
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    53
1503
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
    54
from cubicweb import (Unauthorized, NoSelectableObject, NotAnEntity,
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
    55
                      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
    56
# 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
    57
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
    58
from cubicweb.vregistry import class_regid
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    59
from cubicweb.cwconfig import CubicWebConfiguration
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    60
from cubicweb.schema import split_expression
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    61
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    62
# helpers for debugging selectors
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    63
SELECTOR_LOGGER = logging.getLogger('cubicweb.selectors')
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    64
TRACED_OIDS = ()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    65
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    66
def lltrace(selector):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    67
    # don't wrap selectors if not in development mode
3638
648d6dbec630 system/user modes + CWDEV instead of installed/dev mixed modes. Fix behaviour when setting CW_MODE explicitly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3522
diff changeset
    68
    if CubicWebConfiguration.mode == 'system': # XXX config.debug
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    69
        return selector
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    70
    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
    71
        # /!\ 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
    72
        #     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
    73
        if isinstance(cls, Selector):
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
    74
            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
    75
            vobj = args[0]
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    76
        else:
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    77
            selname = selector.__name__
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    78
            vobj = cls
2834
7df3494ae657 [vreg appobject] use class_regid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2822
diff changeset
    79
        oid = class_regid(vobj)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    80
        ret = selector(cls, *args, **kwargs)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    81
        if TRACED_OIDS == 'all' or oid in TRACED_OIDS:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    82
            #SELECTOR_LOGGER.warning('selector %s returned %s for %s', selname, ret, cls)
4026
d80a55a024d8 add regid when tracing selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3890
diff changeset
    83
            print '%s -> %s for %s(%s)' % (selname, ret, vobj, vobj.__regid__)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    84
        return ret
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    85
    traced.__name__ = selector.__name__
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    86
    return traced
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    87
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    88
class traced_selection(object):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    89
    """selector debugging helper.
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    90
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    91
    Typical usage is :
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    92
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    93
    >>> with traced_selection():
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    94
    ...     # some code in which you want to debug selectors
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    95
    ...     # for all objects
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    96
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    97
    or
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    98
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    99
    >>> with traced_selection( ('oid1', 'oid2') ):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   100
    ...     # some code in which you want to debug selectors
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   101
    ...     # for objects with id 'oid1' and 'oid2'
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   102
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   103
    """
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   104
    def __init__(self, traced='all'):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   105
        self.traced = traced
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   106
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   107
    def __enter__(self):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   108
        global TRACED_OIDS
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   109
        TRACED_OIDS = self.traced
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   110
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   111
    def __exit__(self, exctype, exc, traceback):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   112
        global TRACED_OIDS
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   113
        TRACED_OIDS = ()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   114
        return traceback is None
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   115
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   116
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   117
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
   118
    """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
   119
    the interface.
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   120
    """
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   121
    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
   122
        # adjust score if the interface is an entity class
3399
2b84f4adb6f8 use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3396
diff changeset
   123
        parents = etypesreg.parent_classes(cls_or_inst.__regid__)
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   124
        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
   125
            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
   126
        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
   127
            return 1
1784
f0fb914e57db already a class
sylvain.thenault@logilab.fr
parents: 1694
diff changeset
   128
        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
   129
            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
   130
                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
   131
        return 0
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   132
    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
   133
        # 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
   134
        return 2
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   135
    return 0
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   136
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   137
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   138
# abstract selectors ##########################################################
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   139
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   140
class PartialSelectorMixIn(object):
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   141
    """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
   142
    class to find missing information.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   143
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   144
    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
   145
    """
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   146
    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
   147
        self.complete(cls)
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   148
        return super(PartialSelectorMixIn, self).__call__(cls, *args, **kwargs)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   149
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   150
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   151
class ImplementsMixIn(object):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   152
    """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
   153
    """
3522
cde0ff4f7a8c [selectors] add accept_none to EClassSelector so we can specify to not ignore None from outer join in some cases
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3350
diff changeset
   154
    def __init__(self, *expected_ifaces, **kwargs):
cde0ff4f7a8c [selectors] add accept_none to EClassSelector so we can specify to not ignore None from outer join in some cases
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3350
diff changeset
   155
        super(ImplementsMixIn, self).__init__(**kwargs)
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   156
        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
   157
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   158
    def __str__(self):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   159
        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
   160
                           ','.join(str(s) for s in self.expected_ifaces))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   161
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   162
    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
   163
        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
   164
        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
   165
        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
   166
        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
   167
            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
   168
                # entity type
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   169
                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
   170
                    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
   171
                except KeyError:
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   172
                    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
   173
            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
   174
        return score
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   175
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   176
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   177
class EClassSelector(Selector):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   178
    """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
   179
    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
   180
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   181
    * if 'entity' find in kwargs, return the score returned by the score_class
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   182
      method for this entity's class
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   183
    * elif row is specified, return the score returned by the score_class method
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   184
      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
   185
    * 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
   186
      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
   187
      - `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
   188
        returned
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   189
      - `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
   190
        returned
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   191
    """
3522
cde0ff4f7a8c [selectors] add accept_none to EClassSelector so we can specify to not ignore None from outer join in some cases
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3350
diff changeset
   192
    def __init__(self, once_is_enough=False, accept_none=True):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   193
        self.once_is_enough = once_is_enough
3522
cde0ff4f7a8c [selectors] add accept_none to EClassSelector so we can specify to not ignore None from outer join in some cases
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3350
diff changeset
   194
        self.accept_none = accept_none
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   195
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   196
    @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
   197
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   198
        if kwargs.get('entity'):
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   199
            return self.score_class(kwargs['entity'].__class__, req)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   200
        if not rset:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   201
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   202
        score = 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   203
        if row is None:
3522
cde0ff4f7a8c [selectors] add accept_none to EClassSelector so we can specify to not ignore None from outer join in some cases
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3350
diff changeset
   204
            if not self.accept_none:
cde0ff4f7a8c [selectors] add accept_none to EClassSelector so we can specify to not ignore None from outer join in some cases
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3350
diff changeset
   205
                if any(rset[i][col] is None for i in xrange(len(rset))):
cde0ff4f7a8c [selectors] add accept_none to EClassSelector so we can specify to not ignore None from outer join in some cases
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3350
diff changeset
   206
                    return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   207
            for etype in rset.column_types(col):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   208
                if etype is None: # outer join
3522
cde0ff4f7a8c [selectors] add accept_none to EClassSelector so we can specify to not ignore None from outer join in some cases
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3350
diff changeset
   209
                    return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   210
                escore = self.score(cls, req, etype)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   211
                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
   212
                    return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   213
                elif self.once_is_enough:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   214
                    return escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   215
                score += escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   216
        else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   217
            etype = rset.description[row][col]
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   218
            if etype is not None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   219
                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
   220
        return score
634
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
    def score(self, cls, req, etype):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   223
        if etype in BASE_TYPES:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   224
            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
   225
        return self.score_class(req.vreg['etypes'].etype_class(etype), req)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   226
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   227
    def score_class(self, eclass, req):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   228
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   229
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   230
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   231
class EntitySelector(EClassSelector):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   232
    """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
   233
    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
   234
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   235
    * 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
   236
      method for this entity
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   237
    * 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
   238
      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
   239
    * 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
   240
      entity found in the specified column, unless:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   241
      - `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
   242
        returned
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   243
      - `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
   244
        returned
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   245
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   246
    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
   247
          considered.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   248
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   249
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   250
    @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
   251
    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
   252
        if not rset and not kwargs.get('entity'):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   253
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   254
        score = 0
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   255
        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
   256
            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
   257
        elif row is None:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   258
            col = col or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   259
            for row, rowvalue in enumerate(rset.rows):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   260
                if rowvalue[col] is None: # outer join
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   261
                    continue
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 650
diff changeset
   262
                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
   263
                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
   264
                    return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   265
                elif self.once_is_enough:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   266
                    return escore
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   267
                score += escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   268
        else:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   269
            col = col or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   270
            etype = rset.description[row][col]
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   271
            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
   272
                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
   273
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   274
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   275
    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
   276
        try:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   277
            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
   278
        except NotAnEntity:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   279
            return 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   280
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   281
    def score_entity(self, entity):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   282
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   283
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   284
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   285
# very basic selectors ########################################################
1138
22f634977c95 make pylint happy, fix some bugs on the way
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   286
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   287
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   288
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   289
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
   290
    """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
   291
    if rset is None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   292
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   293
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   294
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   295
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   296
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   297
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
   298
    """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
   299
    if rset is not None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   300
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   301
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   302
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   303
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   304
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   305
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
   306
    """accept any non empty result set"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   307
    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
   308
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   309
    return 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   310
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   311
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   312
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   313
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
   314
    """accept empty result set"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   315
    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
   316
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   317
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   318
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   319
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   320
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   321
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
   322
    """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
   323
    else accepts anyway
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   324
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   325
    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
   326
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   327
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   328
4320
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   329
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   330
class multi_lines_rset(Selector):
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   331
    def __init__(self, nb=None):
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   332
        self.expected = nb
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   333
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   334
    def match_expected(self, num):
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   335
        if self.expected is None:
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   336
            return num > 1
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   337
        return num == self.expected
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   338
4320
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   339
    @lltrace
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   340
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   341
        return rset is not None and self.match_expected(rset.rowcount)
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   342
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   343
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   344
class multi_columns_rset(multi_lines_rset):
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   345
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   346
    @lltrace
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   347
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   348
        return rset and self.match_expected(len(rset.rows[0]))
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   349
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   350
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   351
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   352
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   353
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
   354
    """accept result set with more lines than the page size.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   355
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   356
    Page size is searched in (respecting order):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   357
    * a page_size argument
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   358
    * a page_size form parameters
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   359
    * the navigation.page-size property
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   360
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   361
    page_size = kwargs.get('page_size')
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   362
    if page_size is None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   363
        page_size = req.form.get('page_size')
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   364
        if page_size is None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   365
            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
   366
        else:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   367
            page_size = int(page_size)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   368
    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
   369
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   370
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   371
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   372
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   373
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   374
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
   375
    """accept sorted result set"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   376
    rqlst = rset.syntax_tree()
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   377
    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
   378
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   379
    return 2
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   380
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   381
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   382
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   383
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
   384
    """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
   385
    of the same type
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   386
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   387
    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
   388
        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   389
    if len(rset.column_types(col)) != 1:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   390
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   391
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   392
4320
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   393
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   394
class multi_etypes_rset(multi_lines_rset):
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   395
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   396
    @lltrace
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   397
    def __call__(self, cls, req, rset=None, **kwargs):
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   398
        return rset and self.match_expected(len(rset.column_types(col)))
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   399
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   400
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   401
class non_final_entity(EClassSelector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   402
    """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
   403
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   404
    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
   405
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   406
    def score(self, cls, req, etype):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   407
        if etype in BASE_TYPES:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   408
            return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   409
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   410
4320
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   411
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   412
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   413
@lltrace
828
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   414
def authenticated_user(cls, req, *args, **kwargs):
1492
sylvain.thenault@logilab.fr
parents: 1474
diff changeset
   415
    """accept if user is authenticated"""
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   416
    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
   417
        return 0
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   418
    return 1
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   419
828
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   420
def anonymous_user():
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   421
    return ~ authenticated_user()
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   422
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   423
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   424
@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
   425
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
   426
    """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
   427
    is given
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   428
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   429
    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
   430
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   431
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   432
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   433
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   434
@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
   435
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
   436
                       **kwargs):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   437
    """accept if:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   438
    * no context given
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   439
    * 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
   440
      given cls
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   441
    """
3399
2b84f4adb6f8 use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3396
diff changeset
   442
    propval = req.property_value('%s.%s.context' % (cls.__registry__,
2b84f4adb6f8 use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3396
diff changeset
   443
                                                    cls.__regid__))
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   444
    if not propval:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   445
        propval = cls.context
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   446
    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
   447
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   448
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   449
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   450
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   451
class match_search_state(Selector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   452
    """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
   453
    states given to the initializer
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   454
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   455
    :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
   456
                     object to create a relation with another)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   457
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   458
    def __init__(self, *expected):
774
48cb1f42e79c tell on which class the assertion's failed
sylvain.thenault@logilab.fr
parents: 770
diff changeset
   459
        assert expected, self
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   460
        self.expected = frozenset(expected)
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   461
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   462
    def __str__(self):
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   463
        return '%s(%s)' % (self.__class__.__name__,
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   464
                           ','.join(sorted(str(s) for s in self.expected)))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   465
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   466
    @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
   467
    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
   468
        try:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   469
            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
   470
                return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   471
        except AttributeError:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   472
            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
   473
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   474
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   475
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   476
class match_form_params(match_search_state):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   477
    """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
   478
    in request's form parameters
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   479
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   480
    :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
   481
                      found in request's form parameters
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   482
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   483
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   484
    @lltrace
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   485
    def __call__(self, cls, req, *args, **kwargs):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   486
        score = 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   487
        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
   488
            if not param in req.form:
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   489
                return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   490
            score += 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   491
        return len(self.expected)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   492
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   493
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   494
class match_kwargs(match_search_state):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   495
    """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
   496
    in named arguments given to the selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   497
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   498
    :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
   499
                      found in named arguments (kwargs)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   500
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   501
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   502
    @lltrace
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   503
    def __call__(self, cls, req, *args, **kwargs):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   504
        for arg in self.expected:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   505
            if not arg in kwargs:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   506
                return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   507
        return len(self.expected)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   508
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   509
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   510
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
   511
    """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
   512
    score is the number of groups in which the user is.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   513
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   514
    If the special 'owners' group is given:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   515
    * 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
   516
      logged user
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   517
    * 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
   518
      user
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   519
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   520
    :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
   521
                             user should be
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   522
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   523
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   524
    @lltrace
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   525
    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
   526
        user = req.user
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   527
        if user is None:
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   528
            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
   529
        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
   530
        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
   531
            if row is not None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   532
                if not user.owns(rset[row][col]):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   533
                    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   534
                score = 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   535
            else:
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   536
                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
   537
        return score
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   538
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   539
1503
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   540
class match_transition(match_search_state):
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   541
    @lltrace
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   542
    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
   543
        try:
3350
fa77640a9155 since we have the transition entity, give it directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3346
diff changeset
   544
            # 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
   545
            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
   546
                return 0
fa77640a9155 since we have the transition entity, give it directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3346
diff changeset
   547
        except KeyError:
1503
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   548
            return 0
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   549
        return 1
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   550
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   551
1263
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   552
class match_view(match_search_state):
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   553
    """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
   554
    initializer
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   555
    """
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   556
    @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
   557
    def __call__(self, cls, req, rset=None, row=None, col=0, view=None, **kwargs):
3399
2b84f4adb6f8 use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3396
diff changeset
   558
        if view is None or not view.__regid__ in self.expected:
1263
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   559
            return 0
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   560
        return 1
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   561
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   562
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   563
class appobject_selectable(Selector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   564
    """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
   565
    context.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   566
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   567
    :param registry: a registry name (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   568
    :param oid: an object identifier (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   569
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   570
    def __init__(self, registry, oid):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   571
        self.registry = registry
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   572
        self.oid = oid
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   573
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
   574
    def __call__(self, cls, req, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   575
        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
   576
            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
   577
            return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   578
        except NoSelectableObject:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   579
            return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   580
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   581
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   582
# not so basic selectors ######################################################
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   583
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   584
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
   585
    """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
   586
    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
   587
    implemented interfaces.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   588
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   589
    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
   590
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   591
    :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
   592
                             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
   593
                             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
   594
                             registry (at selection time)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   595
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   596
    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
   597
          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
   598
    """
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   599
    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
   600
        return self.score_interfaces(req, eclass, eclass)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   601
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   602
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   603
class specified_etype_implements(implements):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   604
    """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
   605
    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
   606
    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
   607
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   608
    :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
   609
                             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
   610
                             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
   611
                             registry (at selection time)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   612
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   613
    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
   614
          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
   615
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   616
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   617
    @lltrace
789
sylvain.thenault@logilab.fr
parents: 788
diff changeset
   618
    def __call__(self, cls, req, *args, **kwargs):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   619
        try:
2514
c745dfb2734e [selectors] change specified_etype_implements: kwargs prevails on req.form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2381
diff changeset
   620
            etype = kwargs['etype']
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   621
        except KeyError:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   622
            try:
2514
c745dfb2734e [selectors] change specified_etype_implements: kwargs prevails on req.form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2381
diff changeset
   623
                etype = req.form['etype']
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   624
            except KeyError:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   625
                return 0
3346
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   626
            else:
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   627
                # 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
   628
                # 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
   629
                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
   630
                    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
   631
                    req.form['etype'] = etype
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   632
                except KeyError:
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   633
                    return 0
4181
c79135c217df backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4102 4148
diff changeset
   634
        score = self.score_class(req.vreg['etypes'].etype_class(etype), req)
4148
748454627176 cubicweb security #36257: les urls /add/EntityName sont accessibles en anonyme
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   635
        if score:
748454627176 cubicweb security #36257: les urls /add/EntityName sont accessibles en anonyme
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   636
            eschema = req.vreg.schema.eschema(etype)
748454627176 cubicweb security #36257: les urls /add/EntityName sont accessibles en anonyme
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   637
            if eschema.has_local_role('add') or eschema.has_perm(req, 'add'):
748454627176 cubicweb security #36257: les urls /add/EntityName sont accessibles en anonyme
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   638
                return score
748454627176 cubicweb security #36257: les urls /add/EntityName sont accessibles en anonyme
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   639
        return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   640
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   641
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   642
class relation_possible(EClassSelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   643
    """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
   644
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   645
    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
   646
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   647
    :param rtype: a relation type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   648
    :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
   649
                 'object', default to 'subject'.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   650
    :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
   651
                        target type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   652
    :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
   653
                   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
   654
                   be returned
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   655
    """
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   656
    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
   657
                 action='read', once_is_enough=False):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   658
        super(relation_possible, self).__init__(once_is_enough)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   659
        self.rtype = rtype
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   660
        self.role = role
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   661
        self.target_etype = target_etype
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   662
        self.action = action
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   663
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   664
    def score_class(self, eclass, req):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   665
        eschema = eclass.e_schema
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   666
        try:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   667
            if self.role == 'object':
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3650
diff changeset
   668
                rschema = eschema.objrels[self.rtype]
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   669
            else:
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3650
diff changeset
   670
                rschema = eschema.subjrels[self.rtype]
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   671
        except KeyError:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   672
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   673
        if self.target_etype is not None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   674
            try:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   675
                rdef = rschema.role_rdef(eschema, self.target_etype, self.role)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   676
                if not rdef.may_have_permission(self.action, req):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   677
                    return 0
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1037
diff changeset
   678
            except KeyError:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   679
                return 0
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   680
        else:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   681
            return rschema.may_have_permission(self.action, req, eschema, self.role)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   682
        return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   683
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   684
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   685
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
   686
    """partial version of the relation_possible selector
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   687
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   688
    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
   689
    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
   690
    for this selector are:
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   691
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   692
    - `rtype`: same as `rtype` parameter of the `relation_possible` selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   693
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   694
    - `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
   695
      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
   696
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   697
    - `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
   698
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   699
    :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
   700
                   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
   701
                   be returned
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   702
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   703
    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
   704
        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
   705
                                                        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
   706
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   707
    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
   708
        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
   709
        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
   710
        self.target_etype = getattr(cls, 'etype', None)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   711
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   712
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   713
class may_add_relation(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   714
    """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
   715
    by the logged user.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   716
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   717
    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
   718
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   719
    :param rtype: a relation type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   720
    :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
   721
                 'object', default to 'subject'.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   722
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   723
4234
0adf45697422 if specified, benefit from target_etype information in the [partial_]add_relation selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   724
    def __init__(self, rtype, role='subject', target_etype=None,
0adf45697422 if specified, benefit from target_etype information in the [partial_]add_relation selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   725
                 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
   726
        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
   727
        self.rtype = rtype
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   728
        self.role = role
4234
0adf45697422 if specified, benefit from target_etype information in the [partial_]add_relation selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   729
        self.target_etype = target_etype
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   730
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   731
    def score_entity(self, entity):
4264
273307c54b4d update selectors.py: change entity.schema with entity._cw.vreg.schema
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 4252
diff changeset
   732
        rschema = entity._cw.vreg.schema.rschema(self.rtype)
4234
0adf45697422 if specified, benefit from target_etype information in the [partial_]add_relation selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   733
        if self.target_etype is not None:
0adf45697422 if specified, benefit from target_etype information in the [partial_]add_relation selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   734
            rschema = rschema.role_rdef(entity.e_schema, self.target_etype, self.role)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   735
        if self.role == 'subject':
3378
2f25f701301d use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   736
            if not rschema.has_perm(entity._cw, 'add', fromeid=entity.eid):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   737
                return 0
3378
2f25f701301d use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   738
        elif not rschema.has_perm(entity._cw, 'add', toeid=entity.eid):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   739
            return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   740
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   741
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   742
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   743
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
   744
    """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
   745
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   746
    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
   747
    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
   748
    for this selector are:
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   749
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   750
    - `rtype`: same as `rtype` parameter of the `relation_possible` selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   751
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   752
    - `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
   753
      to determine the role of class in the relation.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   754
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   755
    :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
   756
                   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
   757
                   be returned
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   758
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   759
    def __init__(self, once_is_enough=False):
4234
0adf45697422 if specified, benefit from target_etype information in the [partial_]add_relation selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   760
        super(partial_may_add_relation, self).__init__(None, once_is_enough=once_is_enough)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   761
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   762
    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
   763
        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
   764
        self.role = role(cls)
4234
0adf45697422 if specified, benefit from target_etype information in the [partial_]add_relation selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   765
        self.target_etype = getattr(cls, 'etype', None)
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   766
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   767
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   768
class has_related_entities(EntitySelector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   769
    """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
   770
    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
   771
    type). Checks first if the relation is possible.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   772
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   773
    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
   774
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   775
    :param rtype: a relation type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   776
    :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
   777
                 'object', default to 'subject'.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   778
    :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
   779
                        target type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   780
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   781
    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
   782
                 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
   783
        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
   784
        self.rtype = rtype
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   785
        self.role = role
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   786
        self.target_etype = target_etype
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   787
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   788
    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
   789
        relpossel = relation_possible(self.rtype, self.role, self.target_etype)
3378
2f25f701301d use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   790
        if not relpossel.score_class(entity.__class__, entity._cw):
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   791
            return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   792
        rset = entity.related(self.rtype, self.role)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   793
        if self.target_etype:
1011
22812cfe36b4 fix w/ rset with more than one column
sylvain.thenault@logilab.fr
parents: 876
diff changeset
   794
            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
   795
        return rset and 1 or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   796
833
8c6bfd9158fb bw compat for selection for creation forms
sylvain.thenault@logilab.fr
parents: 828
diff changeset
   797
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   798
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
   799
    """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
   800
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   801
    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
   802
    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
   803
    for this selector are:
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   804
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   805
    - `rtype`: same as `rtype` parameter of the `relation_possible` selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   806
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   807
    - `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
   808
      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
   809
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   810
    - `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
   811
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   812
    :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
   813
                   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
   814
                   be returned
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   815
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   816
    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
   817
        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
   818
                                                           None, once_is_enough)
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   819
    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
   820
        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
   821
        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
   822
        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
   823
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   824
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   825
class has_permission(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   826
    """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
   827
    set entity.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   828
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   829
    * 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
   830
      instance found in the specified cell
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   831
    * 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
   832
      in the found in the specified column
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   833
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   834
    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
   835
          considered.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   836
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   837
    :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
   838
    """
770
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   839
    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
   840
        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
   841
        self.action = action
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   842
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   843
    @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
   844
    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
   845
        if rset is None:
d62fb3e9797d protect against None rset
sylvain.thenault@logilab.fr
parents: 784
diff changeset
   846
            return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   847
        user = req.user
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   848
        action = self.action
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   849
        if row is None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   850
            score = 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   851
            need_local_check = []
2816
85f7502d32be access schema through req.vreg
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2797
diff changeset
   852
            geteschema = req.vreg.schema.eschema
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   853
            for etype in rset.column_types(0):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   854
                if etype in BASE_TYPES:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   855
                    return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   856
                eschema = geteschema(etype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   857
                if not user.matching_groups(eschema.get_groups(action)):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   858
                    if eschema.has_local_role(action):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   859
                        # have to ckeck local roles
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   860
                        need_local_check.append(eschema)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   861
                        continue
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   862
                    else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   863
                        # even a local role won't be enough
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   864
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   865
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   866
            if need_local_check:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   867
                # check local role for entities of necessary types
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   868
                for i, row in enumerate(rset):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   869
                    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
   870
                        continue
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 650
diff changeset
   871
                    if not self.score(req, rset, i, col):
634
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
            return score
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   875
        return self.score(req, rset, row, col)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   876
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   877
    def score_entity(self, entity):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   878
        if entity.has_perm(self.action):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   879
            return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   880
        return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   881
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   882
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   883
class has_add_permission(EClassSelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   884
    """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
   885
    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
   886
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   887
    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
   888
    """
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   889
    def score(self, cls, req, etype):
2816
85f7502d32be access schema through req.vreg
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2797
diff changeset
   890
        eschema = req.vreg.schema.eschema(etype)
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3650
diff changeset
   891
        if not (eschema.final or eschema.is_subobject(strict=True)) \
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   892
               and eschema.has_perm(req, 'add'):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   893
            return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   894
        return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   895
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   896
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   897
class rql_condition(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   898
    """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
   899
    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
   900
    condition.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   901
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   902
    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
   903
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   904
    :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
   905
                       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
   906
                       to represent the logged user
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   907
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   908
    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
   909
    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
   910
    """
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   911
    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
   912
        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
   913
        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
   914
            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
   915
        else:
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   916
            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
   917
        self.rql = rql
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   918
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   919
    def score(self, req, rset, row, col):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   920
        try:
764
9de67b681624 some test fixes
sylvain.thenault@logilab.fr
parents: 759
diff changeset
   921
            return len(req.execute(self.rql, {'x': rset[row][col],
9de67b681624 some test fixes
sylvain.thenault@logilab.fr
parents: 759
diff changeset
   922
                                              'u': req.user.eid}, 'x'))
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   923
        except Unauthorized:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   924
            return 0
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   925
1887
7e19c94ce0d7 [selectors] provide a nicer representation of rql_condition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1784
diff changeset
   926
    def __repr__(self):
7e19c94ce0d7 [selectors] provide a nicer representation of rql_condition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1784
diff changeset
   927
        return u'<rql_condition "%s" at %x>' % (self.rql, id(self))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   928
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
   929
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   930
class score_entity(EntitySelector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   931
    """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
   932
    found in the result set.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   933
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   934
    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
   935
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   936
    :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
   937
                      return a score >= 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   938
    """
764
9de67b681624 some test fixes
sylvain.thenault@logilab.fr
parents: 759
diff changeset
   939
    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
   940
        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
   941
        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
   942
            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
   943
            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
   944
                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
   945
            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
   946
                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
   947
            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
   948
        self.score_entity = intscore
2972
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   949
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   950
## deprecated stuff ############################################################
2972
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   951
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   952
entity_implements = class_renamed('entity_implements', implements)
2972
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   953
4081
64548076add4 avoid infinite recursion error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4071
diff changeset
   954
class _but_etype(EntitySelector):
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   955
    """accept if the given entity types are not found in the result set.
2972
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   956
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   957
    See `EntitySelector` documentation for behaviour when row is not specified.
2972
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   958
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   959
    :param *etypes: entity types (`basestring`) which should be refused
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   960
    """
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   961
    def __init__(self, *etypes):
4102
5ba6df5fcb07 missing underscore leads to infinite recursion error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4081
diff changeset
   962
        super(_but_etype, self).__init__()
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   963
        self.but_etypes = etypes
2972
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   964
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   965
    def score(self, req, rset, row, col):
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   966
        if rset.description[row][col] in self.but_etypes:
2972
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   967
            return 0
4071
e19e586cc74e deprecates entity_implements / but_etype selectors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4026
diff changeset
   968
        return 1
2972
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   969
4081
64548076add4 avoid infinite recursion error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4071
diff changeset
   970
but_etype = class_renamed('but_etype', _but_etype, 'use ~implements(*etypes) instead')
4320
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   971
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   972
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   973
# XXX deprecated the one_* variants of selectors below w/ multi_xxx(nb=1)?
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   974
#     take care at the implementation though (looking for the 'row' argument's
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   975
#     value)
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   976
two_lines_rset = class_renamed('two_lines_rset', multi_lines_rset)
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   977
two_cols_rset = class_renamed('two_cols_rset', multi_columns_rset)
4efd4c306746 closes #345410: two_lines_rset, two_cols_rset, two_etypes_rset are badly named
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4264
diff changeset
   978
two_etypes_rset = class_renamed('two_etypes_rset', multi_etypes_rset)