predicates.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 02 Sep 2015 15:31:18 +0200
changeset 10634 06a43f727601
parent 10381 ef9607fac387
child 10476 62251bfdfd79
child 10636 a9e9daf77598
permissions -rw-r--r--
[web/views] avoid propagation of NoSelectableObject in some case of inlined relations / permissions When selecting an inlined creation form, we should catch the NoSelectable exception that will be raised if the user cannot add entities of the target type (this is not and cannot be verified earlier) or if some other custom selector prevents the form from being selected. Closes #6510921
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/>.
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    18
""".. _Selectors:
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    19
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    20
Predicates and selectors
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    21
------------------------
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    22
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    23
A predicate is a class testing a particular aspect of a context. A selector is
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    24
built by combining existant predicates or even selectors.
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    25
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    26
Using and combining existant predicates
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    27
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    28
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    29
You can combine predicates using the `&`, `|` and `~` operators.
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    30
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    31
When two predicates are combined using the `&` operator, it means that
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    32
both should return a positive score. On success, the sum of scores is
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    33
returned.
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    34
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    35
When two predicates are combined using the `|` operator, it means that
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    36
one of them should return a positive score. On success, the first
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    37
positive score is returned.
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    38
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    39
You can also "negate" a predicate by precedeing it by the `~` unary operator.
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    40
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    41
Of course you can use parenthesis to balance expressions.
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    42
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    43
Example
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    44
~~~~~~~
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    45
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    46
The goal: when on a blog, one wants the RSS link to refer to blog entries, not to
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    47
the blog entity itself.
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    48
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    49
To do that, one defines a method on entity classes that returns the
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    50
RSS stream url for a given entity. The default implementation on
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    51
:class:`~cubicweb.entities.AnyEntity` (the generic entity class used
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    52
as base for all others) and a specific implementation on `Blog` will
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    53
do what we want.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
    54
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    55
But when we have a result set containing several `Blog` entities (or
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    56
different entities), we don't know on which entity to call the
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    57
aforementioned method. In this case, we keep the generic behaviour.
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    58
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    59
Hence we have two cases here, one for a single-entity rsets, the other for
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    60
multi-entities rsets.
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    61
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    62
In web/views/boxes.py lies the RSSIconBox class. Look at its selector:
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    63
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    64
.. sourcecode:: python
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    65
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
    66
  class RSSIconBox(box.Box):
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
    67
    ''' just display the RSS icon on uniform result set '''
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
    68
    __select__ = box.Box.__select__ & non_final_entity()
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    69
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    70
It takes into account:
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    71
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    72
* the inherited selection criteria (one has to look them up in the class
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    73
  hierarchy to know the details)
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    74
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    75
* :class:`~cubicweb.predicates.non_final_entity`, which filters on result sets
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    76
  containing non final entities (a 'final entity' being synonym for entity
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    77
  attributes type, eg `String`, `Int`, etc)
718
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
    78
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    79
This matches our second case. Hence we have to provide a specific component for
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    80
the first case:
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    81
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    82
.. sourcecode:: python
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    83
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    84
  class EntityRSSIconBox(RSSIconBox):
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    85
    '''just display the RSS icon on uniform result set for a single entity'''
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    86
    __select__ = RSSIconBox.__select__ & one_line_rset()
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    87
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    88
Here, one adds the :class:`~cubicweb.predicates.one_line_rset` predicate, which
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    89
filters result sets of size 1. Thus, on a result set containing multiple
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    90
entities, :class:`one_line_rset` makes the EntityRSSIconBox class non
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    91
selectable. However for a result set with one entity, the `EntityRSSIconBox`
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    92
class will have a higher score than `RSSIconBox`, which is what we wanted.
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    93
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    94
Of course, once this is done, you have to:
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    95
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    96
* fill in the call method of `EntityRSSIconBox`
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    97
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    98
* provide the default implementation of the method returning the RSS stream url
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
    99
  on :class:`~cubicweb.entities.AnyEntity`
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   100
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   101
* redefine this method on `Blog`.
718
f7011679437a doc update, move yes_registerer here
sylvain.thenault@logilab.fr
parents: 697
diff changeset
   102
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   103
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   104
When to use selectors?
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   105
~~~~~~~~~~~~~~~~~~~~~~
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   106
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   107
Selectors are to be used whenever arises the need of dispatching on the shape or
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   108
content of a result set or whatever else context (value in request form params,
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   109
authenticated user groups, etc...). That is, almost all the time.
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   110
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   111
Here is a quick example:
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   112
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   113
.. sourcecode:: python
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   114
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   115
    class UserLink(component.Component):
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   116
	'''if the user is the anonymous user, build a link to login else a link
5608
f9ab62103ad4 proof read documentation
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5502
diff changeset
   117
	to the connected user object with a logout link
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   118
	'''
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   119
	__regid__ = 'loggeduserlink'
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   120
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   121
	def call(self):
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
   122
	    if self._cw.session.anonymous_session:
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   123
		# display login link
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   124
		...
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   125
	    else:
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   126
		# display a link to the connected user object with a loggout link
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   127
		...
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   128
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   129
The proper way to implement this with |cubicweb| is two have two different
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   130
classes sharing the same identifier but with different selectors so you'll get
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
   131
the correct one according to the context.
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   132
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
   133
.. sourcecode:: python
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   134
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   135
    class UserLink(component.Component):
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   136
	'''display a link to the connected user object with a loggout link'''
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   137
	__regid__ = 'loggeduserlink'
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   138
	__select__ = component.Component.__select__ & authenticated_user()
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   139
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   140
	def call(self):
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   141
            # display useractions and siteactions
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   142
	    ...
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   143
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   144
    class AnonUserLink(component.Component):
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   145
	'''build a link to login'''
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   146
	__regid__ = 'loggeduserlink'
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   147
	__select__ = component.Component.__select__ & anonymous_user()
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   148
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   149
	def call(self):
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   150
	    # display login link
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   151
            ...
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   152
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
   153
The big advantage, aside readability once you're familiar with the
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
   154
system, is that your cube becomes much more easily customizable by
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
   155
improving componentization.
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   156
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   157
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   158
.. _CustomPredicates:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   159
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   160
Defining your own predicates
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   161
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   162
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   163
.. autodocstring:: cubicweb.appobject::objectify_predicate
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   164
5306
763319a51e72 [doc/book] some fixes for vregistry, selectors & appobjects
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5281
diff changeset
   165
In other cases, you can take a look at the following abstract base classes:
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   166
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   167
.. autoclass:: cubicweb.predicates.ExpectedValuePredicate
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   168
.. autoclass:: cubicweb.predicates.EClassPredicate
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   169
.. autoclass:: cubicweb.predicates.EntityPredicate
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   170
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   171
.. _DebuggingSelectors:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   172
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   173
Debugging selection
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   174
~~~~~~~~~~~~~~~~~~~
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   175
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   176
Once in a while, one needs to understand why a view (or any application object)
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   177
is, or is not selected appropriately. Looking at which predicates fired (or did
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   178
not) is the way. The :class:`logilab.common.registry.traced_selection` context
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   179
manager to help with that, *if you're running your instance in debug mode*.
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   180
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   181
.. autoclass:: logilab.common.registry.traced_selection
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   182
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   183
"""
5886
00a78298d30d cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5732
diff changeset
   184
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   185
__docformat__ = "restructuredtext en"
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   186
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   187
import logging
4719
aaed3f813ef8 kill dead/useless code as suggested by pylint
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4664
diff changeset
   188
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
   189
