cubicweb/predicates.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Fri, 22 Mar 2019 17:42:36 +0100
changeset 12542 85194bd49119
parent 12508 a8c1ea390400
child 12567 26744ad37953
permissions -rw-r--r--
Drop more deprecated code This follows up on changeset a8c1ea390400, in which code deprecated using logilab.common.deprecation got dropped. Now we also drop code deprecated using stdlib's warn(<msg>, DeprecationWarning). Notice that, as a consequence of dropping old/new etypes aliases in cubicweb/schema.py, we drop the import ETYPE_NAME_MAP (no longer needed); but since other modules imported that name from cubicweb.schema, we need to update the import statement to use "cubicweb" directly.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9547
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
     1
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5306
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
10499
d0907690af55 [doc] move the documentations from docstring directly to the book.
David Douard <david.douard@logilab.fr>
parents: 10498
diff changeset
    18
"""Predicate classes
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    19
"""
5886
00a78298d30d cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5732
diff changeset
    20
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11129
diff changeset
    21
634
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
import logging
4719
aaed3f813ef8 kill dead/useless code as suggested by pylint
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4664
diff changeset
    24
from warnings import warn
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
    25
from operator import eq
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    26
10613
8d9fe02387e3 [py3k] six.integer_types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10612
diff changeset
    27
from six import string_types, integer_types
10609
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10599
diff changeset
    28
from six.moves import range
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10599
diff changeset
    29
12508
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11956
diff changeset
    30
from logilab.common.registry import Predicate, objectify_predicate
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    31
6106
1e6d93f70d14 [selectors] fix match_transition & introduce new edited_attribute selector
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6046
diff changeset
    32
from yams.schema import BASE_TYPES, role_name
5944
b962dff47c36 [ftirank] when ordered by fti rank, we don't want page navigation. Anyway, sorted nav component shouldn't consider has_text relation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5904
diff changeset
    33
