selectors.py
author Alexandre Fayolle <alexandre.fayolle@logilab.fr>
Tue, 06 Oct 2009 16:56:22 +0200
branchstable
changeset 3563 f1dbb9bf4da3
parent 3522 cde0ff4f7a8c
child 3524 a3431f4e2f40
child 3638 648d6dbec630
permissions -rw-r--r--
fix label in generated form for relations the label for object relations was incorrect, because the '_object' mangling is done on the wrong component of field.label. fix ticket 472831
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
     1
"""This file contains some basic selectors required by application objects.
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
     2
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
     3
A selector is responsible to score how well an object may be used with a
718
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
     4
given context by returning a score.
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
     5
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
     6
In CubicWeb Usually the context consists for a request object, a result set
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
     7
or None, a specific row/col in the result set, etc...
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
     8
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
     9
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    10
If you have trouble with selectors, especially if the objet (typically
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    11
a view or a component) you want to use is not selected and you want to
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    12
know which one(s) of its selectors fail (e.g. returns 0), you can use
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    13
`traced_selection` or even direclty `TRACED_OIDS`.
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    14
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    15
`TRACED_OIDS` is a tuple of traced object ids. The special value
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    16
'all' may be used to log selectors for all objects.
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    17
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    18
For instance, say that the following code yields a `NoSelectableObject`
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    19
exception::
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    20
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    21
    self.view('calendar', myrset)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    22
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    23
You can log the selectors involved for *calendar* by replacing the line
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    24
above by::
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    25
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    26
    # in Python2.5
692
800592b8d39b replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 660
diff changeset
    27
    from cubicweb.selectors import traced_selection
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    28
    with traced_selection():
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    29
        self.view('calendar', myrset)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    30
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    31
    # in Python2.4
692
800592b8d39b replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 660
diff changeset
    32
    from cubicweb import selectors
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    33
    selectors.TRACED_OIDS = ('calendar',)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    34
    self.view('calendar', myrset)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    35
    selectors.TRACED_OIDS = ()
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
    36
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    37
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    38
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1909
diff changeset
    39
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    40
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1909
diff changeset
    41
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    42
"""
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    43
__docformat__ = "restructuredtext en"
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    44
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    45
import logging
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    46
from warnings import warn
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    47
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    48
from logilab.common.compat import all
2972
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
    49
from logilab.common.deprecation import deprecated
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
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    58
from cubicweb.cwconfig import CubicWebConfiguration
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    59
from cubicweb.schema import split_expression
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    60
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    61
# helpers for debugging selectors
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    62
SELECTOR_LOGGER = logging.getLogger('cubicweb.selectors')
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    63
TRACED_OIDS = ()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    64
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    65
def lltrace(selector):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    66
    # don't wrap selectors if not in development mode
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    67
    if CubicWebConfiguration.mode == 'installed':
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    68
        return selector
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    69
    def traced(cls, *args, **kwargs):
752
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    70
        # /!\ lltrace decorates pure function or __call__ method, this
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    71
        #     means argument order may be different
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    72
        if isinstance(cls, Selector):
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
    73
            selname = str(cls)
752
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    74
            vobj = args[0]
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    75
        else:
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    76
            selname = selector.__name__
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    77
            vobj = cls
c0506c4a1e6c fix lltrace to consider __call__ and pure functions decoration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 737
diff changeset
    78
        oid = vobj.id
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    79
        ret = selector(cls, *args, **kwargs)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    80
        if TRACED_OIDS == 'all' or oid in TRACED_OIDS:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    81
            #SELECTOR_LOGGER.warning('selector %s returned %s for %s', selname, ret, cls)
2308
b478c3a8ad2a typos, cleanup, lighter traced seletion output
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2274
diff changeset
    82
            print '%s -> %s for %s' % (selname, ret, vobj)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    83
        return ret
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    84
    traced.__name__ = selector.__name__
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    85
    return traced
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    86
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    87
class traced_selection(object):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    88
    """selector debugging helper.
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    89
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    90
    Typical usage is :
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    91
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    92
    >>> with traced_selection():
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    93
    ...     # some code in which you want to debug selectors
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    94
    ...     # for all objects
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    95
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    96
    or
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    97
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    98
    >>> with traced_selection( ('oid1', 'oid2') ):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    99
    ...     # some code in which you want to debug selectors
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   100
    ...     # for objects with id 'oid1' and 'oid2'
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   101
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   102
    """
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   103
    def __init__(self, traced='all'):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   104
        self.traced = traced
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   105
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   106
    def __enter__(self):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   107
        global TRACED_OIDS
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   108
        TRACED_OIDS = self.traced
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   109
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   110
    def __exit__(self, exctype, exc, traceback):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   111
        global TRACED_OIDS
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   112
        TRACED_OIDS = ()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   113
        return traceback is None
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   114
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   115
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   116
def score_interface(cls_or_inst, cls, iface):
1907
0f3363d24239 dubious docstring; hard-to-understand function
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1784
diff changeset
   117
    """Return XXX if the give object (maybe an instance or class) implements
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   118
    the interface.
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   119
    """
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   120
    if getattr(iface, '__registry__', None) == 'etypes':
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   121
        # adjust score if the interface is an entity class
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   122
        parents = cls_or_inst.parent_classes()
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   123
        if iface is cls:
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   124
            return len(parents) + 4
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   125
        if iface is parents[-1]: # Any
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   126
            return 1