from operator import eq
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   190
10381
ef9607fac387 [predicates] Use proper deprecation mechanisms
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10019
diff changeset
   191
from logilab.common.deprecation import deprecated
8872
b638a99ab9cf [predicates] keep making `yes` predicate importable from cubicweb (closes #2790319)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8866
diff changeset
   192
from logilab.common.registry import Predicate, objectify_predicate, yes
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   193
6106
1e6d93f70d14 [selectors] fix match_transition & introduce new edited_attribute selector
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6046
diff changeset
   194
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
   195
from rql.nodes import Function
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   196
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
   197
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
   198
                      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
   199
from cubicweb.uilib import eid_param
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   200
from cubicweb.schema import split_expression
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   201
10381
ef9607fac387 [predicates] Use proper deprecation mechanisms
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10019
diff changeset
   202
yes = deprecated('[3.15] import yes() from use logilab.common.registry')(yes)
8872
b638a99ab9cf [predicates] keep making `yes` predicate importable from cubicweb (closes #2790319)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8866
diff changeset
   203
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   204
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   205
# 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
   206
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   207
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
   208
    """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
   209
    class to find missing information.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   210
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   211
    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
   212
    """
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   213
    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
   214
        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
   215
        return super(PartialPredicateMixIn, self).__call__(cls, *args, **kwargs)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   216
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   217
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   218
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
   219
    """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
   220
    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
   221
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   222
    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
   223
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   224
    * 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
   225
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
   226
    * 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
   227
      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
   228
      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
   229
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
   230
    * 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
   231
      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
   232
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
   233
    * 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
   234
      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
   235
      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
   236
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
   237
    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
   238
    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
   239
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
   240
      - `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
   241
        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
   242
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
   243
      - `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
   244
        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
   245
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   246
      - `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
   247
        (this may occurs with outer join)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   248
    """
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
   249
    def __init__(self, once_is_enough=None, accept_none=True, 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
   250
        if once_is_enough is not None:
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
   251
            warn("[3.14] once_is_enough is deprecated, use 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
   252
                 DeprecationWarning, stacklevel=2)
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
   253
            if 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
   254
                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
   255
        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
   256
        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
   257
        self.accept_none = accept_none
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   258
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
   259
    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
   260
                 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
   261
                 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
   262
                 **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
   263
        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
   264
            return self.score_class(entity.__class__, req)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   265
        if not rset:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   266
            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
   267
        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
   268
            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
   269
        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
   270
            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
   271
                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
   272
            if not accept_none and \
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
   273
                   any(rset[i][col] is None for i in xrange(len(rset))):
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
   274
                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
   275
            etypes = rset.column_types(col)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   276
        else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   277
            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
   278
            # 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
   279
            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
   280
                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
   281
            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
   282
        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
   283
        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
   284
            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
   285
            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
   286
                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
   287
            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
   288
                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
   289
            score += escore
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   290
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   291
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   292
    def score(self, cls, req, etype):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   293
        if etype in BASE_TYPES:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   294
            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
   295
        return self.score_class(req.vreg['etypes'].etype_class(etype), req)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   296
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   297
    def score_class(self, eclass, req):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   298
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   299
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   300
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   301
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
   302
    """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
   303
    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
   304
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   305
    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
   306
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   307
    * 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
   308
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
   309
    * 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
   310
      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
   311
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   312
    * 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
   313
      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
   314
      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
   315
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
   316
      - `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
   317
        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
   318
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
   319
      - `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
   320
        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
   321
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   322
      - `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
   323
        (this may occurs with outer join)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   324
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   325
    .. Note::
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   326
       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
   327
       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
   328
       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
   329
       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
   330
       which may be much more costly.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   331
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   332
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
   333
    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
   334
                 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
   335
        if not rset and entity is None:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   336
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   337
        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
   338
        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
   339
            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
   340
        elif row is None:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   341
            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
   342
            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
   343
                accept_none = self.accept_none
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   344
            for row, rowvalue in enumerate(rset.rows):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   345
                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
   346
                    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
   347
                        return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   348
                    continue
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 650
diff changeset
   349
                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
   350
                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
   351
                    return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   352
                elif self.once_is_enough:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   353
                    return escore
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   354
                score += escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   355
        else:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   356
            col = col or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   357
            etype = rset.description[row][col]
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   358
            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
   359
                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
   360
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   361
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   362
    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
   363
        try:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   364
            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
   365
        except NotAnEntity:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   366
            return 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   367
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   368
    def score_entity(self, entity):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   369
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   370
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   371
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   372
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
   373
    """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
   374
    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
   375
    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
   376
    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
   377
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
   378
    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
   379
    :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
   380
    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
   381
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
   382
    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
   383
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
   384
    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
   385
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
   386
    - 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
   387
      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
   388
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
   389
    - 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
   390
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
   391
    - 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
   392
8032
bcb87336c7d2 [doc] fix most of ReST compilation errors and warnings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   393
    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
   394
    """
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
   395
    def __init__(self, *expected, **kwargs):
774
48cb1f42e79c tell on which class the assertion's failed
sylvain.thenault@logilab.fr
parents: 770
diff changeset
   396
        assert expected, self
7173
c6eb201d4410 [selectors] abstract ExpectedValueSelector now accept a set as single argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6919
diff changeset
   397
        if len(expected) == 1 and isinstance(expected[0], set):
c6eb201d4410 [selectors] abstract ExpectedValueSelector now accept a set as single argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6919
diff changeset
   398
            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
   399
        else:
c6eb201d4410 [selectors] abstract ExpectedValueSelector now accept a set as single argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6919
diff changeset
   400
            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
   401
        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
   402
        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
   403
        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
   404
        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
   405
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   406
    def __str__(self):
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   407
        return '%s(%s)' % (self.__class__.__name__,
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   408
                           ','.join(sorted(str(s) for s in self.expected)))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   409
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
   410
    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
   411
        values = self._values_set(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
   412
        matching = len(values & 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
   413
        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
   414
            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
   415
        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
   416
            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
   417
        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
   418
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
   419
    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
   420
        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
   421
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
   422
    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
   423
        raise NotImplementedError()
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   424
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   425
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   426
# bare predicates ##############################################################
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
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 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
   429
    """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
   430
    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
   431
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
   432
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
   433
    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
   434
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
   435
    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
   436
    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
   437
    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
   438
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   439
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
   440
    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
   441
        return frozenset(kwargs)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   442
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   443
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   444
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
   445
    """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
   446
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
   447
    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
   448
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
    * `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
   450
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   451
    * `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
   452
      selectable.
1263
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   453
    """
5561
58b05c314443 [selectors] ensure adaptable('IDownloadable') takes precedence over implements('Any')
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5557
diff changeset
   454
    selectable_score = 1
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   455
    def __init__(self, registry, *regids):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   456
        self.registry = registry
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   457
        self.regids = regids
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   458
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
   459
    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
   460
        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
   461
            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
   462
                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
   463
        return 0
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   464
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   465
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   466
class adaptable(appobject_selectable):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   467
    """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
   468
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   469
    Initializer arguments:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   470
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   471
    * `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
   472
      (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
   473
      when multiple identifiers are given.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   474
    """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   475
    def __init__(self, *regids):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   476
        super(adaptable, self).__init__('adapters', *regids)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   477
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
   478
    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
   479
        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
   480
        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
   481
        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
   482
            # 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
   483
            # 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
   484
            # same adapter can't be used for each type
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
   485
            for row in xrange(len(kwargs['rset'])):
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
   486
                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
   487
                _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
   488
                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
   489
                    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
   490
                # 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
   491
                # 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
   492
                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
   493
        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
   494
            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
   495
        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
   496
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
   497
    @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
   498
    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
   499
        # 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
   500
        # 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
   501
        # 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
   502
        # * 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
   503
        # * 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
   504
        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
   505
            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
   506
        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
   507
            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
   508
        return score
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   509
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
   510
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   511
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
   512
    """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
   513
    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
   514
    """
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   515
    # 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
   516
    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
   517
        self._key = key
6402
a589df8b9b66 [selector] fix iterable detection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6397
diff changeset
   518
        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
   519
            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
   520
        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
   521
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
   522
    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
   523
        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
   524
            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
   525
        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
   526
            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
   527
                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
   528
            else:
980f4415baab [selectors] make configuration_values selector works for startup/maintainance hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6402
diff changeset
   529
                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
   530
            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
   531
        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
   532
6402
a589df8b9b66 [selector] fix iterable detection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6397
diff changeset
   533
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   534
# 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
   535
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   536
@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
   537
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
   538
    """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
   539
    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
   540
        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
   541
    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
   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
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   544
# 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
   545
@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
   546
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
   547
    """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
   548
    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
   549
        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
   550
    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
   551
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   552
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   553
@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
   554
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
   555
    """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
   556
    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
   557
        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
   558
    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
   559
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   560
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   561
# 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
   562
@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
   563
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
   564
    """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
   565
    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
   566
        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
   567
    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
   568
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   569
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   570
# 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
   571
@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
   572
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
   573
    """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
   574
      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
   575
    """
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
   576
    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
   577
        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
   578
    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
   579
        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
   580
    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
   581
c57c8176b8c2 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
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   583
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
   584
    """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
   585
    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
   586
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   587
    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
   588
        `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
   589
    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
   590
        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
   591
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   592
    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
   593
    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
   594
    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
   595
    """
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   596
    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
   597
        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
   598
        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
   599
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   600
    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
   601
        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
   602
            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
   603
        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
   604
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   605
    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
   606
        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
   607
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   608
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   609
class multi_columns_rset(multi_lines_rset):
5452
4ac3ea9face9 [doc] typos
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   610
    """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
   611
    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
   612
    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
   613
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   614
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   615
    def __call__(self, cls, req, rset=None, **kwargs):
8397
42ec34b3ced9 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8190
diff changeset
   616
        # '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
   617
        # 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
   618
        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
   619
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   620
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   621
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
   622
    """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
   623
    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
   624
    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
   625
    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
   626
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   627
    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
   628
    * 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
   629
    * 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
   630
    * 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
   631
    """
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
   632
    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
   633
        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
   634
        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
   635
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
   636
    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
   637
        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
   638
            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
   639
        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
   640
        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
   641
            page_size = req.form.get('page_size')
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
   642
            if page_size 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
   643
                page_size = req.property_value('navigation.page-size')
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
   644
            else:
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
   645
                page_size = int(page_size)
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
   646
        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
   647
            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
   648
        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
   649
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   650
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   651
@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
   652
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
   653
    """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
   654
    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
   655
    '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
   656
    """
c57c8176b8c2 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
    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
   658
        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
   659
    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
   660
    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
   661
        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
   662
        (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
   663
         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
   664
        ):
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
        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
   666
    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
   667
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   668
c57c8176b8c2 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
# 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
   670
@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
   671
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
   672
    """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
   673
    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
   674
    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
   675
    """
c57c8176b8c2 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
    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
   677
        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
   678
    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
   679
        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
   680
    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
   681
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   682
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   683
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
   684
    """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
   685
    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
   686
    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
   687
    *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
   688
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   689
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   690
    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
   691
        # '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
   692
        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
   693
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   694
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   695
@objectify_predicate
5502
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   696
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
   697
    """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
   698
    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
   699
    """
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   700
    if rset is None:
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   701
        return 0
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   702
    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
   703
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   704
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   705
# 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
   706
9547
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   707
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
   708
    """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
   709
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   710
    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
   711
    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
   712
    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
   713
    """
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   714
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   715
    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
   716
        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
   717
        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
   718
            return 0
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   719
        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
   720
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   721
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   722
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   723
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
   724
    """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
   725
    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
   726
    `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
   727
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   728
    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
   729
    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
   730
    """
c57c8176b8c2 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
    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
   732
        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
   733
            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
   734
        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
   735
4664
bd5ecd5b9494 #714109: [selectors] non_final_entity should implement score_class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4545
diff changeset
   736
    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
   737
        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
   738
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   739
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
   740
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
   741
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
   742
    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
   743
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
   744
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
   745
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   746
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
   747
    """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
   748
    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
   749
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
   750
    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
   751
    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
   752
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   753
    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
   754
    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
   755
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
   756
    .. 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
   757
              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
   758
    """
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
   759
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
   760
    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
   761
        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
   762
        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
   763
        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
   764
            assert isinstance(etype, basestring), etype
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
   765
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
   766
    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
   767
        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
   768
                           ','.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
   769
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
   770
    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
   771
        # 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
   772
        try:
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   773
            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
   774
        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
   775
            # 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
   776
            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
   777
        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
   778
            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
   779
        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
   780
            # 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
   781
            #  (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
   782
            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
   783
            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
   784
            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
   785
                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
   786
                    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
   787
                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
   788
                    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
   789
        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
   790
        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
   791
        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
   792
            # 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
   793
            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
   794
                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
   795
            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
   796
                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
   797
            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
   798
                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
   799
                    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
   800
                        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
   801
                        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
   802
        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
   803
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   804
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   805
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
   806
    """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
   807
    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
   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
    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
   810
    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
   811
6869
900cb9b1b687 [tests] new unit tests about score_entity selector (inscore machinery)
Julien Jehannet <julien@smaf.org>
parents: 6615
diff changeset
   812
    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
   813
    value at the end.
900cb9b1b687 [tests] new unit tests about score_entity selector (inscore machinery)
Julien Jehannet <julien@smaf.org>
parents: 6615
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
    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
   816
    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
   817
    """
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
   818
    def __init__(self, scorefunc, once_is_enough=None, 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
   819
        super(score_entity, self).__init__(mode=mode, once_is_enough=once_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
   820
        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
   821
            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
   822
            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
   823
                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
   824
            if isinstance(score, (int, long)):
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   825
                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
   826
            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
   827
        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
   828
c57c8176b8c2 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
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   830
class has_mimetype(EntityPredicate):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   831
    """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
   832
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   833
    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
   834
    only PNG images.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   835
    """
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
   836
    def __init__(self, mimetype, once_is_enough=None, 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
   837
        super(has_mimetype, self).__init__(mode=mode, once_is_enough=once_is_enough)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   838
        self.mimetype = mimetype
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   839
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   840
    def score_entity(self, entity):
5858
384d34e76d6d cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5736
diff changeset
   841
        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
   842
        if idownloadable is None:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   843
            return 0
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   844
        mt = idownloadable.download_content_type()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   845
        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
   846
            return 0
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   847
        return 1
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   848
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   849
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   850
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
   851
    """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
   852
    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
   853
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   854
    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
   855
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
   856
    * `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
   857
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   858
    * `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
   859
      '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
   860
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   861
    * `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
   862
      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
   863
c57c8176b8c2 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
    * `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
   865
      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
   866
      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
   867
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
    * `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
   869
      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
   870
      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
   871
c57c8176b8c2 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
      - 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
   873
        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
   874
        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
   875
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   876
      - 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
   877
        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
   878
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   879
    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
   880
    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
   881
    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
   882
    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
   883
    according to the input context.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   884
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   885
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   886
    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
   887
                 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
   888
        super(relation_possible, self).__init__(**kwargs)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   889
        self.rtype = rtype
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   890
        self.role = role
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   891
        self.target_etype = target_etype
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   892
        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
   893
        self.strict = strict
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
    # 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
   896
    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
   897
        # 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
   898
        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
   899
            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
   900
        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
   901
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   902
    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
   903
        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
   904
            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
   905
        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
   906
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   907
    def _get_rschema(self, eclass):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   908
        eschema = eclass.e_schema
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   909
        try:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   910
            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
   911
                return eschema.objrels[self.rtype]
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   912
            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
   913
                return eschema.subjrels[self.rtype]
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   914
        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
   915
            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
   916
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   917
    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
   918
        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
   919
        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
   920
            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
   921
        eschema = eclass.e_schema
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   922
        if self.target_etype is not None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   923
            try:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   924
                rdef = rschema.role_rdef(eschema, self.target_etype, self.role)
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1037
diff changeset
   925
            except KeyError:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   926
                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
   927
            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
   928
                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
   929
            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
   930
            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
   931
                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
   932
        elif self.action:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   933
            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
   934
        return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   935
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   936
    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
   937
        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
   938
        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
   939
            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
   940
        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
   941
            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
   942
                try:
b0155bfd4e17 Protect against crash in the `relation_possible` predicate with ambiguous relations.
Florent Cayre <florent.cayre@logilab.fr>
parents: 8872
diff changeset
   943
                    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
   944
                                                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
   945
                except KeyError:
b0155bfd4e17 Protect against crash in the `relation_possible` predicate with ambiguous relations.
Florent Cayre <florent.cayre@logilab.fr>
parents: 8872
diff changeset
   946
                    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
   947
            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
   948
                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
   949
                    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
   950
            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
   951
                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
   952
        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
   953
            req = entity._cw
aa01eb033620 [selectors] fix dumb name error introduced in parent changeset
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5900
diff changeset
   954
            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
   955
            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
   956
                return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   957
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   958
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   959
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   960
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
   961
    """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
   962
    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
   963
    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
   964
    as initializer arguments.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   965
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   966
    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
   967
    customized.
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   968
    """
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
   969
    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
   970
        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
   971
                                                        action, **kwargs)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   972
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   973
    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
   974
        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
   975
        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
   976
        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
   977
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   978
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   979
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
   980
    """Return 1 if entity support the specified relation and has some linked
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   981
    entities by this relation , optionaly filtered according to the 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
   982
    target type.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   983
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
   984
    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
   985
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   986
    * `rtype`, the name of the relation
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   987
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
    * `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
   989
      '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
   990
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   991
    * `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
   992
      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
   993
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   994
    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
   995
    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
   996
    """
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
   997
    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
   998
        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
   999
        self.rtype = rtype
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1000
        self.role = role
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1001
        self.target_etype = target_etype
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1002
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1003
    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
  1004
        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
  1005
        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
  1006
            return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1007
        rset = entity.related(self.rtype, self.role)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1008
        if self.target_etype:
1011
22812cfe36b4 fix w/ rset with more than one column
sylvain.thenault@logilab.fr
parents: 876
diff changeset
  1009
            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
  1010
        return rset and 1 or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1011
833
8c6bfd9158fb bw compat for selection for creation forms
sylvain.thenault@logilab.fr
parents: 828
diff changeset
  1012
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1013
class partial_has_related_entities(PartialPredicateMixIn, has_related_entities):
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1014
    """Same as :class:~`cubicweb.predicates.has_related_entity`, 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
  1015
    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
  1016
    expected by the initializer.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1017
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1018
    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
  1019
    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
  1020
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1021
    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
  1022
        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
  1023
                                                           **kwargs)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1024
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
  1025
    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
  1026
        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
  1027
        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
  1028
        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
  1029
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
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
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
  1032
    """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
  1033
    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
  1034
    of 'read', 'add', 'delete', 'update').
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1035
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
  1036
    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
  1037
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1038
    * 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
  1039
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
  1040
    * 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
  1041
      in the specified cell
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1042
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
  1043
    * 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
  1044
      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
  1045
    """
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
  1046
    def __init__(self, action):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1047
        self.action = action
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1048
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1049
    # 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
  1050
    # 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
  1051
    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
  1052
        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
  1053
            return self.score_entity(entity)
788
d62fb3e9797d protect against None rset
sylvain.thenault@logilab.fr
parents: 784
diff changeset
  1054
        if rset is None:
d62fb3e9797d protect against None rset
sylvain.thenault@logilab.fr
parents: 784
diff changeset
  1055
            return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1056
        if row is None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1057
            score = 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1058
            need_local_check = []
2816
85f7502d32be access schema through req.vreg
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2797
diff changeset
  1059
            geteschema = req.vreg.schema.eschema
6360
1edfc0f3bb1d [selector] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6348
diff changeset
  1060
            user = req.user
1edfc0f3bb1d [selector] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6348
diff changeset
  1061
            action = self.action
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1062
            for etype in rset.column_types(0):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1063
                if etype in BASE_TYPES:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1064
                    return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1065
                eschema = geteschema(etype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1066
                if not user.matching_groups(eschema.get_groups(action)):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1067
                    if eschema.has_local_role(action):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1068
                        # have to ckeck local roles
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1069
                        need_local_check.append(eschema)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1070
                        continue
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1071
                    else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1072
                        # even a local role won't be enough
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1073
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1074
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1075
            if need_local_check:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1076
                # check local role for entities of necessary types
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1077
                for i, row in enumerate(rset):
6360
1edfc0f3bb1d [selector] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6348
diff changeset
  1078
                    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
  1079
                        continue
6364
ad9ed9803eb6 cleanup and micro-optimization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6360
diff changeset
  1080
                    # micro-optimisation instead of calling self.score(req,
ad9ed9803eb6 cleanup and micro-optimization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6360
diff changeset
  1081
                    # rset, i, col): rset may be large
ad9ed9803eb6 cleanup and micro-optimization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6360
diff changeset
  1082
                    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
  1083
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1084
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1085
            return score
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
  1086
        return self.score(req, rset, row, col)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1087
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1088
    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
  1089
        if entity.cw_has_perm(self.action):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1090
            return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1091
        return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1092
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1093
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1094
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
  1095
    """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
  1096
    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
  1097
    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
  1098
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
  1099
    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
  1100
    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
  1101
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1102
    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
  1103
    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
  1104
    not specified.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1105
    """
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
  1106
    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
  1107
        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
  1108
        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
  1109
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1110
    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
  1111
        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
  1112
            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
  1113
        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
  1114
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1115
    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
  1116
        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
  1117
        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
  1118
               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
  1119
            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
  1120
        return 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1121
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1122
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1123
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
  1124
    """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
  1125
    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
  1126
    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
  1127
    condition.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1128
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
  1129
    `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
  1130
    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
  1131
    represent the request's user.
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1132
6871
b746dae3a004 [docstring] minor: add warning about entity cache for rql_condition selector
Julien Jehannet <julien@smaf.org>
parents: 6870
diff changeset
  1133
    .. warning::
b746dae3a004 [docstring] minor: add warning about entity cache for rql_condition selector
Julien Jehannet <julien@smaf.org>
parents: 6870
diff changeset
  1134
        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
  1135
        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
  1136
        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
  1137
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1138
    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
  1139
    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
  1140
    """
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
  1141
    def __init__(self, expression, once_is_enough=None, mode='all', user_condition=False):
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
  1142
        super(rql_condition, self).__init__(mode=mode, once_is_enough=once_is_enough)
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
  1143
        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
  1144
        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
  1145
            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
  1146
        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
  1147
            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
  1148
        else:
6457
3234d8d6e264 [selector] more efficient rql_condition by simply retreiving COUNT()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6445
diff changeset
  1149
            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
  1150
        self.rql = rql
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1151
6870
658039c5eeac [selectors] minor: use similar __repr__ implementation for selector instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6869
diff changeset
  1152
    def __str__(self):
658039c5eeac [selectors] minor: use similar __repr__ implementation for selector instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6869
diff changeset
  1153
        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
  1154
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
  1155
    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
  1156
        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
  1157
            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
  1158
                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
  1159
            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
  1160
                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
  1161
        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
  1162
            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
  1163
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
  1164
    def _score(self, req, eid):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1165
        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
  1166
            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
  1167
        except Unauthorized:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1168
            return 0
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
  1169
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
  1170
    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
  1171
        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
  1172
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
  1173
    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
  1174
        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
  1175
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
  1176
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1177
# 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
  1178
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1179
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
  1180
    """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
  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
    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
  1183
    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
  1184
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1185
    * 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
  1186
    * 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
  1187
      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
  1188
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1189
    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
  1190
    (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
  1191
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1192
    :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
  1193
    """
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1194
    def __init__(self, *expected):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1195
        assert expected, self
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1196
        self.expected = frozenset(expected)
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1197
        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
  1198
            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
  1199
            # 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
  1200
            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
  1201
                # 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
  1202
                # 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
  1203
                # 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
  1204
                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
  1205
                    self._validate(adapted)
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1206
            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
  1207
        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
  1208
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1209
    def _score(self, adapted):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1210
        trinfo = adapted.latest_trinfo()
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1211
        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
  1212
            statename = adapted.state
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1213
        else:
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1214
            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
  1215
        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
  1216
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1217
    def _validate(self, adapted):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1218
        wf = adapted.current_workflow
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1219
        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
  1220
        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
  1221
        if unknown:
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1222
            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
  1223
                             % (wf.name, ",".join(unknown)))
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1224
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1225
    def __str__(self):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1226
        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
  1227
                           ','.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
  1228
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1229
9344
4da3ef764395 [predicates] allow multiple transition names in on_fire_transition (closes #3013720)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9256
diff changeset
  1230
def on_fire_transition(etype, tr_names, from_state_name=None):
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
  1231
    """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
  1232
    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
  1233
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1234
    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
  1235
    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
  1236
    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
  1237
    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
  1238
    but also its original state, transition, destination state, user...).
7559
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7529
diff changeset
  1239
7529
2fdc310be7cd [book] add autoload section from code and fix sphinx warnings
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 7452
diff changeset
  1240
    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
  1241
    """
9344
4da3ef764395 [predicates] allow multiple transition names in on_fire_transition (closes #3013720)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9256
diff changeset
  1242
    if from_state_name is not None:
4da3ef764395 [predicates] allow multiple transition names in on_fire_transition (closes #3013720)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9256
diff changeset
  1243
        warn("on_fire_transition's from_state_name argument is unused", DeprecationWarning)
4da3ef764395 [predicates] allow multiple transition names in on_fire_transition (closes #3013720)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9256
diff changeset
  1244
    if isinstance(tr_names, basestring):
4da3ef764395 [predicates] allow multiple transition names in on_fire_transition (closes #3013720)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9256
diff changeset
  1245
        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
  1246
    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
  1247
        # 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
  1248
        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
  1249
                # 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
  1250
                # 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
  1251
                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
  1252
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
  1253
    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
  1254
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1255
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1256
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
  1257
    """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
  1258
    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
  1259
    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
  1260
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1261
    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
  1262
    the web ui.
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1263
    """
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
  1264
    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
  1265
        # 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
  1266
        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
  1267
            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
  1268
            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
  1269
                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
  1270
        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
  1271
            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
  1272
        return 0
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1273
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
  1274
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1275
# 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
  1276
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1277
@objectify_predicate
5490
b7b96b8decf1 [selectors] fix no_cnx selector's prototype
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
  1278
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
  1279
    """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
  1280
    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
  1281
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
  1282
    May only be used on the web side, not on the data repository side.
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
  1283
    """
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
  1284
    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
  1285
        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
  1286
    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
  1287
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1288
@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
  1289
def authenticated_user(cls, req, **kwargs):
9553
be9b12f42d76 [predicates] fix thinko in doc strings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9547
diff changeset
  1290
    """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
  1291
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1292
    May only be used on the web side, not on the data repository side.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1293
    """
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
  1294
    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
  1295
        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
  1296
    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
  1297
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1298
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1299
# XXX == ~ authenticated_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
  1300
def anonymous_user():
9553
be9b12f42d76 [predicates] fix thinko in doc strings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9547
diff changeset
  1301
    """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
  1302
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1303
    May only be used on the web side, not on the data repository side.
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1304
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1305
    return ~ authenticated_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
  1306
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1307
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
  1308
    """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
  1309
    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
  1310
    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
  1311
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1312
    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
  1313
    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
  1314
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1315
    * 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
  1316
      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
  1317
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1318
    * 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
  1319
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1320
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1321
    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
  1322
        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
  1323
            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
  1324
        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
  1325
        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
  1326
            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
  1327
        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
  1328
        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
  1329
            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
  1330
                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
  1331
                    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
  1332
                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
  1333
            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
  1334
                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
  1335
        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
  1336
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1337
# 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
  1338
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6140
diff changeset
  1339
# 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
  1340
@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
  1341
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
  1342
    """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
  1343
c57c8176b8c2 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
    * *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
  1345
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1346
    * 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
  1347
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1348
    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
  1349
    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
  1350
    """
c57c8176b8c2 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
    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
  1352
        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
  1353
    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
  1354
c57c8176b8c2 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
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1356
@objectify_predicate
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1357
def contextual(cls, req, view=None, **kwargs):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1358
    """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
  1359
    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
  1360
        return 1
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1361
    return 0
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1362
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1363
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1364
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
  1365
    """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
  1366
    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
  1367
    """
c57c8176b8c2 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
    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
  1369
        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
  1370
            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
  1371
        return 1
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1372
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
  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 match_context(ExpectedValuePredicate):
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1375
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1376
    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
  1377
        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
  1378
            return 0
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1379
        return 1
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1380
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1381
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6140
diff changeset
  1382
# 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
  1383
@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
  1384
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
  1385
    """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
  1386
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1387
    * 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
  1388
      `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
  1389
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1390
    * 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
  1391
      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
  1392
c57c8176b8c2 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
    * 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
  1394
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1395
    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
  1396
    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
  1397
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1398
    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
  1399
        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
  1400
    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
  1401
                                                    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
  1402
    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
  1403
        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
  1404
    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
  1405
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1406
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1407
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
  1408
    """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
  1409
    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
  1410
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1411
    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
  1412
    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
  1413
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1414
    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
  1415
    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
  1416
    """
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
  1417
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
  1418
    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
  1419
        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
  1420
            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
  1421
                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
  1422
        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
  1423
            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
  1424
        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
  1425
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1426
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1427
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
  1428
    """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
  1429
    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
  1430
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
  1431
    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
  1432
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
  1433
    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
  1434
    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
  1435
    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
  1436
    """
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
  1437
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
  1438
    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
  1439
        return frozenset(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
  1440
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1441
8751
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1442
class match_http_method(ExpectedValuePredicate):
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1443
    """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
  1444
    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
  1445
    """
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1446
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1447
    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
  1448
        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
  1449
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1450
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1451
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
  1452
    """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
  1453
    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
  1454
    """
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1455
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1456
    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
  1457
        try:
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1458
            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
  1459
        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
  1460
            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
  1461
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1462
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1463
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
  1464
    """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
  1465
    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
  1466
    """
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1467
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1468
    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
  1469
        try:
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1470
            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
  1471
        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
  1472
            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
  1473
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1474
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
  1475
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
  1476
    """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
  1477
    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
  1478
    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
  1479
    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
  1480
    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
  1481
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1482
    .. 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
  1483
              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
  1484
              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
  1485
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1486
    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
  1487
    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
  1488
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1489
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1490
    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
  1491
        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
  1492
            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
  1493
        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
  1494
            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
  1495
                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
  1496
            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
  1497
                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
  1498
            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
  1499
                # 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
  1500
                # 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
  1501
                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
  1502
                    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
  1503
                    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
  1504
                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
  1505
                    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
  1506
        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
  1507
        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
  1508
            eschema = req.vreg.schema.eschema(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
  1509
            if eschema.has_local_role('add') or eschema.has_perm(req, 'add'):
3276
4480887772a3 [selectors] score_entity selector now ensures an int score is returned
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2972
diff changeset
  1510
                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
  1511
        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
  1512
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1513
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1514
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
  1515
    """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
  1516
    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
  1517
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1518
    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
  1519
    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
  1520
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1521
     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
  1522
                               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
  1523
    """
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
  1524
    def __init__(self, attribute, once_is_enough=None, 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
  1525
        super(attribute_edited, self).__init__(mode=mode, once_is_enough=once_is_enough)
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
  1526
        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
  1527
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1528
    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
  1529
        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
  1530
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1531
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1532
# 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
  1533
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1534
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
  1535
    """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
  1536
    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
  1537
    """
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
  1538
    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
  1539
        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
  1540
        # 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
  1541
        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
  1542
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
  1543
    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
  1544
        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
  1545
            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
  1546
        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
  1547
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
  1548
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1549
@objectify_predicate
5480
2d5c46e78ae9 [css] introducing scale and rhythm composition
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5452
diff changeset
  1550
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
  1551
    """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
  1552
    return req.vreg.config.debugmode and 1 or 0