from rql.nodes import Function
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    34
5881
57387070f612 [selectors] use before-registry-reset event to init is_instance cache: cleaner code and avoid reloading bug (making hooks test fail for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
    35
from cubicweb import (Unauthorized, NoSelectableObject, NotAnEntity,
57387070f612 [selectors] use before-registry-reset event to init is_instance cache: cleaner code and avoid reloading bug (making hooks test fail for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
    36
                      CW_EVENT_MANAGER, role)
6106
1e6d93f70d14 [selectors] fix match_transition & introduce new edited_attribute selector
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6046
diff changeset
    37
from cubicweb.uilib import eid_param
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    38
from cubicweb.schema import split_expression
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    39
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
    40
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    41
# abstract predicates / mixin helpers ###########################################
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
    42
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    43
class PartialPredicateMixIn(object):
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    44
    """convenience mix-in for predicates that will look into the containing
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
    45
    class to find missing information.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
    46
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
    47
    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
    48
    """
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
    49
    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
    50
        self.complete(cls)
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    51
        return super(PartialPredicateMixIn, self).__call__(cls, *args, **kwargs)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    52
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
    53
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    54
class EClassPredicate(Predicate):
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    55
    """abstract class for predicates working on *entity class(es)* specified
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    56
    explicitly or found of the result set.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    57
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    58
    Here are entity lookup / scoring rules:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    59
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    60
    * if `entity` is specified, return score for this entity's class
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
    61
7610
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    62
    * elif `rset`, `select` and `filtered_variable` are specified, return score
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    63
      for the possible classes for variable in the given rql :class:`Select`
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    64
      node
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    65
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    66
    * elif `rset` and `row` are specified, return score for the class of the
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    67
      entity found in the specified cell, using column specified by `col` or 0
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    68
7610
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    69
    * elif `rset` is specified return score for each entity class found in the
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    70
      column specified specified by the `col` argument or in column 0 if not
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    71
      specified
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    72
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    73
    When there are several classes to be evaluated, return the sum of scores for
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    74
    each entity class unless:
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    75
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
    76
      - `mode` == 'all' (the default) and some entity class is scored
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    77
        to 0, in which case 0 is returned
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    78
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
    79
      - `mode` == 'any', in which case the first non-zero score is
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
    80
        returned
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    81
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    82
      - `accept_none` is False and some cell in the column has a None value
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
    83
        (this may occurs with outer join)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    84
    """
12508
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11956
diff changeset
    85
    def __init__(self, accept_none=True, mode='all'):
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
    86
        assert mode in ('any', 'all'), 'bad mode %s' % mode
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
    87
        self.once_is_enough = mode == 'any'
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
    88
        self.accept_none = accept_none
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
    89
7610
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    90
    def __call__(self, cls, req, rset=None, row=None, col=0, entity=None,
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    91
                 select=None, filtered_variable=None,
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    92
                 accept_none=None,
5565
6113b031605c [selectors] allow to override `accept_none` value of EClassSelector / EntitySelector based selector by specifying a value in selection context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5564
diff changeset
    93
                 **kwargs):
7610
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    94
        if entity is not None:
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    95
            return self.score_class(entity.__class__, req)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    96
        if not rset:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    97
            return 0
7610
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    98
        if select is not None and filtered_variable is not None:
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
    99
            etypes = set(sol[filtered_variable.name] for sol in select.solutions)
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   100
        elif row is None:
5565
6113b031605c [selectors] allow to override `accept_none` value of EClassSelector / EntitySelector based selector by specifying a value in selection context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5564
diff changeset
   101
            if accept_none is None:
6113b031605c [selectors] allow to override `accept_none` value of EClassSelector / EntitySelector based selector by specifying a value in selection context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5564
diff changeset
   102
                accept_none = self.accept_none
7610
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   103
            if not accept_none and \
10599
99e9fe1e633f [predicates] Simplify range(len()) iteration
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10499
diff changeset
   104
                   any(row[col] is None for row in rset):
7610
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   105
                return 0
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   106
            etypes = rset.column_types(col)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   107
        else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   108
            etype = rset.description[row][col]
7610
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   109
            # may have None in rset.description on outer join
7982
77ed9b2fc9a5 [selectors] EClassSelector (eg is_instance & all) should check for None value (possible w/ outer join) when a row is specified. Closes #2033165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   110
            if etype is None or rset.rows[row][col] is None:
7610
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   111
                return 0
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   112
            etypes = (etype,)
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   113
        score = 0
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   114
        for etype in etypes:
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   115
            escore = self.score(cls, req, etype)
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   116
            if not escore and not self.once_is_enough:
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   117
                return 0
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   118
            elif self.once_is_enough:
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   119
                return escore
838a0c910bb5 [selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7559
diff changeset
   120
            score += escore
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   121
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   122
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   123
    def score(self, cls, req, etype):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   124
        if etype in BASE_TYPES:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   125
            return 0
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
   126
        return self.score_class(req.vreg['etypes'].etype_class(etype), req)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   127
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   128
    def score_class(self, eclass, req):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   129
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   130
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   131
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   132
class EntityPredicate(EClassPredicate):
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   133
    """abstract class for predicates working on *entity instance(s)* specified
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   134
    explicitly or found of the result set.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   135
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   136
    Here are entity lookup / scoring rules:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   137
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   138
    * if `entity` is specified, return score for this entity
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   139
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   140
    * elif `row` is specified, return score for the entity found in the
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   141
      specified cell, using column specified by `col` or 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   142
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   143
    * else return the sum of scores for each entity found in the column
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   144
      specified specified by the `col` argument or in column 0 if not specified,
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   145
      unless:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   146
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   147
      - `mode` == 'all' (the default) and some entity class is scored
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   148
        to 0, in which case 0 is returned
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   149
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   150
      - `mode` == 'any', in which case the first non-zero score is
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   151
        returned
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   152
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   153
      - `accept_none` is False and some cell in the column has a None value
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   154
        (this may occurs with outer join)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   155
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   156
    .. Note::
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   157
       using :class:`EntityPredicate` or :class:`EClassPredicate` as base predicate
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   158
       class impacts performance, since when no entity or row is specified the
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   159
       later works on every different *entity class* found in the result set,
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   160
       while the former works on each *entity* (eg each row of the result set),
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   161
       which may be much more costly.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   162
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   163
5565
6113b031605c [selectors] allow to override `accept_none` value of EClassSelector / EntitySelector based selector by specifying a value in selection context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5564
diff changeset
   164
    def __call__(self, cls, req, rset=None, row=None, col=0, accept_none=None,
8481
ff3b163f52e9 [predicates] fix predicates that erroneously evaluate the entity passed as a parameter as a boolean, instead of testing its existence in the keyword arguments -using the kwargs.get('entity') idiom instead of 'entity' in kwargs or similar- ; closes #2424288
Florent Cayré <florent.cayre@logilab.fr>
parents: 8397
diff changeset
   165
                 entity=None, **kwargs):
ff3b163f52e9 [predicates] fix predicates that erroneously evaluate the entity passed as a parameter as a boolean, instead of testing its existence in the keyword arguments -using the kwargs.get('entity') idiom instead of 'entity' in kwargs or similar- ; closes #2424288
Florent Cayré <florent.cayre@logilab.fr>
parents: 8397
diff changeset
   166
        if not rset and entity is None:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   167
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   168
        score = 0
8481
ff3b163f52e9 [predicates] fix predicates that erroneously evaluate the entity passed as a parameter as a boolean, instead of testing its existence in the keyword arguments -using the kwargs.get('entity') idiom instead of 'entity' in kwargs or similar- ; closes #2424288
Florent Cayré <florent.cayre@logilab.fr>
parents: 8397
diff changeset
   169
        if entity is not None:
ff3b163f52e9 [predicates] fix predicates that erroneously evaluate the entity passed as a parameter as a boolean, instead of testing its existence in the keyword arguments -using the kwargs.get('entity') idiom instead of 'entity' in kwargs or similar- ; closes #2424288
Florent Cayré <florent.cayre@logilab.fr>
parents: 8397
diff changeset
   170
            score = self.score_entity(entity)
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   171
        elif row is None:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   172
            col = col or 0
5565
6113b031605c [selectors] allow to override `accept_none` value of EClassSelector / EntitySelector based selector by specifying a value in selection context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5564
diff changeset
   173
            if accept_none is None:
6113b031605c [selectors] allow to override `accept_none` value of EClassSelector / EntitySelector based selector by specifying a value in selection context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5564
diff changeset
   174
                accept_none = self.accept_none
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   175
            for row, rowvalue in enumerate(rset.rows):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   176
                if rowvalue[col] is None: # outer join
5565
6113b031605c [selectors] allow to override `accept_none` value of EClassSelector / EntitySelector based selector by specifying a value in selection context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5564
diff changeset
   177
                    if not accept_none:
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   178
                        return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   179
                    continue
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 650
diff changeset
   180
                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
   181
                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
   182
                    return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   183
                elif self.once_is_enough:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   184
                    return escore
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   185
                score += escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   186
        else:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   187
            col = col or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   188
            etype = rset.description[row][col]
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   189
            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
   190
                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
   191
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   192
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   193
    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
   194
        try:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   195
            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
   196
        except NotAnEntity:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   197
            return 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   198
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   199
    def score_entity(self, entity):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   200
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   201
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   202
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   203
class ExpectedValuePredicate(Predicate):
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   204
    """Take a list of expected values as initializer argument and store them
7173
c6eb201d4410 [selectors] abstract ExpectedValueSelector now accept a set as single argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6919
diff changeset
   205
    into the :attr:`expected` set attribute. You may also give a set as single
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
   206
    argument, which will then be referenced as set of expected values,
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   207
    allowing modifications to the given set to be considered.
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   208
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   209
    You should implement one of :meth:`_values_set(cls, req, **kwargs)` or
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
   210
    :meth:`_get_value(cls, req, **kwargs)` method which should respectively
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   211
    return the set of values or the unique possible value for the given context.
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   212
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   213
    You may also specify a `mode` behaviour as argument, as explained below.
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   214
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   215
    Returned score is:
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   216
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   217
    - 0 if `mode` == 'all' (the default) and at least one expected
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   218
      values isn't found
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   219
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   220
    - 0 if `mode` == 'any' and no expected values isn't found at all
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   221
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   222
    - else the number of matching values
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   223
8032
bcb87336c7d2 [doc] fix most of ReST compilation errors and warnings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   224
    Notice `mode` = 'any' with a single expected value has no effect at all.
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   225
    """
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   226
    def __init__(self, *expected, **kwargs):
774
48cb1f42e79c tell on which class the assertion's failed
sylvain.thenault@logilab.fr
parents: 770
diff changeset
   227
        assert expected, self
10476
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   228
        if len(expected) == 1 and isinstance(expected[0], (set, dict)):
7173
c6eb201d4410 [selectors] abstract ExpectedValueSelector now accept a set as single argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6919
diff changeset
   229
            self.expected = expected[0]
c6eb201d4410 [selectors] abstract ExpectedValueSelector now accept a set as single argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6919
diff changeset
   230
        else:
c6eb201d4410 [selectors] abstract ExpectedValueSelector now accept a set as single argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6919
diff changeset
   231
            self.expected = frozenset(expected)
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   232
        mode = kwargs.pop('mode', 'all')
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   233
        assert mode in ('any', 'all'), 'bad mode %s' % mode
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   234
        self.once_is_enough = mode == 'any'
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   235
        assert not kwargs, 'unexpected arguments %s' % kwargs
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   236
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   237
    def __str__(self):
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   238
        return '%s(%s)' % (self.__class__.__name__,
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   239
                           ','.join(sorted(str(s) for s in self.expected)))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   240
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   241
    def __call__(self, cls, req, **kwargs):
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   242
        values = self._values_set(cls, req, **kwargs)
10476
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   243
        if isinstance(values, dict):
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   244
            if isinstance(self.expected, dict):
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   245
                matching = 0
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   246
                for key, expected_value in self.expected.items():
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   247
                    if key in values:
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   248
                        if (isinstance(expected_value, (list, tuple, frozenset, set))
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   249
                            and values[key] in expected_value):
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   250
                            matching += 1
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   251
                        elif values[key] == expected_value:
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   252
                            matching += 1
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   253
            if isinstance(self.expected, (set, frozenset)):
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   254
                values = frozenset(values)
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   255
                matching = len(values & self.expected)
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   256
        else:
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   257
            matching = len(values & self.expected)
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   258
        if self.once_is_enough:
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   259
            return matching
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   260
        if matching == len(self.expected):
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   261
            return matching
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   262
        return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   263
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   264
    def _values_set(self, cls, req, **kwargs):
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   265
        return frozenset( (self._get_value(cls, req, **kwargs),) )
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   266
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   267
    def _get_value(self, cls, req, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   268
        raise NotImplementedError()
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   269
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   270
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   271
# bare predicates ##############################################################
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   272
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   273
class match_kwargs(ExpectedValuePredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   274
    """Return non-zero score if parameter names specified as initializer
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   275
    arguments are specified in the input context.
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   276
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   277
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   278
    Return a score corresponding to the number of expected parameters.
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   279
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   280
    When multiple parameters are expected, all of them should be found in
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   281
    the input context unless `mode` keyword argument is given to 'any',
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   282
    in which case a single matching parameter is enough.
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   283
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   284
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   285
    def _values_set(self, cls, req, **kwargs):
10476
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
   286
        return kwargs
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   287
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   288
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   289
class appobject_selectable(Predicate):
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   290
    """Return 1 if another appobject is selectable using the same input context.
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   291
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   292
    Initializer arguments:
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   293
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   294
    * `registry`, a registry name
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   295
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   296
    * `regids`, object identifiers in this registry, one of them should be
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   297
      selectable.
1263
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   298
    """
5561
58b05c314443 [selectors] ensure adaptable('IDownloadable') takes precedence over implements('Any')
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5557
diff changeset
   299
    selectable_score = 1
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   300
    def __init__(self, registry, *regids):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   301
        self.registry = registry
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   302
        self.regids = regids
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   303
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
   304
    def __call__(self, cls, req, **kwargs):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   305
        for regid in self.regids:
8862
8011ca5d2841 [predicates] use select_or_none rather than select+try/except, expected to be more efficient
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8535
diff changeset
   306
            if req.vreg[self.registry].select_or_none(regid, req, **kwargs) is not None:
5561
58b05c314443 [selectors] ensure adaptable('IDownloadable') takes precedence over implements('Any')
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5557
diff changeset
   307
                return self.selectable_score
6541
9c3821885443 [selectors] close #1333238: appobject_selectable with multiple regids fails
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6364
diff changeset
   308
        return 0
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   309
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   310
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   311
class adaptable(appobject_selectable):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   312
    """Return 1 if another appobject is selectable using the same input context.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   313
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   314
    Initializer arguments:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   315
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   316
    * `regids`, adapter identifiers (e.g. interface names) to which the context
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   317
      (usually entities) should be adaptable. One of them should be selectable
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   318
      when multiple identifiers are given.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   319
    """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   320
    def __init__(self, *regids):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   321
        super(adaptable, self).__init__('adapters', *regids)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   322
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
   323
    def __call__(self, cls, req, **kwargs):
5567
bb97cd6ded2d [selectors] adaptable selector should not accept None in rset
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5566
diff changeset
   324
        kwargs.setdefault('accept_none', False)
8858
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   325
        score = super(adaptable, self).__call__(cls, req, **kwargs)
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   326
        if score == 0 and kwargs.get('rset') and len(kwargs['rset']) > 1 and not 'row' in kwargs:
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   327
            # on rset containing several entity types, each row may be
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   328
            # individually adaptable, while the whole rset won't be if the
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   329
            # same adapter can't be used for each type
10609
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10599
diff changeset
   330
            for row in range(len(kwargs['rset'])):
8858
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   331
                kwargs.setdefault('col', 0)
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   332
                _score = super(adaptable, self).__call__(cls, req, row=row, **kwargs)
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   333
                if not _score:
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   334
                    return 0
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   335
                # adjust score per row as expected by default adjust_score
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   336
                # implementation
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   337
                score += self.adjust_score(_score)
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   338
        else:
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   339
            score = self.adjust_score(score)
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   340
        return score
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   341
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   342
    @staticmethod
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   343
    def adjust_score(score):
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   344
        # being adaptable to an interface should takes precedence other
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   345
        # is_instance('Any'), but not other explicit
51fdbbbd07b2 [predicates] fix 'adaptable' implementation, used to return 0 on a rset with individualy adaptable entities of different types. Closes #2709663
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8528
diff changeset
   346
        # is_instance('SomeEntityType'), and, for **a single entity**:
6008
e1c43115af3b [selector] adjuts score returned by the adaptable selector to get correct priority over is_instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5944
diff changeset
   347
        # * is_instance('Any') score is 1
e1c43115af3b [selector] adjuts score returned by the adaptable selector to get correct priority over is_instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5944
diff changeset
   348
        # * is_instance('SomeEntityType') score is at least 2
e1c43115af3b [selector] adjuts score returned by the adaptable selector to get correct priority over is_instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5944
diff changeset
   349
        if score >= 2:
e1c43115af3b [selector] adjuts score returned by the adaptable selector to get correct priority over is_instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5944
diff changeset
   350
            return score - 0.5
e1c43115af3b [selector] adjuts score returned by the adaptable selector to get correct priority over is_instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5944
diff changeset
   351
        if score == 1:
e1c43115af3b [selector] adjuts score returned by the adaptable selector to get correct priority over is_instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5944
diff changeset
   352
            return score + 0.5
e1c43115af3b [selector] adjuts score returned by the adaptable selector to get correct priority over is_instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5944
diff changeset
   353
        return score
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   354
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   355
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   356
class configuration_values(Predicate):
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   357
    """Return 1 if the instance has an option set to a given value(s) in its
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   358
    configuration file.
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   359
    """
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   360
    # XXX this predicate could be evaluated on startup
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   361
    def __init__(self, key, values):
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   362
        self._key = key
6402
a589df8b9b66 [selector] fix iterable detection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6397
diff changeset
   363
        if not isinstance(values, (tuple, list)):
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   364
            values = (values,)
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   365
        self._values = frozenset(values)
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   366
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   367
    def __call__(self, cls, req, **kwargs):
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   368
        try:
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   369
            return self._score
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   370
        except AttributeError:
6445
980f4415baab [selectors] make configuration_values selector works for startup/maintainance hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6402
diff changeset
   371
            if req is None:
980f4415baab [selectors] make configuration_values selector works for startup/maintainance hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6402
diff changeset
   372
                config = kwargs['repo'].config
980f4415baab [selectors] make configuration_values selector works for startup/maintainance hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6402
diff changeset
   373
            else:
980f4415baab [selectors] make configuration_values selector works for startup/maintainance hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6402
diff changeset
   374
                config = req.vreg.config
980f4415baab [selectors] make configuration_values selector works for startup/maintainance hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6402
diff changeset
   375
            self._score = config[self._key] in self._values
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   376
        return self._score
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   377
6402
a589df8b9b66 [selector] fix iterable detection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6397
diff changeset
   378
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   379
# rset predicates ##############################################################
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   380
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   381
@objectify_predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   382
def none_rset(cls, req, rset=None, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   383
    """Return 1 if the result set is None (eg usually not specified)."""
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   384
    if rset is None:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   385
        return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   386
    return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   387
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   388
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   389
# XXX == ~ none_rset
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   390
@objectify_predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   391
def any_rset(cls, req, rset=None, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   392
    """Return 1 for any result set, whatever the number of rows in it, even 0."""
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   393
    if rset is not None:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   394
        return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   395
    return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   396
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   397
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   398
@objectify_predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   399
def nonempty_rset(cls, req, rset=None, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   400
    """Return 1 for result set containing one ore more rows."""
8528
f32c50c6b7e0 don't use rset.rowcount in predicates, this makes them usable with other types such as lists
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8481
diff changeset
   401
    if rset:
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   402
        return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   403
    return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   404
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   405
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   406
# XXX == ~ nonempty_rset
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   407
@objectify_predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   408
def empty_rset(cls, req, rset=None, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   409
    """Return 1 for result set which doesn't contain any row."""
8528
f32c50c6b7e0 don't use rset.rowcount in predicates, this makes them usable with other types such as lists
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8481
diff changeset
   410
    if rset is not None and len(rset) == 0:
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   411
        return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   412
    return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   413
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   414
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   415
# XXX == multi_lines_rset(1)
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   416
@objectify_predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   417
def one_line_rset(cls, req, rset=None, row=None, **kwargs):
5715
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5627
diff changeset
   418
    """Return 1 if the result set is of size 1, or greater but a specific row in
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5627
diff changeset
   419
      the result set is specified ('row' argument).
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   420
    """
6905
fe9fd048e64c [selectors] one_line_rset selector should also work when rset is None but an entity is specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6881
diff changeset
   421
    if rset is None and 'entity' in kwargs:
fe9fd048e64c [selectors] one_line_rset selector should also work when rset is None but an entity is specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6881
diff changeset
   422
        return 1
8528
f32c50c6b7e0 don't use rset.rowcount in predicates, this makes them usable with other types such as lists
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8481
diff changeset
   423
    if rset is not None and (row is not None or len(rset) == 1):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   424
        return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   425
    return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   426
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   427
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   428
class multi_lines_rset(Predicate):
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   429
    """Return 1 if the operator expression matches between `num` elements
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   430
    in the result set and the `expected` value if defined.
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   431
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   432
    By default, multi_lines_rset(expected) matches equality expression:
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   433
        `nb` row(s) in result set equals to expected value
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   434
    But, you can perform richer comparisons by overriding default operator:
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   435
        multi_lines_rset(expected, operator.gt)
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   436
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   437
    If `expected` is None, return 1 if the result set contains *at least*
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   438
    two rows.
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   439
    If rset is None, return 0.
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   440
    """
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   441
    def __init__(self, expected=None, operator=eq):
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   442
        self.expected = expected
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   443
        self.operator = operator
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   444
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   445
    def match_expected(self, num):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   446
        if self.expected is None:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   447
            return num > 1
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   448
        return self.operator(num, self.expected)
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   449
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   450
    def __call__(self, cls, req, rset=None, **kwargs):
8528
f32c50c6b7e0 don't use rset.rowcount in predicates, this makes them usable with other types such as lists
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8481
diff changeset
   451
        return int(rset is not None and self.match_expected(len(rset)))
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   452
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   453
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   454
class multi_columns_rset(multi_lines_rset):
5452
4ac3ea9face9 [doc] typos
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   455
    """If `nb` is specified, return 1 if the result set has exactly `nb` column
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   456
    per row. Else (`nb` is None), return 1 if the result set contains *at least*
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   457
    two columns per row. Return 0 for empty result set.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   458
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   459
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   460
    def __call__(self, cls, req, rset=None, **kwargs):
8397
42ec34b3ced9 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8190
diff changeset
   461
        # 'or 0' since we *must not* return None. Also don't use rset.rows so
42ec34b3ced9 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8190
diff changeset
   462
        # this selector will work if rset is a simple list of list.
42ec34b3ced9 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8190
diff changeset
   463
        return rset and self.match_expected(len(rset[0])) or 0
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   464
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   465
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   466
class paginated_rset(Predicate):
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   467
    """Return 1 or more for result set with more rows than one or more page
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   468
    size.  You can specify expected number of pages to the initializer (default
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   469
    to one), and you'll get that number of pages as score if the result set is
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   470
    big enough.
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   471
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   472
    Page size is searched in (respecting order):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   473
    * a `page_size` argument
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   474
    * a `page_size` form parameters
8032
bcb87336c7d2 [doc] fix most of ReST compilation errors and warnings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   475
    * the `navigation.page-size` property (see :ref:`PersistentProperties`)
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   476
    """
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   477
    def __init__(self, nbpages=1):
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   478
        assert nbpages > 0
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   479
        self.nbpages = nbpages
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   480
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   481
    def __call__(self, cls, req, rset=None, **kwargs):
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   482
        if rset is None:
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   483
            return 0
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   484
        page_size = kwargs.get('page_size')
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   485
        if page_size is None:
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   486
            page_size = req.form.get('page_size')
10826
dff28956f37e [predicates] guard against non-integer page_size form parameter
Julien Cristau <julien.cristau@logilab.fr>
parents: 10651
diff changeset
   487
            if page_size is not None:
dff28956f37e [predicates] guard against non-integer page_size form parameter
Julien Cristau <julien.cristau@logilab.fr>
parents: 10651
diff changeset
   488
                try:
dff28956f37e [predicates] guard against non-integer page_size form parameter
Julien Cristau <julien.cristau@logilab.fr>
parents: 10651
diff changeset
   489
                    page_size = int(page_size)
dff28956f37e [predicates] guard against non-integer page_size form parameter
Julien Cristau <julien.cristau@logilab.fr>
parents: 10651
diff changeset
   490
                except ValueError:
dff28956f37e [predicates] guard against non-integer page_size form parameter
Julien Cristau <julien.cristau@logilab.fr>
parents: 10651
diff changeset
   491
                    page_size = None
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   492
            if page_size is None:
11092
3d177dfcdb19 [predicates] fix paginated_rset when the class has no page_size_property
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11081
diff changeset
   493
                page_size_prop = getattr(cls, 'page_size_property', 'navigation.page-size')
3d177dfcdb19 [predicates] fix paginated_rset when the class has no page_size_property
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11081
diff changeset
   494
                page_size = req.property_value(page_size_prop)
8528
f32c50c6b7e0 don't use rset.rowcount in predicates, this makes them usable with other types such as lists
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8481
diff changeset
   495
        if len(rset) <= (page_size*self.nbpages):
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   496
            return 0
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5608
diff changeset
   497
        return self.nbpages
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   498
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   499
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   500
@objectify_predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   501
def sorted_rset(cls, req, rset=None, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   502
    """Return 1 for sorted result set (e.g. from an RQL query containing an
6397
66401ba9332a [book] improve documentation lisibility for cwconfig chapter and fix some references
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 6395
diff changeset
   503
    ORDERBY clause), with exception that it will return 0 if the rset is
5944
b962dff47c36 [ftirank] when ordered by fti rank, we don't want page navigation. Anyway, sorted nav component shouldn't consider has_text relation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5904
diff changeset
   504
    'ORDERBY FTIRANK(VAR)' (eg sorted by rank value of the has_text index).
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   505
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   506
    if rset is None:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   507
        return 0
5944
b962dff47c36 [ftirank] when ordered by fti rank, we don't want page navigation. Anyway, sorted nav component shouldn't consider has_text relation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5904
diff changeset
   508
    selects = rset.syntax_tree().children
b962dff47c36 [ftirank] when ordered by fti rank, we don't want page navigation. Anyway, sorted nav component shouldn't consider has_text relation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5904
diff changeset
   509
    if (len(selects) > 1 or
b962dff47c36 [ftirank] when ordered by fti rank, we don't want page navigation. Anyway, sorted nav component shouldn't consider has_text relation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5904
diff changeset
   510
        not selects[0].orderby or
b962dff47c36 [ftirank] when ordered by fti rank, we don't want page navigation. Anyway, sorted nav component shouldn't consider has_text relation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5904
diff changeset
   511
        (isinstance(selects[0].orderby[0].term, Function) and
b962dff47c36 [ftirank] when ordered by fti rank, we don't want page navigation. Anyway, sorted nav component shouldn't consider has_text relation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5904
diff changeset
   512
         selects[0].orderby[0].term.name == 'FTIRANK')
b962dff47c36 [ftirank] when ordered by fti rank, we don't want page navigation. Anyway, sorted nav component shouldn't consider has_text relation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5904
diff changeset
   513
        ):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   514
        return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   515
    return 2
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   516
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   517
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   518
# XXX == multi_etypes_rset(1)
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   519
@objectify_predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   520
def one_etype_rset(cls, req, rset=None, col=0, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   521
    """Return 1 if the result set contains entities which are all of the same
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   522
    type in the column specified by the `col` argument of the input context, or
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   523
    in column 0.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   524
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   525
    if rset is None:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   526
        return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   527
    if len(rset.column_types(col)) != 1:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   528
        return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   529
    return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   530
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   531
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   532
class multi_etypes_rset(multi_lines_rset):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   533
    """If `nb` is specified, return 1 if the result set contains `nb` different
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   534
    types of entities in the column specified by the `col` argument of the input
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   535
    context, or in column 0. If `nb` is None, return 1 if the result set contains
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   536
    *at least* two different types of entities.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   537
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   538
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   539
    def __call__(self, cls, req, rset=None, col=0, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   540
        # 'or 0' since we *must not* return None
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   541
        return rset and self.match_expected(len(rset.column_types(col))) or 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   542
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   543
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   544
@objectify_predicate
5502
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   545
def logged_user_in_rset(cls, req, rset=None, row=None, col=0, **kwargs):
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   546
    """Return positive score if the result set at the specified row / col
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   547
    contains the eid of the logged user.
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   548
    """
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   549
    if rset is None:
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   550
        return 0
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   551
    return req.user.eid == rset[row or 0][col]
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   552
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   553
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   554
# entity predicates #############################################################
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   555
9547
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   556
class composite_etype(Predicate):
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   557
    """Return 1 for composite entities.
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   558
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   559
    A composite entity has an etype for which at least one relation
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   560
    definition points in its direction with the
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   561
    composite='subject'/'object' notation.
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   562
    """
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   563
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   564
    def __call__(self, cls, req, **kwargs):
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   565
        entity = kwargs.pop('entity', None)
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   566
        if entity is None:
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   567
            return 0
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   568
        return entity.e_schema.is_composite
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   569
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   570
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   571
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   572
class non_final_entity(EClassPredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   573
    """Return 1 for entity of a non final entity type(s). Remember, "final"
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   574
    entity types are String, Int, etc... This is equivalent to
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   575
    `is_instance('Any')` but more optimized.
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   576
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   577
    See :class:`~cubicweb.predicates.EClassPredicate` documentation for entity
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   578
    class lookup / score rules according to the input context.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   579
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   580
    def score(self, cls, req, etype):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   581
        if etype in BASE_TYPES:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   582
            return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   583
        return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   584
4664
bd5ecd5b9494 #714109: [selectors] non_final_entity should implement score_class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4545
diff changeset
   585
    def score_class(self, eclass, req):
bd5ecd5b9494 #714109: [selectors] non_final_entity should implement score_class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4545
diff changeset
   586
        return 1 # necessarily true if we're there
bd5ecd5b9494 #714109: [selectors] non_final_entity should implement score_class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4545
diff changeset
   587
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   588
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   589
5881
57387070f612 [selectors] use before-registry-reset event to init is_instance cache: cleaner code and avoid reloading bug (making hooks test fail for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   590
def _reset_is_instance_cache(vreg):
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   591
    vreg._is_instance_predicate_cache = {}
5881
57387070f612 [selectors] use before-registry-reset event to init is_instance cache: cleaner code and avoid reloading bug (making hooks test fail for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   592
57387070f612 [selectors] use before-registry-reset event to init is_instance cache: cleaner code and avoid reloading bug (making hooks test fail for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   593
CW_EVENT_MANAGER.bind('before-registry-reset', _reset_is_instance_cache)
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   594
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   595
class is_instance(EClassPredicate):
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   596
    """Return non-zero score for entity that is an instance of the one of given
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   597
    type(s). If multiple arguments are given, matching one of them is enough.
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   598
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   599
    Entity types should be given as string, the corresponding class will be
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   600
    fetched from the registry at selection time.
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   601
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   602
    See :class:`~cubicweb.predicates.EClassPredicate` documentation for entity
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   603
    class lookup / score rules according to the input context.
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   604
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   605
    .. note:: the score will reflect class proximity so the most specific object
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   606
              will be selected.
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   607
    """
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   608
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   609
    def __init__(self, *expected_etypes, **kwargs):
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   610
        super(is_instance, self).__init__(**kwargs)
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   611
        self.expected_etypes = expected_etypes
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   612
        for etype in self.expected_etypes:
10612
84468b90e9c1 [py3k] basestring → six.string_types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
   613
            assert isinstance(etype, string_types), etype
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   614
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   615
    def __str__(self):
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   616
        return '%s(%s)' % (self.__class__.__name__,
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   617
                           ','.join(str(s) for s in self.expected_etypes))
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   618
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   619
    def score_class(self, eclass, req):
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   620
        # cache on vreg to avoid reloading issues
6615
9807fb5d5f8d [dbapi] 'before-registry-reset' not called for db-api connections, cache may not be initialized
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6565
diff changeset
   621
        try:
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   622
            cache = req.vreg._is_instance_predicate_cache
6615
9807fb5d5f8d [dbapi] 'before-registry-reset' not called for db-api connections, cache may not be initialized
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6565
diff changeset
   623
        except AttributeError:
9807fb5d5f8d [dbapi] 'before-registry-reset' not called for db-api connections, cache may not be initialized
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6565
diff changeset
   624
            # XXX 'before-registry-reset' not called for db-api connections
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   625
            cache = req.vreg._is_instance_predicate_cache = {}
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   626
        try:
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   627
            expected_eclasses = cache[self]
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   628
        except KeyError:
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   629
            # turn list of entity types as string into a list of
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   630
            #  (entity class, parent classes)
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   631
            etypesreg = req.vreg['etypes']
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   632
            expected_eclasses = cache[self] = []
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   633
            for etype in self.expected_etypes:
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   634
                try:
6046
3fd4a34c4a09 [selectors] fix is_instance bug w/ parent classes. Also slight performance enhancements by changing what's returned by vreg['etypes'].parent_classes method (dedicated for this usage...) and removing no more necessary methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6008
diff changeset
   635
                    expected_eclasses.append(etypesreg.etype_class(etype))
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   636
                except KeyError:
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   637
                    continue # entity type not in the schema
6046
3fd4a34c4a09 [selectors] fix is_instance bug w/ parent classes. Also slight performance enhancements by changing what's returned by vreg['etypes'].parent_classes method (dedicated for this usage...) and removing no more necessary methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6008
diff changeset
   638
        parents, any = req.vreg['etypes'].parent_classes(eclass.__regid__)
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   639
        score = 0
6046
3fd4a34c4a09 [selectors] fix is_instance bug w/ parent classes. Also slight performance enhancements by changing what's returned by vreg['etypes'].parent_classes method (dedicated for this usage...) and removing no more necessary methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6008
diff changeset
   640
        for expectedcls in expected_eclasses:
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   641
            # adjust score according to class proximity
6046
3fd4a34c4a09 [selectors] fix is_instance bug w/ parent classes. Also slight performance enhancements by changing what's returned by vreg['etypes'].parent_classes method (dedicated for this usage...) and removing no more necessary methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6008
diff changeset
   642
            if expectedcls is eclass:
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   643
                score += len(parents) + 4
6046
3fd4a34c4a09 [selectors] fix is_instance bug w/ parent classes. Also slight performance enhancements by changing what's returned by vreg['etypes'].parent_classes method (dedicated for this usage...) and removing no more necessary methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6008
diff changeset
   644
            elif expectedcls is any: # Any
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   645
                score += 1
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   646
            else:
6046
3fd4a34c4a09 [selectors] fix is_instance bug w/ parent classes. Also slight performance enhancements by changing what's returned by vreg['etypes'].parent_classes method (dedicated for this usage...) and removing no more necessary methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6008
diff changeset
   647
                for index, basecls in enumerate(reversed(parents)):
3fd4a34c4a09 [selectors] fix is_instance bug w/ parent classes. Also slight performance enhancements by changing what's returned by vreg['etypes'].parent_classes method (dedicated for this usage...) and removing no more necessary methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6008
diff changeset
   648
                    if expectedcls is basecls:
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   649
                        score += index + 3
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   650
                        break
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   651
        return score
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
   652
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   653
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   654
class score_entity(EntityPredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   655
    """Return score according to an arbitrary function given as argument which
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   656
    will be called with input content entity as argument.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   657
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   658
    This is a very useful predicate that will usually interest you since it
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   659
    allows a lot of things without having to write a specific predicate.
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   660
6869
900cb9b1b687 [tests] new unit tests about score_entity selector (inscore machinery)
Julien Jehannet <julien@smaf.org>
parents: 6615
diff changeset
   661
    The function can return arbitrary value which will be casted to an integer
900cb9b1b687 [tests] new unit tests about score_entity selector (inscore machinery)
Julien Jehannet <julien@smaf.org>
parents: 6615
diff changeset
   662
    value at the end.
900cb9b1b687 [tests] new unit tests about score_entity selector (inscore machinery)
Julien Jehannet <julien@smaf.org>
parents: 6615
diff changeset
   663
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   664
    See :class:`~cubicweb.predicates.EntityPredicate` documentation for entity
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   665
    lookup / score rules according to the input context.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   666
    """
12508
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11956
diff changeset
   667
    def __init__(self, scorefunc, mode='all'):
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11956
diff changeset
   668
        super(score_entity, self).__init__(mode=mode)
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   669
        def intscore(*args, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   670
            score = scorefunc(*args, **kwargs)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   671
            if not score:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   672
                return 0
10613
8d9fe02387e3 [py3k] six.integer_types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10612
diff changeset
   673
            if isinstance(score, integer_types):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   674
                return score
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   675
            return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   676
        self.score_entity = intscore
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   677
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   678
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   679
class has_mimetype(EntityPredicate):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   680
    """Return 1 if the entity adapt to IDownloadable and has the given MIME type.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   681
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   682
    You can give 'image/' to match any image for instance, or 'image/png' to match
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   683
    only PNG images.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   684
    """
12508
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11956
diff changeset
   685
    def __init__(self, mimetype, mode='all'):
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11956
diff changeset
   686
        super(has_mimetype, self).__init__(mode=mode)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   687
        self.mimetype = mimetype
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   688
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   689
    def score_entity(self, entity):
5858
384d34e76d6d cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5736
diff changeset
   690
        idownloadable = entity.cw_adapt_to('IDownloadable')
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   691
        if idownloadable is None:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   692
            return 0
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   693
        mt = idownloadable.download_content_type()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   694
        if not (mt and mt.startswith(self.mimetype)):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   695
            return 0
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   696
        return 1
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   697
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   698
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   699
class relation_possible(EntityPredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   700
    """Return 1 for entity that supports the relation, provided that the
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   701
    request's user may do some `action` on it (see below).
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   702
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   703
    The relation is specified by the following initializer arguments:
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   704
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   705
    * `rtype`, the name of the relation
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   706
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   707
    * `role`, the role of the entity in the relation, either 'subject' or
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   708
      'object', default to 'subject'
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   709
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   710
    * `target_etype`, optional name of an entity type that should be supported
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   711
      at the other end of the relation
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   712
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   713
    * `action`, a relation schema action (e.g. one of 'read', 'add', 'delete',
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   714
      default to 'read') which must be granted to the user, else a 0 score will
5732
7b0765f22ad0 [selectors] relation_possible selector accept None as action, in which case no perms checking is done
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5615
diff changeset
   715
      be returned. Give None if you don't want any permission checking.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   716
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   717
    * `strict`, boolean (default to False) telling what to do when the user has
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   718
      not globally the permission for the action (eg the action is not granted
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   719
      to one of the user's groups)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   720
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   721
      - when strict is False, if there are some local role defined for this
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   722
        action (e.g. using rql expressions), then the permission will be
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   723
        considered as granted
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   724
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   725
      - when strict is True, then the permission will be actually checked for
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   726
        each entity
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   727
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   728
    Setting `strict` to True impacts performance for large result set since
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   729
    you'll then get the :class:`~cubicweb.predicates.EntityPredicate` behaviour
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   730
    while otherwise you get the :class:`~cubicweb.predicates.EClassPredicate`'s
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   731
    one. See those classes documentation for entity lookup / score rules
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   732
    according to the input context.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   733
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   734
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   735
    def __init__(self, rtype, role='subject', target_etype=None,
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   736
                 action='read', strict=False, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   737
        super(relation_possible, self).__init__(**kwargs)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   738
        self.rtype = rtype
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   739
        self.role = role
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   740
        self.target_etype = target_etype
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   741
        self.action = action
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   742
        self.strict = strict
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   743
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   744
    # hack hack hack
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   745
    def __call__(self, cls, req, **kwargs):
7624
ce020f90fb8e [facet] closes #1806932: test and fix facet bug w/ having query (need rql update)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7610
diff changeset
   746
        # hack hack hack
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   747
        if self.strict:
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   748
            return EntityPredicate.__call__(self, cls, req, **kwargs)
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   749
        return EClassPredicate.__call__(self, cls, req, **kwargs)
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   750
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   751
    def score(self, *args):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   752
        if self.strict:
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   753
            return EntityPredicate.score(self, *args)
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   754
        return EClassPredicate.score(self, *args)
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   755
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   756
    def _get_rschema(self, eclass):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   757
        eschema = eclass.e_schema
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   758
        try:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   759
            if self.role == 'object':
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   760
                return eschema.objrels[self.rtype]
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   761
            else:
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   762
                return eschema.subjrels[self.rtype]
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   763
        except KeyError:
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   764
            return None
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   765
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   766
    def score_class(self, eclass, req):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   767
        rschema = self._get_rschema(eclass)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   768
        if rschema is None:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   769
            return 0 # relation not supported
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   770
        eschema = eclass.e_schema
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   771
        if self.target_etype is not None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   772
            try:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   773
                rdef = rschema.role_rdef(eschema, self.target_etype, self.role)
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1037
diff changeset
   774
            except KeyError:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   775
                return 0
5900
002af94623d3 [selectors] relation_possible selector should check user may read target entity type when specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5886
diff changeset
   776
            if self.action and not rdef.may_have_permission(self.action, req):
002af94623d3 [selectors] relation_possible selector should check user may read target entity type when specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5886
diff changeset
   777
                return 0
002af94623d3 [selectors] relation_possible selector should check user may read target entity type when specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5886
diff changeset
   778
            teschema = req.vreg.schema.eschema(self.target_etype)
002af94623d3 [selectors] relation_possible selector should check user may read target entity type when specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5886
diff changeset
   779
            if not teschema.may_have_permission('read', req):
002af94623d3 [selectors] relation_possible selector should check user may read target entity type when specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5886
diff changeset
   780
                return 0
5732
7b0765f22ad0 [selectors] relation_possible selector accept None as action, in which case no perms checking is done
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5615
diff changeset
   781
        elif self.action:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   782
            return rschema.may_have_permission(self.action, req, eschema, self.role)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   783
        return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   784
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   785
    def score_entity(self, entity):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   786
        rschema = self._get_rschema(entity)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   787
        if rschema is None:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   788
            return 0 # relation not supported
5732
7b0765f22ad0 [selectors] relation_possible selector accept None as action, in which case no perms checking is done
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5615
diff changeset
   789
        if self.action:
7b0765f22ad0 [selectors] relation_possible selector accept None as action, in which case no perms checking is done
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5615
diff changeset
   790
            if self.target_etype is not None:
9152
b0155bfd4e17 Protect against crash in the `relation_possible` predicate with ambiguous relations.
Florent Cayre <florent.cayre@logilab.fr>
parents: 8872
diff changeset
   791
                try:
b0155bfd4e17 Protect against crash in the `relation_possible` predicate with ambiguous relations.
Florent Cayre <florent.cayre@logilab.fr>
parents: 8872
diff changeset
   792
                    rschema = rschema.role_rdef(entity.e_schema,
b0155bfd4e17 Protect against crash in the `relation_possible` predicate with ambiguous relations.
Florent Cayre <florent.cayre@logilab.fr>
parents: 8872
diff changeset
   793
                                                self.target_etype, self.role)
b0155bfd4e17 Protect against crash in the `relation_possible` predicate with ambiguous relations.
Florent Cayre <florent.cayre@logilab.fr>
parents: 8872
diff changeset
   794
                except KeyError:
b0155bfd4e17 Protect against crash in the `relation_possible` predicate with ambiguous relations.
Florent Cayre <florent.cayre@logilab.fr>
parents: 8872
diff changeset
   795
                    return 0
5732
7b0765f22ad0 [selectors] relation_possible selector accept None as action, in which case no perms checking is done
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5615
diff changeset
   796
            if self.role == 'subject':
7b0765f22ad0 [selectors] relation_possible selector accept None as action, in which case no perms checking is done
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5615
diff changeset
   797
                if not rschema.has_perm(entity._cw, self.action, fromeid=entity.eid):
7b0765f22ad0 [selectors] relation_possible selector accept None as action, in which case no perms checking is done
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5615
diff changeset
   798
                    return 0
7b0765f22ad0 [selectors] relation_possible selector accept None as action, in which case no perms checking is done
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5615
diff changeset
   799
            elif not rschema.has_perm(entity._cw, self.action, toeid=entity.eid):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   800
                return 0
5900
002af94623d3 [selectors] relation_possible selector should check user may read target entity type when specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5886
diff changeset
   801
        if self.target_etype is not None:
5903
aa01eb033620 [selectors] fix dumb name error introduced in parent changeset
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5900
diff changeset
   802
            req = entity._cw
aa01eb033620 [selectors] fix dumb name error introduced in parent changeset
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5900
diff changeset
   803
            teschema = req.vreg.schema.eschema(self.target_etype)
5900
002af94623d3 [selectors] relation_possible selector should check user may read target entity type when specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5886
diff changeset
   804
            if not teschema.may_have_permission('read', req):
002af94623d3 [selectors] relation_possible selector should check user may read target entity type when specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5886
diff changeset
   805
                return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   806
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   807
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   808
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   809
class partial_relation_possible(PartialPredicateMixIn, relation_possible):
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   810
    """Same as :class:~`cubicweb.predicates.relation_possible`, but will look for
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   811
    attributes of the selected class to get information which is otherwise
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   812
    expected by the initializer, except for `action` and `strict` which are kept
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   813
    as initializer arguments.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   814
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   815
    This is useful to predefine predicate of an abstract class designed to be
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   816
    customized.
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   817
    """
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   818
    def __init__(self, action='read', **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   819
        super(partial_relation_possible, self).__init__(None, None, None,
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   820
                                                        action, **kwargs)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   821
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   822
    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
   823
        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
   824
        self.role = role(cls)
7990
a673d1d9a738 [diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7986
diff changeset
   825
        self.target_etype = getattr(cls, 'target_etype', None)
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   826
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   827
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   828
class has_related_entities(EntityPredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   829
    """Return 1 if entity support the specified relation and has some linked
10903
da30851f9706 spelling: *aly → *ally
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10826
diff changeset
   830
    entities by this relation , optionally filtered according to the specified
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   831
    target type.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   832
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   833
    The relation is specified by the following initializer arguments:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   834
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   835
    * `rtype`, the name of the relation
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   836
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   837
    * `role`, the role of the entity in the relation, either 'subject' or
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   838
      'object', default to 'subject'.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   839
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   840
    * `target_etype`, optional name of an entity type that should be found
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   841
      at the other end of the relation
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   842
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   843
    See :class:`~cubicweb.predicates.EntityPredicate` documentation for entity
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   844
    lookup / score rules according to the input context.
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   845
    """
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   846
    def __init__(self, rtype, role='subject', target_etype=None, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   847
        super(has_related_entities, self).__init__(**kwargs)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   848
        self.rtype = rtype
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   849
        self.role = role
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   850
        self.target_etype = target_etype
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   851
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   852
    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
   853
        relpossel = relation_possible(self.rtype, self.role, self.target_etype)
3378
2f25f701301d use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
   854
        if not relpossel.score_class(entity.__class__, entity._cw):
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   855
            return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   856
        rset = entity.related(self.rtype, self.role)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   857
        if self.target_etype:
1011
22812cfe36b4 fix w/ rset with more than one column
sylvain.thenault@logilab.fr
parents: 876
diff changeset
   858
            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
   859
        return rset and 1 or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   860
833
8c6bfd9158fb bw compat for selection for creation forms
sylvain.thenault@logilab.fr
parents: 828
diff changeset
   861
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   862
class partial_has_related_entities(PartialPredicateMixIn, has_related_entities):
11956
3199a40db419 [predicates] Fix reference to has_related_entities in partial_has_related_entities docstring
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   863
    """Same as :class:~`cubicweb.predicates.has_related_entities`, but will look
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   864
    for attributes of the selected class to get information which is otherwise
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   865
    expected by the initializer.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   866
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   867
    This is useful to predefine predicate of an abstract class designed to be
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   868
    customized.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   869
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   870
    def __init__(self, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   871
        super(partial_has_related_entities, self).__init__(None, None, None,
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   872
                                                           **kwargs)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   873
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   874
    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
   875
        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
   876
        self.role = role(cls)
7990
a673d1d9a738 [diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7986
diff changeset
   877
        self.target_etype = getattr(cls, 'target_etype', None)
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   878
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   879
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   880
class has_permission(EntityPredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   881
    """Return non-zero score if request's user has the permission to do the
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   882
    requested action on the entity. `action` is an entity schema action (eg one
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   883
    of 'read', 'add', 'delete', 'update').
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   884
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   885
    Here are entity lookup / scoring rules:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   886
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   887
    * if `entity` is specified, check permission is granted for this entity
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   888
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   889
    * elif `row` is specified, check permission is granted for the entity found
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   890
      in the specified cell
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   891
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   892
    * else check permission is granted for each entity found in the column
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   893
      specified specified by the `col` argument or in column 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   894
    """
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   895
    def __init__(self, action):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   896
        self.action = action
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   897
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   898
    # don't use EntityPredicate.__call__ but this optimized implementation to
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   899
    # avoid considering each entity when it's not necessary
8481
ff3b163f52e9 [predicates] fix predicates that erroneously evaluate the entity passed as a parameter as a boolean, instead of testing its existence in the keyword arguments -using the kwargs.get('entity') idiom instead of 'entity' in kwargs or similar- ; closes #2424288
Florent Cayré <florent.cayre@logilab.fr>
parents: 8397
diff changeset
   900
    def __call__(self, cls, req, rset=None, row=None, col=0, entity=None, **kwargs):
ff3b163f52e9 [predicates] fix predicates that erroneously evaluate the entity passed as a parameter as a boolean, instead of testing its existence in the keyword arguments -using the kwargs.get('entity') idiom instead of 'entity' in kwargs or similar- ; closes #2424288
Florent Cayré <florent.cayre@logilab.fr>
parents: 8397
diff changeset
   901
        if entity is not None:
ff3b163f52e9 [predicates] fix predicates that erroneously evaluate the entity passed as a parameter as a boolean, instead of testing its existence in the keyword arguments -using the kwargs.get('entity') idiom instead of 'entity' in kwargs or similar- ; closes #2424288
Florent Cayré <florent.cayre@logilab.fr>
parents: 8397
diff changeset
   902
            return self.score_entity(entity)
788
d62fb3e9797d protect against None rset
sylvain.thenault@logilab.fr
parents: 784
diff changeset
   903
        if rset is None:
d62fb3e9797d protect against None rset
sylvain.thenault@logilab.fr
parents: 784
diff changeset
   904
            return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   905
        if row is None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   906
            score = 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   907
            need_local_check = []
2816
85f7502d32be access schema through req.vreg
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2797
diff changeset
   908
            geteschema = req.vreg.schema.eschema
6360
1edfc0f3bb1d [selector] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6348
diff changeset
   909
            user = req.user
1edfc0f3bb1d [selector] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6348
diff changeset
   910
            action = self.action
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   911
            for etype in rset.column_types(0):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   912
                if etype in BASE_TYPES:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   913
                    return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   914
                eschema = geteschema(etype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   915
                if not user.matching_groups(eschema.get_groups(action)):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   916
                    if eschema.has_local_role(action):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   917
                        # have to ckeck local roles
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   918
                        need_local_check.append(eschema)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   919
                        continue
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   920
                    else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   921
                        # even a local role won't be enough
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   922
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   923
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   924
            if need_local_check:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   925
                # check local role for entities of necessary types
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   926
                for i, row in enumerate(rset):
6360
1edfc0f3bb1d [selector] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6348
diff changeset
   927
                    if not rset.description[i][col] in need_local_check:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   928
                        continue
6364
ad9ed9803eb6 cleanup and micro-optimization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6360
diff changeset
   929
                    # micro-optimisation instead of calling self.score(req,
ad9ed9803eb6 cleanup and micro-optimization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6360
diff changeset
   930
                    # rset, i, col): rset may be large
ad9ed9803eb6 cleanup and micro-optimization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6360
diff changeset
   931
                    if not rset.get_entity(i, col).cw_has_perm(action):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   932
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   933
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   934
            return score
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   935
        return self.score(req, rset, row, col)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   936
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   937
    def score_entity(self, entity):
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
   938
        if entity.cw_has_perm(self.action):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   939
            return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   940
        return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   941
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   942
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   943
class has_add_permission(EClassPredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   944
    """Return 1 if request's user has the add permission on entity type
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   945
    specified in the `etype` initializer argument, or according to entity found
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   946
    in the input content if not specified.
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   947
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   948
    It also check that then entity type is not a strict subobject (e.g. may only
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   949
    be used as a composed of another entity).
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   950
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   951
    See :class:`~cubicweb.predicates.EClassPredicate` documentation for entity
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   952
    class lookup / score rules according to the input context when `etype` is
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   953
    not specified.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   954
    """
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   955
    def __init__(self, etype=None, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   956
        super(has_add_permission, self).__init__(**kwargs)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   957
        self.etype = etype
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   958
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   959
    def __call__(self, cls, req, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   960
        if self.etype is None:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   961
            return super(has_add_permission, self).__call__(cls, req, **kwargs)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   962
        return self.score(cls, req, self.etype)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   963
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   964
    def score_class(self, eclass, req):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   965
        eschema = eclass.e_schema
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   966
        if eschema.final or eschema.is_subobject(strict=True) \
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   967
               or not eschema.has_perm(req, 'add'):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   968
            return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   969
        return 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   970
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   971
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   972
class rql_condition(EntityPredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   973
    """Return non-zero score if arbitrary rql specified in `expression`
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   974
    initializer argument return some results for entity found in the input
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   975
    context. Returned score is the number of items returned by the rql
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   976
    condition.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   977
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   978
    `expression` is expected to be a string containing an rql expression, which
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   979
    must use 'X' variable to represent the context entity and may use 'U' to
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   980
    represent the request's user.
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   981
6871
b746dae3a004 [docstring] minor: add warning about entity cache for rql_condition selector
Julien Jehannet <julien@smaf.org>
parents: 6870
diff changeset
   982
    .. warning::
b746dae3a004 [docstring] minor: add warning about entity cache for rql_condition selector
Julien Jehannet <julien@smaf.org>
parents: 6870
diff changeset
   983
        If simply testing value of some attribute/relation of context entity (X),
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   984
        you should rather use the :class:`score_entity` predicate which will
6871
b746dae3a004 [docstring] minor: add warning about entity cache for rql_condition selector
Julien Jehannet <julien@smaf.org>
parents: 6870
diff changeset
   985
        benefit from the ORM's request entities cache.
b746dae3a004 [docstring] minor: add warning about entity cache for rql_condition selector
Julien Jehannet <julien@smaf.org>
parents: 6870
diff changeset
   986
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   987
    See :class:`~cubicweb.predicates.EntityPredicate` documentation for entity
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   988
    lookup / score rules according to the input context.
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
   989
    """
12508
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11956
diff changeset
   990
    def __init__(self, expression, mode='all', user_condition=False):
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11956
diff changeset
   991
        super(rql_condition, self).__init__(mode=mode)
7362
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
   992
        self.user_condition = user_condition
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
   993
        if user_condition:
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
   994
            rql = 'Any COUNT(U) WHERE U eid %%(u)s, %s' % expression
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
   995
        elif 'U' in frozenset(split_expression(expression)):
6457
3234d8d6e264 [selector] more efficient rql_condition by simply retreiving COUNT()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6445
diff changeset
   996
            rql = 'Any COUNT(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
   997
        else:
6457
3234d8d6e264 [selector] more efficient rql_condition by simply retreiving COUNT()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6445
diff changeset
   998
            rql = 'Any COUNT(X) WHERE X eid %%(x)s, %s' % expression
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   999
        self.rql = rql
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1000
6870
658039c5eeac [selectors] minor: use similar __repr__ implementation for selector instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6869
diff changeset
  1001
    def __str__(self):
658039c5eeac [selectors] minor: use similar __repr__ implementation for selector instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6869
diff changeset
  1002
        return '%s(%r)' % (self.__class__.__name__, self.rql)
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1003
7362
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
  1004
    def __call__(self, cls, req, **kwargs):
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
  1005
        if self.user_condition:
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
  1006
            try:
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
  1007
                return req.execute(self.rql, {'u': req.user.eid})[0][0]
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
  1008
            except Unauthorized:
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
  1009
                return 0
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
  1010
        else:
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
  1011
            return super(rql_condition, self).__call__(cls, req, **kwargs)
b9813c9d32ac [selectors] enhance rql_condition to make it usable as a condition on request's user
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7345
diff changeset
  1012
7345
b9eaad6e34c3 [selectors] test/fix rql_condition to make it works when entity is specified via 'entity' keyword argument instead of rset, row and col
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7298
diff changeset
  1013
    def _score(self, req, eid):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1014
        try:
7345
b9eaad6e34c3 [selectors] test/fix rql_condition to make it works when entity is specified via 'entity' keyword argument instead of rset, row and col
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7298
diff changeset
  1015
            return req.execute(self.rql, {'x': eid, 'u': req.user.eid})[0][0]
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1016
        except Unauthorized:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1017
            return 0
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
  1018
7345
b9eaad6e34c3 [selectors] test/fix rql_condition to make it works when entity is specified via 'entity' keyword argument instead of rset, row and col
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7298
diff changeset
  1019
    def score(self, req, rset, row, col):
b9eaad6e34c3 [selectors] test/fix rql_condition to make it works when entity is specified via 'entity' keyword argument instead of rset, row and col
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7298
diff changeset
  1020
        return self._score(req, rset[row][col])
b9eaad6e34c3 [selectors] test/fix rql_condition to make it works when entity is specified via 'entity' keyword argument instead of rset, row and col
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7298
diff changeset
  1021
b9eaad6e34c3 [selectors] test/fix rql_condition to make it works when entity is specified via 'entity' keyword argument instead of rset, row and col
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7298
diff changeset
  1022
    def score_entity(self, entity):
b9eaad6e34c3 [selectors] test/fix rql_condition to make it works when entity is specified via 'entity' keyword argument instead of rset, row and col
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7298
diff changeset
  1023
        return self._score(entity._cw, entity.eid)
b9eaad6e34c3 [selectors] test/fix rql_condition to make it works when entity is specified via 'entity' keyword argument instead of rset, row and col
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7298
diff changeset
  1024
b9eaad6e34c3 [selectors] test/fix rql_condition to make it works when entity is specified via 'entity' keyword argument instead of rset, row and col
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7298
diff changeset
  1025
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1026
# workflow predicates ###########################################################
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1027
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1028
class is_in_state(score_entity):
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1029
    """Return 1 if entity is in one of the states given as argument list
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1030
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1031
    You should use this instead of your own :class:`score_entity` predicate to
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1032
    avoid some gotchas:
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1033
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1034
    * possible views gives a fake entity with no state
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1035
    * you must use the latest tr info thru the workflow adapter for repository
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1036
      side checking of the current state
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1037
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1038
    In debug mode, this predicate can raise :exc:`ValueError` for unknown states names
7297
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1039
    (only checked on entities without a custom workflow)
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1040
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1041
    :rtype: int
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1042
    """
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1043
    def __init__(self, *expected):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1044
        assert expected, self
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1045
        self.expected = frozenset(expected)
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1046
        def score(entity, expected=self.expected):
6908
f07dc0e8948d fix #1452413 : is_in_state selector does not match initial state of an entity
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6905
diff changeset
  1047
            adapted = entity.cw_adapt_to('IWorkflowable')
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1048
            # in debug mode only (time consuming)
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1049
            if entity._cw.vreg.config.debugmode:
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1050
                # validation can only be done for generic etype workflow because
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1051
                # expected transition list could have been changed for a custom
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1052
                # workflow (for the current entity)
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1053
                if not entity.custom_workflow:
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1054
                    self._validate(adapted)
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1055
            return self._score(adapted)
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1056
        super(is_in_state, self).__init__(score)
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1057
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1058
    def _score(self, adapted):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1059
        trinfo = adapted.latest_trinfo()
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1060
        if trinfo is None: # entity is probably in it's initial state
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1061
            statename = adapted.state
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1062
        else:
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1063
            statename = trinfo.new_state.name
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1064
        return statename in self.expected
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1065
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1066
    def _validate(self, adapted):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1067
        wf = adapted.current_workflow
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1068
        valid = [n.name for n in wf.reverse_state_of]
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1069
        unknown = sorted(self.expected.difference(valid))
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1070
        if unknown:
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1071
            raise ValueError("%s: unknown state(s): %s"
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1072
                             % (wf.name, ",".join(unknown)))
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1073
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1074
    def __str__(self):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1075
        return '%s(%s)' % (self.__class__.__name__,
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1076
                           ','.join(str(s) for s in self.expected))
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1077
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1078
12542
85194bd49119 Drop more deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12508
diff changeset
  1079
def on_fire_transition(etype, tr_names):
7297
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1080
    """Return 1 when entity of the type `etype` is going through transition of
9344
4da3ef764395 [predicates] allow multiple transition names in on_fire_transition (closes #3013720)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9256
diff changeset
  1081
    a name included in `tr_names`.
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1082
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1083
    You should use this predicate on 'after_add_entity' hook, since it's actually
7297
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1084
    looking for addition of `TrInfo` entities. Hence in the hook, `self.entity`
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1085
    will reference the matching `TrInfo` entity, allowing to get all the
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1086
    transition details (including the entity to which is applied the transition
7529
2fdc310be7cd [book] add autoload section from code and fix sphinx warnings
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 7452
diff changeset
  1087
    but also its original state, transition, destination state, user...).
7559
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7529
diff changeset
  1088
7529
2fdc310be7cd [book] add autoload section from code and fix sphinx warnings
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 7452
diff changeset
  1089
    See :class:`cubicweb.entities.wfobjs.TrInfo` for more information.
7297
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1090
    """
10612
84468b90e9c1 [py3k] basestring → six.string_types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
  1091
    if isinstance(tr_names, string_types):
9344
4da3ef764395 [predicates] allow multiple transition names in on_fire_transition (closes #3013720)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9256
diff changeset
  1092
        tr_names = set((tr_names,))
7297
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1093
    def match_etype_and_transition(trinfo):
7298
a448e470c150 [selectors] fix on_fire_transition for cases where change_state is called (eg no transition specified)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7297
diff changeset
  1094
        # take care trinfo.transition is None when calling change_state
9344
4da3ef764395 [predicates] allow multiple transition names in on_fire_transition (closes #3013720)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9256
diff changeset
  1095
        return (trinfo.transition and trinfo.transition.name in tr_names
7298
a448e470c150 [selectors] fix on_fire_transition for cases where change_state is called (eg no transition specified)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7297
diff changeset
  1096
                # is_instance() first two arguments are 'cls' (unused, so giving
a448e470c150 [selectors] fix on_fire_transition for cases where change_state is called (eg no transition specified)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7297
diff changeset
  1097
                # None is fine) and the request/session
7297
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1098
                and is_instance(etype)(None, trinfo._cw, entity=trinfo.for_entity))
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1099
7297
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1100
    return is_instance('TrInfo') & score_entity(match_etype_and_transition)
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1101
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1102
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1103
class match_transition(ExpectedValuePredicate):
7297
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1104
    """Return 1 if `transition` argument is found in the input context which has
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1105
    a `.name` attribute matching one of the expected names given to the
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1106
    initializer.
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1107
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1108
    This predicate is expected to be used to customise the status change form in
7297
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1109
    the web ui.
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1110
    """
7297
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1111
    def __call__(self, cls, req, transition=None, **kwargs):
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1112
        # XXX check this is a transition that apply to the object?
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1113
        if transition is None:
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1114
            treid = req.form.get('treid', None)
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1115
            if treid:
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1116
                transition = req.entity_from_eid(treid)
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1117
        if transition is not None and getattr(transition, 'name', None) in self.expected:
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1118
            return 1
117dbb11a42e [workflow selectors] introduced new on_fire_transition hook selector, deprecated on_transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7173
diff changeset
  1119
        return 0
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1120
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1121
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1122
# logged user predicates ########################################################
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1123
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1124
@objectify_predicate
5490
b7b96b8decf1 [selectors] fix no_cnx selector's prototype
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
  1125
def no_cnx(cls, req, **kwargs):
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5174
diff changeset
  1126
    """Return 1 if the web session has no connection set. This occurs when
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5174
diff changeset
  1127
    anonymous access is not allowed and user isn't authenticated.
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5174
diff changeset
  1128
    """
5244
5467674ad101 [web] put a fake object that raise Unauthorized on any attribute access as req.cnx and req._user, so we are properly asked to authenticated on any view that tries to do something with one of those attributes (instead of doing defensive programming everywhere we're doing that)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
  1129
    if not req.cnx:
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5174
diff changeset
  1130
        return 1
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5174
diff changeset
  1131
    return 0
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5174
diff changeset
  1132
10497
12bc4e92aa62 [predicates] objectify the anonymous_user predicate
David Douard <david.douard@logilab.fr>
parents: 10476
diff changeset
  1133
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1134
@objectify_predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1135
def authenticated_user(cls, req, **kwargs):
9553
be9b12f42d76 [predicates] fix thinko in doc strings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9547
diff changeset
  1136
    """Return 1 if the user is authenticated (i.e. not the anonymous user).
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1137
    """
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5174
diff changeset
  1138
    if req.session.anonymous_session:
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1139
        return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1140
    return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1141
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1142
10497
12bc4e92aa62 [predicates] objectify the anonymous_user predicate
David Douard <david.douard@logilab.fr>
parents: 10476
diff changeset
  1143
@objectify_predicate
12bc4e92aa62 [predicates] objectify the anonymous_user predicate
David Douard <david.douard@logilab.fr>
parents: 10476
diff changeset
  1144
def anonymous_user(cls, req, **kwargs):
9553
be9b12f42d76 [predicates] fix thinko in doc strings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9547
diff changeset
  1145
    """Return 1 if the user is not authenticated (i.e. is the anonymous user).
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1146
    """
10497
12bc4e92aa62 [predicates] objectify the anonymous_user predicate
David Douard <david.douard@logilab.fr>
parents: 10476
diff changeset
  1147
    if req.session.anonymous_session:
12bc4e92aa62 [predicates] objectify the anonymous_user predicate
David Douard <david.douard@logilab.fr>
parents: 10476
diff changeset
  1148
        return 1
12bc4e92aa62 [predicates] objectify the anonymous_user predicate
David Douard <david.douard@logilab.fr>
parents: 10476
diff changeset
  1149
    return 0
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1150
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1151
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1152
class match_user_groups(ExpectedValuePredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1153
    """Return a non-zero score if request's user is in at least one of the
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1154
    groups given as initializer argument. Returned score is the number of groups
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1155
    in which the user is.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1156
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1157
    If the special 'owners' group is given and `rset` is specified in the input
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1158
    context:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1159
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1160
    * if `row` is specified check the entity at the given `row`/`col` (default
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1161
      to 0) is owned by the user
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1162
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1163
    * else check all entities in `col` (default to 0) are owned by the user
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1164
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1165
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1166
    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
7452
7e8182a63559 Fix conditionnal logic broken in 195b24fe3a03
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7448
diff changeset
  1167
        if not getattr(req, 'cnx', True): # default to True for repo session instances
7428
5338d895b891 [web session] fix session handling so we get a chance to have for instance the 'forgotpwd' feature working on a site where anonymous are not allowed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7362
diff changeset
  1168
            return 0
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1169
        user = req.user
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1170
        if user is None:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1171
            return int('guests' in self.expected)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1172
        score = user.matching_groups(self.expected)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1173
        if not score and 'owners' in self.expected and rset:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1174
            if row is not None:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1175
                if not user.owns(rset[row][col]):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1176
                    return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1177
                score = 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1178
            else:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1179
                score = all(user.owns(r[col]) for r in rset)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1180
        return score
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1181
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1182
# Web request predicates ########################################################
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1183
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6140
diff changeset
  1184
# XXX deprecate
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1185
@objectify_predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1186
def primary_view(cls, req, view=None, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1187
    """Return 1 if:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1188
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1189
    * *no view is specified* in the input context
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1190
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1191
    * a view is specified and its `.is_primary()` method return True
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1192
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1193
    This predicate is usually used by contextual components that only want to
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1194
    appears for the primary view of an entity.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1195
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1196
    if view is not None and not view.is_primary():
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1197
        return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1198
    return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1199
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1200
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1201
@objectify_predicate
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1202
def contextual(cls, req, view=None, **kwargs):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1203
    """Return 1 if view's contextual property is true"""
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1204
    if view is not None and view.contextual:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1205
        return 1
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1206
    return 0
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1207
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1208
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1209
class match_view(ExpectedValuePredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1210
    """Return 1 if a view is specified an as its registry id is in one of the
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1211
    expected view id given to the initializer.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1212
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1213
    def __call__(self, cls, req, view=None, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1214
        if view is None or not view.__regid__ in self.expected:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1215
            return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1216
        return 1
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1217
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
  1218
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1219
class match_context(ExpectedValuePredicate):
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1220
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1221
    def __call__(self, cls, req, context=None, **kwargs):
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1222
        if not context in self.expected:
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1223
            return 0
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1224
        return 1
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1225
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1226
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6140
diff changeset
  1227
# XXX deprecate
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1228
@objectify_predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1229
def match_context_prop(cls, req, context=None, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1230
    """Return 1 if:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1231
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1232
    * no `context` is specified in input context (take care to confusion, here
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1233
      `context` refers to a string given as an argument to the input context...)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1234
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1235
    * specified `context` is matching the context property value for the
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1236
      appobject using this predicate
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1237
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1238
    * the appobject's context property value is None
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1239
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1240
    This predicate is usually used by contextual components that want to appears
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1241
    in a configurable place.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1242
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1243
    if context is None:
4509
a17033cfc892 when no context specified, should return non-zero score as documented
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4462
diff changeset
  1244
        return 1
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1245
    propval = req.property_value('%s.%s.context' % (cls.__registry__,
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1246
                                                    cls.__regid__))
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1247
    if propval and context != propval:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1248
        return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1249
    return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1250
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1251
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1252
class match_search_state(ExpectedValuePredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1253
    """Return 1 if the current request search state is in one of the expected
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1254
    states given to the initializer.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1255
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1256
    Known search states are either 'normal' or 'linksearch' (eg searching for an
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1257
    object to create a relation with another).
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1258
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1259
    This predicate is usually used by action that want to appears or not according
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1260
    to the ui search state.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1261
    """
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
  1262
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1263
    def __call__(self, cls, req, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1264
        try:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1265
            if not req.search_state[0] in self.expected:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1266
                return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1267
        except AttributeError:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1268
            return 1 # class doesn't care about search state, accept it
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1269
        return 1
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1270
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1271
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1272
class match_form_params(ExpectedValuePredicate):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1273
    """Return non-zero score if parameter names specified as initializer
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1274
    arguments are specified in request's form parameters.
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1275
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1276
    Return a score corresponding to the number of expected parameters.
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1277
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1278
    When multiple parameters are expected, all of them should be found in
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1279
    the input context unless `mode` keyword argument is given to 'any',
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1280
    in which case a single matching parameter is enough.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1281
    """
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1282
10476
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1283
    def __init__(self, *expected, **kwargs):
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1284
        """override default __init__ to allow either named or positional
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1285
        parameters.
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1286
        """
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1287
        if kwargs and expected:
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1288
            raise ValueError("match_form_params() can't be called with both "
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1289
                             "positional and named arguments")
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1290
        if expected:
10612
84468b90e9c1 [py3k] basestring → six.string_types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
  1291
            if len(expected) == 1 and not isinstance(expected[0], string_types):
10476
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1292
                raise ValueError("match_form_params() positional arguments "
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1293
                                 "must be strings")
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1294
            super(match_form_params, self).__init__(*expected)
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1295
        else:
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1296
            super(match_form_params, self).__init__(kwargs)
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1297
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1298
    def _values_set(self, cls, req, **kwargs):
10476
62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 10381
diff changeset
  1299
        return req.form
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1300
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1301
8751
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1302
class match_http_method(ExpectedValuePredicate):
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1303
    """Return non-zero score if one of the HTTP methods specified as
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1304
    initializer arguments is the HTTP method of the request (GET, POST, ...).
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1305
    """
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1306
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1307
    def __call__(self, cls, req, **kwargs):
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1308
        return int(req.http_method() in self.expected)
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1309
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1310
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1311
class match_edited_type(ExpectedValuePredicate):
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1312
    """return non-zero if main edited entity type is the one specified as
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1313
    initializer argument, or is among initializer arguments if `mode` == 'any'.
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1314
    """
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1315
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1316
    def _values_set(self, cls, req, **kwargs):
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1317
        try:
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1318
            return frozenset((req.form['__type:%s' % req.form['__maineid']],))
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1319
        except KeyError:
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1320
            return frozenset()
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1321
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1322
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1323
class match_form_id(ExpectedValuePredicate):
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1324
    """return non-zero if request form identifier is the one specified as
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1325
    initializer argument, or is among initializer arguments if `mode` == 'any'.
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1326
    """
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1327
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1328
    def _values_set(self, cls, req, **kwargs):
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1329
        try:
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1330
            return frozenset((req.form['__form_id'],))
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1331
        except KeyError:
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1332
            return frozenset()
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1333
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1334
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
  1335
class specified_etype_implements(is_instance):
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1336
    """Return non-zero score if the entity type specified by an 'etype' key
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1337
    searched in (by priority) input context kwargs and request form parameters
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1338
    match a known entity type (case insensitivly), and it's associated entity
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
  1339
    class is of one of the type(s) given to the initializer. If multiple
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
  1340
    arguments are given, matching one of them is enough.
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1341
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1342
    .. note:: as with :class:`~cubicweb.predicates.is_instance`, entity types
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5858
diff changeset
  1343
              should be given as string and the score will reflect class
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1344
              proximity so the most specific object will be selected.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1345
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1346
    This predicate is usually used by views holding entity creation forms (since
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1347
    we've no result set to work on).
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1348
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1349
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1350
    def __call__(self, cls, req, **kwargs):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1351
        try:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1352
            etype = kwargs['etype']
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1353
        except KeyError:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1354
            try:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1355
                etype = req.form['etype']
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1356
            except KeyError:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1357
                return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1358
            else:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1359
                # only check this is a known type if etype comes from req.form,
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1360
                # else we want the error to propagate
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1361
                try:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1362
                    etype = req.vreg.case_insensitive_etypes[etype.lower()]
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1363
                    req.form['etype'] = etype
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1364
                except KeyError:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1365
                    return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1366
        score = self.score_class(req.vreg['etypes'].etype_class(etype), req)
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1367
        if score:
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1368
            eschema = req.vreg.schema.eschema(etype)
10636
a9e9daf77598 [predicates] Simplify specified_etype_implements
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10381
diff changeset
  1369
            if eschema.may_have_permission('add', req):
3276
4480887772a3 [selectors] score_entity selector now ensures an int score is returned
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2972
diff changeset
  1370
                return score
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1371
        return 0
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1372
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1373
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1374
class attribute_edited(EntityPredicate):
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1375
    """Scores if the specified attribute has been edited This is useful for
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1376
    selection of forms by the edit controller.
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1377
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1378
    The initial use case is on a form, in conjunction with match_transition,
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1379
    which will not score at edit time::
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1380
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1381
     is_instance('Version') & (match_transition('ready') |
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1382
                               attribute_edited('publication_date'))
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1383
    """
12508
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11956
diff changeset
  1384
    def __init__(self, attribute, mode='all'):
a8c1ea390400 Drop most of deprecated code
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11956
diff changeset
  1385
        super(attribute_edited, self).__init__(mode=mode)
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1386
        self._attribute = attribute
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1387
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1388
    def score_entity(self, entity):
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1389
        return eid_param(role_name(self._attribute, 'subject'), entity.eid) in entity._cw.form
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1390
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1391
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1392
# Other predicates ##############################################################
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1393
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1394
class match_exception(ExpectedValuePredicate):
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1395
    """Return 1 if exception given as `exc` in the input context is an instance
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1396
    of one of the class given on instanciation of this predicate.
5044
1d9bef4a2b0c [selectors] new is_in_state select to avoid common error when writing state based selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4833
diff changeset
  1397
    """
6465
6401a9d0b5aa [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6457
diff changeset
  1398
    def __init__(self, *expected):
6401a9d0b5aa [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6457
diff changeset
  1399
        assert expected, self
7955
f4c97d3c8b93 [selectors] match_kwargs and match_form_params selectors both accept a new `once_is_enough` argument (closes #1990438)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
  1400
        # we want a tuple, not a set as done in the parent class
6465
6401a9d0b5aa [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6457
diff changeset
  1401
        self.expected = expected
6401a9d0b5aa [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6457
diff changeset
  1402
6401a9d0b5aa [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6457
diff changeset
  1403
    def __call__(self, cls, req, exc=None, **kwargs):
6401a9d0b5aa [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6457
diff changeset
  1404
        if exc is not None and isinstance(exc, self.expected):
6401a9d0b5aa [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6457
diff changeset
  1405
            return 1
6401a9d0b5aa [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6457
diff changeset
  1406
        return 0
6401a9d0b5aa [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6457
diff changeset
  1407
5044
1d9bef4a2b0c [selectors] new is_in_state select to avoid common error when writing state based selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4833
diff changeset
  1408
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1409
@objectify_predicate
5480
2d5c46e78ae9 [css] introducing scale and rhythm composition
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5452
diff changeset
  1410
def debug_mode(cls, req, rset=None, **kwargs):
6395
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1411
    """Return 1 if running in debug mode."""
5480
2d5c46e78ae9 [css] introducing scale and rhythm composition
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5452
diff changeset
  1412
    return req.vreg.config.debugmode and 1 or 0