1784
f0fb914e57db already a class
sylvain.thenault@logilab.fr
parents: 1694
diff changeset
   127
        for index, basecls in enumerate(reversed(parents[:-1])):
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   128
            if iface is basecls:
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   129
                return index + 3
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   130
        return 0
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   131
    if implements_iface(cls_or_inst, iface):
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   132
        # implenting an interface takes precedence other special Any interface
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   133
        return 2
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   134
    return 0
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   135
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   136
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   137
# abstract selectors ##########################################################
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   138
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   139
class PartialSelectorMixIn(object):
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   140
    """convenience mix-in for selectors that will look into the containing
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   141
    class to find missing information.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   142
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   143
    cf. `cubicweb.web.action.LinkToEntityAction` for instance
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   144
    """
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   145
    def __call__(self, cls, *args, **kwargs):
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   146
        self.complete(cls)
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   147
        return super(PartialSelectorMixIn, self).__call__(cls, *args, **kwargs)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   148
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   149
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   150
class ImplementsMixIn(object):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   151
    """mix-in class for selectors checking implemented interfaces of something
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   152
    """
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
   153
    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
   154
        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
   155
        self.expected_ifaces = expected_ifaces
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   156
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   157
    def __str__(self):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   158
        return '%s(%s)' % (self.__class__.__name__,
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   159
                           ','.join(str(s) for s in self.expected_ifaces))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   160
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   161
    def score_interfaces(self, cls_or_inst, cls):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   162
        score = 0
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   163
        vreg, eschema = cls_or_inst.vreg, cls_or_inst.e_schema
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   164
        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
   165
            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
   166
                # entity type
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   167
                try:
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
   168
                    iface = vreg['etypes'].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
   169
                except KeyError:
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   170
                    continue # entity type not in the schema
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   171
            score += score_interface(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
   172
        return score
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   173
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   174
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   175
class EClassSelector(Selector):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   176
    """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
   177
    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
   178
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   179
    * if row is specified, return the score returned by the score_class method
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   180
      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
   181
    * 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
   182
      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
   183
      - `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
   184
        returned
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   185
      - `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
   186
        returned
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   187
    """
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
   188
    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
   189
        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
   190
        self.accept_none = accept_none
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   191
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   192
    @lltrace
2161
200481e7b156 prepare time where it won't be mandatory to give rset to select()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   193
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   194
        if not rset:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   195
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   196
        score = 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   197
        if row is None:
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
   198
            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
   199
                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
   200
                    return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   201
            for etype in rset.column_types(col):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   202
                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
   203
                    return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   204
                escore = self.score(cls, req, etype)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   205
                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
   206
                    return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   207
                elif self.once_is_enough:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   208
                    return escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   209
                score += escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   210
        else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   211
            etype = rset.description[row][col]
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   212
            if etype is not None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   213
                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
   214
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   215
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   216
    def score(self, cls, req, etype):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   217
        if etype in BASE_TYPES:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   218
            return 0
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
   219
        return self.score_class(cls.vreg['etypes'].etype_class(etype), req)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   220
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   221
    def score_class(self, eclass, req):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   222
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   223
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   224
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   225
class EntitySelector(EClassSelector):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   226
    """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
   227
    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
   228
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   229
    * 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
   230
      method for this entity
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   231
    * 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
   232
      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
   233
    * 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
   234
      entity found in the specified column, unless:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   235
      - `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
   236
        returned
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   237
      - `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
   238
        returned
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   239
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   240
    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
   241
          considered.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   242
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   243
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   244
    @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
   245
    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
   246
        if not rset and not kwargs.get('entity'):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   247
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   248
        score = 0
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   249
        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
   250
            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
   251
        elif row is None:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   252
            col = col or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   253
            for row, rowvalue in enumerate(rset.rows):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   254
                if rowvalue[col] is None: # outer join
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   255
                    continue
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 650
diff changeset
   256
                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
   257
                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
   258
                    return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   259
                elif self.once_is_enough:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   260
                    return escore
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   261
                score += escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   262
        else:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   263
            col = col or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   264
            etype = rset.description[row][col]
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   265
            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
   266
                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
   267
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   268
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   269
    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
   270
        try:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   271
            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
   272
        except NotAnEntity:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   273
            return 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   274
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   275
    def score_entity(self, entity):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   276
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   277
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   278
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   279
# very basic selectors ########################################################
1138
22f634977c95 make pylint happy, fix some bugs on the way
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   280
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   281
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   282
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   283
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
   284
    """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
   285
    if rset is None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   286
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   287
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   288
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   289
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   290
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   291
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
   292
    """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
   293
    if rset is not None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   294
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   295
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   296
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   297
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   298
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   299
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
   300
    """accept any non empty result set"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   301
    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
   302
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   303
    return 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   304
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   305
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   306
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   307
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
   308
    """accept empty result set"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   309
    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
   310
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   311
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   312
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   313
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   314
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   315
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
   316
    """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
   317
    else accepts anyway
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   318
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   319
    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
   320
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   321
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   322
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   323
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   324
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   325
def two_lines_rset(cls, req, rset=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   326
    """accept result set with *at least* two lines of result"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   327
    if rset is not None and rset.rowcount > 1:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   328
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   329
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   330
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   331
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   332
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   333
def two_cols_rset(cls, req, rset=None, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   334
    """accept result set with at least one line and two columns of result"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   335
    if rset is not None and rset.rowcount and len(rset.rows[0]) > 1:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   336
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   337
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   338
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   339
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   340
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   341
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
   342
    """accept result set with more lines than the page size.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   343
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   344
    Page size is searched in (respecting order):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   345
    * a page_size argument
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   346
    * a page_size form parameters
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   347
    * the navigation.page-size property
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   348
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   349
    page_size = kwargs.get('page_size')
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   350
    if page_size is None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   351
        page_size = req.form.get('page_size')
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   352
        if page_size is None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   353
            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
   354
        else:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   355
            page_size = int(page_size)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   356
    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
   357
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   358
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   359
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   360
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   361
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   362
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
   363
    """accept sorted result set"""
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   364
    rqlst = rset.syntax_tree()
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   365
    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
   366
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   367
    return 2
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   368
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   369
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   370
@lltrace
2081
7f906fe1c5b7 make rset optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2003
diff changeset
   371
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
   372
    """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
   373
    of the same type
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   374
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   375
    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
   376
        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   377
    if len(rset.column_types(col)) != 1:
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 1
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 two_etypes_rset(cls, req, rset=None, col=0, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   384
    """accept result set where entities in the specified column (or 0) are not
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   385
    of the same type
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   386
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   387
    if rset:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   388
        etypes = rset.column_types(col)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   389
        if len(etypes) > 1:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   390
            return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   391
    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   392
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   393
class non_final_entity(EClassSelector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   394
    """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
   395
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   396
    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
   397
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   398
    def score(self, cls, req, etype):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   399
        if etype in BASE_TYPES:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   400
            return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   401
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   402
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   403
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   404
@lltrace
828
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   405
def authenticated_user(cls, req, *args, **kwargs):
1492
sylvain.thenault@logilab.fr
parents: 1474
diff changeset
   406
    """accept if user is authenticated"""
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   407
    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
   408
        return 0
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   409
    return 1
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   410
828
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   411
def anonymous_user():
394927376a01 two use cases for the 'not' selector
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 810
diff changeset
   412
    return ~ authenticated_user()
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   413
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   414
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   415
@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
   416
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
   417
    """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
   418
    is given
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   419
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   420
    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
   421
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   422
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   423
697
06807984e610 provide objectify_selector decorator for very simple selectors
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 696
diff changeset
   424
@objectify_selector
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   425
@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
   426
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
   427
                       **kwargs):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   428
    """accept if:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   429
    * no context given
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   430
    * 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
   431
      given cls
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   432
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   433
    propval = req.property_value('%s.%s.context' % (cls.__registry__, cls.id))
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   434
    if not propval:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   435
        propval = cls.context
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   436
    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
   437
        return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   438
    return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   439
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   440
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   441
class match_search_state(Selector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   442
    """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
   443
    states given to the initializer
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   444
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   445
    :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
   446
                     object to create a relation with another)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   447
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   448
    def __init__(self, *expected):
774
48cb1f42e79c tell on which class the assertion's failed
sylvain.thenault@logilab.fr
parents: 770
diff changeset
   449
        assert expected, self
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   450
        self.expected = frozenset(expected)
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   451
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   452
    def __str__(self):
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   453
        return '%s(%s)' % (self.__class__.__name__,
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   454
                           ','.join(sorted(str(s) for s in self.expected)))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   455
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   456
    @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
   457
    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
   458
        try:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   459
            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
   460
                return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   461
        except AttributeError:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   462
            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
   463
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   464
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   465
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   466
class match_form_params(match_search_state):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   467
    """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
   468
    in request's form parameters
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   469
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   470
    :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
   471
                      found in request's form parameters
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   472
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   473
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   474
    @lltrace
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   475
    def __call__(self, cls, req, *args, **kwargs):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   476
        score = 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   477
        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
   478
            if not param in req.form:
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   479
                return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   480
            score += 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   481
        return len(self.expected)
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
class match_kwargs(match_search_state):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   485
    """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
   486
    in named arguments given to the selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   487
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   488
    :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
   489
                      found in named arguments (kwargs)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   490
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   491
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   492
    @lltrace
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   493
    def __call__(self, cls, req, *args, **kwargs):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   494
        for arg in self.expected:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   495
            if not arg in kwargs:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   496
                return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   497
        return len(self.expected)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   498
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   499
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   500
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
   501
    """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
   502
    score is the number of groups in which the user is.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   503
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   504
    If the special 'owners' group is given:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   505
    * 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
   506
      logged user
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   507
    * 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
   508
      user
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   509
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   510
    :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
   511
                             user should be
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   512
    """
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
    @lltrace
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   515
    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
   516
        user = req.user
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   517
        if user is None:
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   518
            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
   519
        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
   520
        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
   521
            if row is not None:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   522
                if not user.owns(rset[row][col]):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   523
                    return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   524
                score = 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   525
            else:
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   526
                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
   527
        return score
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   528
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   529
1503
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   530
class match_transition(match_search_state):
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   531
    @lltrace
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   532
    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
   533
        try:
3350
fa77640a9155 since we have the transition entity, give it directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3346
diff changeset
   534
            # 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
   535
            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
   536
                return 0
fa77640a9155 since we have the transition entity, give it directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3346
diff changeset
   537
        except KeyError:
1503
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   538
            return 0
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   539
        return 1
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   540
5cc3afa14e4b new match_transition selector
sylvain.thenault@logilab.fr
parents: 1492
diff changeset
   541
1263
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   542
class match_view(match_search_state):
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   543
    """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
   544
    initializer
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   545
    """
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   546
    @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
   547
    def __call__(self, cls, req, rset=None, row=None, col=0, view=None, **kwargs):
1263
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   548
        if view is None or not view.id in self.expected:
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   549
            return 0
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   550
        return 1
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   551
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   552
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   553
class appobject_selectable(Selector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   554
    """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
   555
    context.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   556
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   557
    :param registry: a registry name (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   558
    :param oid: an object identifier (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   559
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   560
    def __init__(self, registry, oid):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   561
        self.registry = registry
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   562
        self.oid = oid
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   563
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
   564
    def __call__(self, cls, req, **kwargs):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   565
        try:
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
   566
            cls.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
   567
            return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   568
        except NoSelectableObject:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   569
            return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   570
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   571
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   572
# not so basic selectors ######################################################
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   573
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   574
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
   575
    """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
   576
    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
   577
    implemented interfaces.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   578
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   579
    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
   580
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   581
    :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
   582
                             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
   583
                             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
   584
                             registry (at selection time)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   585
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   586
    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
   587
          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
   588
    """
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   589
    def score_class(self, eclass, req):
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   590
        return self.score_interfaces(eclass, eclass)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   591
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   592
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   593
class specified_etype_implements(implements):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   594
    """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
   595
    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
   596
    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
   597
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   598
    :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
   599
                             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
   600
                             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
   601
                             registry (at selection time)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   602
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   603
    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
   604
          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
   605
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   606
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   607
    @lltrace
789
sylvain.thenault@logilab.fr
parents: 788
diff changeset
   608
    def __call__(self, cls, req, *args, **kwargs):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   609
        try:
2514
c745dfb2734e [selectors] change specified_etype_implements: kwargs prevails on req.form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2381
diff changeset
   610
            etype = kwargs['etype']
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   611
        except KeyError:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   612
            try:
2514
c745dfb2734e [selectors] change specified_etype_implements: kwargs prevails on req.form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2381
diff changeset
   613
                etype = req.form['etype']
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   614
            except KeyError:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   615
                return 0
3346
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   616
            else:
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   617
                # 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
   618
                # 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
   619
                try:
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   620
                    etype = cls.vreg.case_insensitive_etypes[etype.lower()]
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   621
                    req.form['etype'] = etype
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   622
                except KeyError:
b1fd9d4ef579 fix case insensitive selector for entity creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3345
diff changeset
   623
                    return 0
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
   624
        return self.score_class(cls.vreg['etypes'].etype_class(etype), req)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   625
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   626
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   627
class entity_implements(ImplementsMixIn, EntitySelector):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   628
    """accept if entity instances found in the result set implements at least one
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   629
    of the interfaces given as argument. Returned score is the number of
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   630
    implemented interfaces.
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   631
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   632
    See `EntitySelector` documentation for behaviour when row is not specified.
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   633
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   634
    :param *expected_ifaces: expected interfaces. An interface may be a class
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   635
                             or an entity type (e.g. `basestring`) in which case
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   636
                             the associated class will be searched in the
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   637
                             registry (at selection time)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   638
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   639
    note: when interface is an entity class, the score will reflect class
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   640
          proximity so the most specific object'll be selected
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   641
    """
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   642
    def score_entity(self, entity):
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   643
        return self.score_interfaces(entity, entity.__class__)
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   644
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   645
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   646
class relation_possible(EClassSelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   647
    """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
   648
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   649
    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
   650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   651
    :param rtype: a relation type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   652
    :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
   653
                 'object', default to 'subject'.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   654
    :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
   655
                        target type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   656
    :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
   657
                   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
   658
                   be returned
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   659
    """
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   660
    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
   661
                 action='read', once_is_enough=False):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   662
        super(relation_possible, self).__init__(once_is_enough)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   663
        self.rtype = rtype
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   664
        self.role = role
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   665
        self.target_etype = target_etype
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   666
        self.action = action
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   667
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   668
    @lltrace
657
fd019f41aa2f work in progress - fix deprecation of EntityAction - fix various selectors bugs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 656
diff changeset
   669
    def __call__(self, cls, req, *args, **kwargs):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   670
        rschema = cls.schema.rschema(self.rtype)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   671
        if not (rschema.has_perm(req, self.action)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   672
                or rschema.has_local_role(self.action)):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   673
            return 0
3345
10ad3869fc92 [selector] check read perm if action is add/update/delete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3276
diff changeset
   674
        if self.action != 'read':
10ad3869fc92 [selector] check read perm if action is add/update/delete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3276
diff changeset
   675
            if not (rschema.has_perm(req, 'read')
10ad3869fc92 [selector] check read perm if action is add/update/delete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3276
diff changeset
   676
                    or rschema.has_local_role('read')):
10ad3869fc92 [selector] check read perm if action is add/update/delete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3276
diff changeset
   677
                return 0
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   678
        score = super(relation_possible, self).__call__(cls, req, *args, **kwargs)
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   679
        return score
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   680
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   681
    def score_class(self, eclass, req):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   682
        eschema = eclass.e_schema
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   683
        try:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   684
            if self.role == 'object':
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   685
                rschema = eschema.object_relation(self.rtype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   686
            else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   687
                rschema = eschema.subject_relation(self.rtype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   688
        except KeyError:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   689
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   690
        if self.target_etype is not None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   691
            try:
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   692
                if self.role == 'subject':
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   693
                    return int(self.target_etype in rschema.objects(eschema))
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   694
                else:
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   695
                    return int(self.target_etype in rschema.subjects(eschema))
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1037
diff changeset
   696
            except KeyError:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   697
                return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   698
        return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   699
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   700
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   701
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
   702
    """partial version of the relation_possible selector
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   703
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   704
    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
   705
    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
   706
    for this selector are:
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   707
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   708
    - `rtype`: same as `rtype` parameter of the `relation_possible` selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   709
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   710
    - `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
   711
      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
   712
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   713
    - `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
   714
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   715
    :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
   716
                   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
   717
                   be returned
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   718
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   719
    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
   720
        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
   721
                                                        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
   722
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   723
    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
   724
        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
   725
        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
   726
        self.target_etype = getattr(cls, 'etype', None)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   727
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   728
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   729
class may_add_relation(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   730
    """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
   731
    by the logged user.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   732
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   733
    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
   734
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   735
    :param rtype: a relation type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   736
    :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
   737
                 'object', default to 'subject'.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   738
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   739
770
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   740
    def __init__(self, rtype, role='subject', once_is_enough=False):
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   741
        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
   742
        self.rtype = rtype
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   743
        self.role = role
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   744
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   745
    def score_entity(self, entity):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   746
        rschema = entity.schema.rschema(self.rtype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   747
        if self.role == 'subject':
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   748
            if not rschema.has_perm(entity.req, 'add', fromeid=entity.eid):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   749
                return 0
835
7dcb11dd443e fix relation_possible, ensure we return int
sylvain.thenault@logilab.fr
parents: 833
diff changeset
   750
        elif not rschema.has_perm(entity.req, 'add', toeid=entity.eid):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   751
            return 0
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   752
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   753
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   754
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   755
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
   756
    """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
   757
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   758
    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
   759
    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
   760
    for this selector are:
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   761
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   762
    - `rtype`: same as `rtype` parameter of the `relation_possible` selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   763
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   764
    - `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
   765
      to determine the role of class in the relation.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   766
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   767
    :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
   768
                   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
   769
                   be returned
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   770
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   771
    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
   772
        super(partial_may_add_relation, self).__init__(None, None, once_is_enough)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   773
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   774
    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
   775
        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
   776
        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
   777
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   778
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   779
class has_related_entities(EntitySelector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   780
    """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
   781
    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
   782
    type). Checks first if the relation is possible.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   783
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   784
    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
   785
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   786
    :param rtype: a relation type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   787
    :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
   788
                 'object', default to 'subject'.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   789
    :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
   790
                        target type (`basestring`)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   791
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   792
    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
   793
                 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
   794
        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
   795
        self.rtype = rtype
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   796
        self.role = role
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   797
        self.target_etype = target_etype
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   798
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   799
    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
   800
        relpossel = relation_possible(self.rtype, self.role, self.target_etype)
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   801
        if not relpossel.score_class(entity.__class__, entity.req):
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   802
            return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   803
        rset = entity.related(self.rtype, self.role)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   804
        if self.target_etype:
1011
22812cfe36b4 fix w/ rset with more than one column
sylvain.thenault@logilab.fr
parents: 876
diff changeset
   805
            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
   806
        return rset and 1 or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   807
833
8c6bfd9158fb bw compat for selection for creation forms
sylvain.thenault@logilab.fr
parents: 828
diff changeset
   808
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   809
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
   810
    """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
   811
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   812
    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
   813
    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
   814
    for this selector are:
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   815
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   816
    - `rtype`: same as `rtype` parameter of the `relation_possible` selector
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   817
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   818
    - `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
   819
      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
   820
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   821
    - `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
   822
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   823
    :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
   824
                   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
   825
                   be returned
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   826
    """
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   827
    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
   828
        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
   829
                                                           None, once_is_enough)
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   830
    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
   831
        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
   832
        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
   833
        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
   834
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   835
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   836
class has_permission(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   837
    """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
   838
    set entity.
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   839
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   840
    * 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
   841
      instance found in the specified cell
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   842
    * 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
   843
      in the found in the specified column
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   844
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   845
    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
   846
          considered.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   847
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   848
    :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
   849
    """
770
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   850
    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
   851
        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
   852
        self.action = action
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   853
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   854
    @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
   855
    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
   856
        if rset is None:
d62fb3e9797d protect against None rset
sylvain.thenault@logilab.fr
parents: 784
diff changeset
   857
            return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   858
        user = req.user
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   859
        action = self.action
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   860
        if row is None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   861
            score = 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   862
            need_local_check = []
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   863
            geteschema = cls.schema.eschema
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   864
            for etype in rset.column_types(0):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   865
                if etype in BASE_TYPES:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   866
                    return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   867
                eschema = geteschema(etype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   868
                if not user.matching_groups(eschema.get_groups(action)):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   869
                    if eschema.has_local_role(action):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   870
                        # have to ckeck local roles
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   871
                        need_local_check.append(eschema)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   872
                        continue
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   873
                    else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   874
                        # even a local role won't be enough
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   875
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   876
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   877
            if need_local_check:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   878
                # check local role for entities of necessary types
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   879
                for i, row in enumerate(rset):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   880
                    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
   881
                        continue
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 650
diff changeset
   882
                    if not self.score(req, rset, i, col):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   883
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   884
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   885
            return score
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   886
        return self.score(req, rset, row, col)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   887
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   888
    def score_entity(self, entity):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   889
        if entity.has_perm(self.action):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   890
            return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   891
        return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   892
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   893
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   894
class has_add_permission(EClassSelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   895
    """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
   896
    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
   897
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   898
    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
   899
    """
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   900
    def score(self, cls, req, etype):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   901
        eschema = cls.schema.eschema(etype)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   902
        if not (eschema.is_final() or eschema.is_subobject(strict=True)) \
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   903
               and eschema.has_perm(req, 'add'):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   904
            return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   905
        return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   906
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   907
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   908
class rql_condition(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   909
    """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
   910
    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
   911
    condition.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   912
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   913
    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
   914
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   915
    :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
   916
                       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
   917
                       to represent the logged user
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   918
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   919
    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
   920
    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
   921
    """
766
33ede72b22b8 fix match_user_groups, appobject_selectable, searchstate_accept* compat selectors
sylvain.thenault@logilab.fr
parents: 764
diff changeset
   922
    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
   923
        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
   924
        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
   925
            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
   926
        else:
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   927
            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
   928
        self.rql = rql
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   929
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   930
    def score(self, req, rset, row, col):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   931
        try:
764
9de67b681624 some test fixes
sylvain.thenault@logilab.fr
parents: 759
diff changeset
   932
            return len(req.execute(self.rql, {'x': rset[row][col],
9de67b681624 some test fixes
sylvain.thenault@logilab.fr
parents: 759
diff changeset
   933
                                              'u': req.user.eid}, 'x'))
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   934
        except Unauthorized:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   935
            return 0
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   936
1887
7e19c94ce0d7 [selectors] provide a nicer representation of rql_condition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1784
diff changeset
   937
    def __repr__(self):
7e19c94ce0d7 [selectors] provide a nicer representation of rql_condition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1784
diff changeset
   938
        return u'<rql_condition "%s" at %x>' % (self.rql, id(self))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   939
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
   940
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   941
class but_etype(EntitySelector):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   942
    """accept if the given entity types are not found in the result set.
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   943
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   944
    See `EntitySelector` documentation for behaviour when row is not specified.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   945
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   946
    :param *etypes: entity types (`basestring`) which should be refused
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   947
    """
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   948
    def __init__(self, *etypes):
770
193b7e981ea9 each subclass of EntitySelector should call its __init__ method
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 769
diff changeset
   949
        super(but_etype, self).__init__()
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   950
        self.but_etypes = etypes
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   951
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   952
    def score(self, req, rset, row, col):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   953
        if rset.description[row][col] in self.but_etypes:
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   954
            return 0
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   955
        return 1
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   956
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   957
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   958
class score_entity(EntitySelector):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   959
    """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
   960
    found in the result set.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   961
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   962
    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
   963
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   964
    :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
   965
                      return a score >= 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   966
    """
764
9de67b681624 some test fixes
sylvain.thenault@logilab.fr
parents: 759
diff changeset
   967
    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
   968
        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
   969
        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
   970
            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
   971
            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
   972
                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
   973
            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
   974
                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
   975
            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
   976
        self.score_entity = intscore
2972
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   977
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   978
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   979
# XXX DEPRECATED ##############################################################
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   980
from cubicweb.vregistry import chainall
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   981
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   982
yes_selector = deprecated()(yes)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   983
norset_selector = deprecated()(none_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   984
rset_selector = deprecated()(any_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   985
anyrset_selector = deprecated()(nonempty_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   986
emptyrset_selector = deprecated()(empty_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   987
onelinerset_selector = deprecated()(one_line_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   988
twolinerset_selector = deprecated()(two_lines_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   989
twocolrset_selector = deprecated()(two_cols_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   990
largerset_selector = deprecated()(paginated_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   991
sortedrset_selector = deprecated()(sorted_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   992
oneetyperset_selector = deprecated()(one_etype_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   993
multitype_selector = deprecated()(two_etypes_rset)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   994
anonymous_selector = deprecated()(anonymous_user)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   995
not_anonymous_selector = deprecated()(authenticated_user)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   996
primaryview_selector = deprecated()(primary_view)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   997
contextprop_selector = deprecated()(match_context_prop)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   998
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
   999
@deprecated('use non_final_entity instead of %s')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1000
def nfentity_selector(cls, req, rset=None, row=None, col=0, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1001
    return non_final_entity()(cls, req, rset, row, col)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1002
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1003
@deprecated('use implements instead of %s')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1004
def implement_interface(cls, req, rset=None, row=None, col=0, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1005
    return implements(*cls.accepts_interfaces)(cls, req, rset, row, col)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1006
_interface_selector = deprecated()(implement_interface)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1007
interface_selector = deprecated()(implement_interface)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1008
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1009
@deprecated('use specified_etype_implements instead of %s')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1010
def accept_etype(cls, req, *args, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1011
    """check etype presence in request form *and* accepts conformance"""
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1012
    return specified_etype_implements(*cls.accepts)(cls, req, *args)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1013
etype_form_selector = accept_etype
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1014
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1015
@deprecated('use match_search_state instead of %s')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1016
def searchstate_selector(cls, req, rset=None, row=None, col=0, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1017
    return match_search_state(cls.search_states)(cls, req, rset, row, col)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1018
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1019
@deprecated('use match_user_groups instead of %s')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1020
def match_user_group(cls, req, rset=None, row=None, col=0, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1021
    return match_user_groups(*cls.require_groups)(cls, req, rset, row, col, **kwargs)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1022
in_group_selector = match_user_group
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1023
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1024
@deprecated('use relation_possible instead of %s')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1025
def has_relation(cls, req, rset=None, row=None, col=0, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1026
    return relation_possible(cls.rtype, role(cls), cls.etype,
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1027
                             getattr(cls, 'require_permission', 'read'))(cls, req, rset, row, col, **kwargs)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1028
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1029
@deprecated('use relation_possible instead of %s')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1030
def one_has_relation(cls, req, rset=None, row=None, col=0, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1031
    return relation_possible(cls.rtype, role(cls), cls.etype,
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1032
                             getattr(cls, 'require_permission', 'read',
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1033
                                     once_is_enough=True))(cls, req, rset, row, col, **kwargs)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1034
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1035
@deprecated('use implements instead of %s')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1036
def accept_rset(cls, req, rset=None, row=None, col=0, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1037
    """simply delegate to cls.accept_rset method"""
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1038
    return implements(*cls.accepts)(cls, req, rset, row=row, col=col)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1039
accept_rset_selector = accept_rset
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1040
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1041
accept = chainall(non_final_entity(), accept_rset, name='accept')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1042
accept = deprecated('use implements selector')(accept)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1043
accept_selector = deprecated()(accept)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1044
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1045
accept_one = deprecated()(chainall(one_line_rset, accept,
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1046
                                   name='accept_one'))
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1047
accept_one_selector = deprecated()(accept_one)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1048
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1049
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1050
def _rql_condition(cls, req, rset=None, row=None, col=0, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1051
    if cls.condition:
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1052
        return rql_condition(cls.condition)(cls, req, rset, row, col)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1053
    return 1
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1054
_rqlcondition_selector = deprecated()(_rql_condition)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1055
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1056
rqlcondition_selector = deprecated()(chainall(non_final_entity(), one_line_rset, _rql_condition,
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1057
                         name='rql_condition'))
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1058
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1059
@deprecated('use but_etype instead of %s')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1060
def but_etype_selector(cls, req, rset=None, row=None, col=0, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1061
    return but_etype(cls.etype)(cls, req, rset, row, col)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1062
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1063
@lltrace
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1064
def etype_rtype_selector(cls, req, rset=None, row=None, col=0, **kwargs):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1065
    schema = cls.schema
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1066
    perm = getattr(cls, 'require_permission', 'read')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1067
    if hasattr(cls, 'etype'):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1068
        eschema = schema.eschema(cls.etype)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1069
        if not (eschema.has_perm(req, perm) or eschema.has_local_role(perm)):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1070
            return 0
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1071
    if hasattr(cls, 'rtype'):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1072
        rschema = schema.rschema(cls.rtype)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1073
        if not (rschema.has_perm(req, perm) or rschema.has_local_role(perm)):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1074
            return 0
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1075
    return 1
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1076
etype_rtype_selector = deprecated()(etype_rtype_selector)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1077
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1078
#req_form_params_selector = deprecated()(match_form_params) # form_params
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1079
#kwargs_selector = deprecated()(match_kwargs) # expected_kwargs
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1080
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1081
# compound selectors ##########################################################
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1082
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1083
searchstate_accept = chainall(nonempty_rset(), accept,
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1084
                              name='searchstate_accept')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1085
searchstate_accept_selector = deprecated()(searchstate_accept)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1086
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1087
searchstate_accept_one = chainall(one_line_rset, accept, _rql_condition,
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1088
                                  name='searchstate_accept_one')
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1089
searchstate_accept_one_selector = deprecated()(searchstate_accept_one)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1090
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1091
searchstate_accept = deprecated()(searchstate_accept)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1092
searchstate_accept_one = deprecated()(searchstate_accept_one)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1093
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1094
# end of deprecation section ##################################################
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1095
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1096
def unbind_method(selector):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1097
    def new_selector(registered):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1098
        # get the unbound method
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1099
        if hasattr(registered, 'im_func'):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1100
            registered = registered.im_func
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1101
        # don't rebind since it will be done automatically during
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1102
        # the assignment, inside the destination class body
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1103
        return selector(registered)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1104
    new_selector.__name__ = selector.__name__
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1105
    return new_selector
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1106
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1107
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1108
def deprecate(registered, msg):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1109
    # get the unbound method
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1110
    if hasattr(registered, 'im_func'):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1111
        registered = registered.im_func
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1112
    def _deprecate(cls, vreg):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1113
        warn(msg, DeprecationWarning)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1114
        return registered(cls, vreg)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1115
    return _deprecate
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1116
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1117
@unbind_method
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1118
def require_group_compat(registered):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1119
    def plug_selector(cls, vreg):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1120
        cls = registered(cls, vreg)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1121
        if getattr(cls, 'require_groups', None):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1122
            warn('use "match_user_groups(group1, group2)" instead of using require_groups',
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1123
                 DeprecationWarning)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1124
            cls.__select__ &= match_user_groups(cls.require_groups)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1125
        return cls
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1126
    return plug_selector
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1127
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1128
@unbind_method
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1129
def accepts_compat(registered):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1130
    def plug_selector(cls, vreg):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1131
        cls = registered(cls, vreg)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1132
        if getattr(cls, 'accepts', None):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1133
            warn('use "implements("EntityType", IFace)" instead of using accepts on %s'
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1134
                 % cls,
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1135
                 DeprecationWarning)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1136
            cls.__select__ &= implements(*cls.accepts)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1137
        return cls
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1138
    return plug_selector
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1139
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1140
@unbind_method
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1141
def accepts_etype_compat(registered):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1142
    def plug_selector(cls, vreg):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1143
        cls = registered(cls, vreg)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1144
        if getattr(cls, 'accepts', None):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1145
            warn('use "specified_etype_implements("EntityType", IFace)" instead of using accepts',
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1146
                 DeprecationWarning)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1147
            cls.__select__ &= specified_etype_implements(*cls.accepts)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1148
        return cls
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1149
    return plug_selector
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1150
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1151
@unbind_method
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1152
def condition_compat(registered):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1153
    def plug_selector(cls, vreg):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1154
        cls = registered(cls, vreg)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1155
        if getattr(cls, 'condition', None):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1156
            warn('use "use rql_condition(expression)" instead of using condition',
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1157
                 DeprecationWarning)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1158
            cls.__select__ &= rql_condition(cls.condition)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1159
        return cls
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1160
    return plug_selector
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1161
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1162
@unbind_method
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1163
def has_relation_compat(registered):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1164
    def plug_selector(cls, vreg):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1165
        cls = registered(cls, vreg)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1166
        if getattr(cls, 'etype', None):
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1167
            warn('use relation_possible selector instead of using etype_rtype',
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1168
                 DeprecationWarning)
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1169
            cls.__select__ &= relation_possible(cls.rtype, role(cls),
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1170
                                                getattr(cls, 'etype', None),
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1171
                                                action=getattr(cls, 'require_permission', 'read'))
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1172
        return cls
23418c13e024 Backed out changeset d83f5d96e1d7
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2970
diff changeset
  1173
    return plug_selector