predicates.py
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Fri, 24 Jan 2014 13:08:53 +0100
changeset 9547 43aace16a953
parent 9344 4da3ef764395
child 9553 be9b12f42d76
permissions -rw-r--r--
[schema] add composite handling helpers on EntitySchema (related to #3463112) These will help write predicates, hooks, etc.
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
3757
122a01751d59 2.4 compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   191
from logilab.common.compat import all, any
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   192
from logilab.common.interface import implements as implements_iface
8872
b638a99ab9cf [predicates] keep making `yes` predicate importable from cubicweb (closes #2790319)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8866
diff changeset
   193
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
   194
6106
1e6d93f70d14 [selectors] fix match_transition & introduce new edited_attribute selector
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6046
diff changeset
   195
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
   196
from rql.nodes import Function
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   197
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
   198
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
   199
                      CW_EVENT_MANAGER, role)
2657
de974465d381 [appobject] kill VObject class, move base selector classes to appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   200
# even if not used, let yes here so it's importable through this module
6106
1e6d93f70d14 [selectors] fix match_transition & introduce new edited_attribute selector
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6046
diff changeset
   201
from cubicweb.uilib import eid_param
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   202
from cubicweb.schema import split_expression
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   203
8872
b638a99ab9cf [predicates] keep making `yes` predicate importable from cubicweb (closes #2790319)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8866
diff changeset
   204
# remember, these imports are there for bw compat only
b638a99ab9cf [predicates] keep making `yes` predicate importable from cubicweb (closes #2790319)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8866
diff changeset
   205
__BACKWARD_COMPAT_IMPORTS = (yes,)
b638a99ab9cf [predicates] keep making `yes` predicate importable from cubicweb (closes #2790319)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8866
diff changeset
   206
1472
96e06e623494 fix implements selector to avoid returning false positive due to entity class inheritance
sylvain.thenault@logilab.fr
parents: 1301
diff changeset
   207
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   208
# 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
   209
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   210
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
   211
    """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
   212
    class to find missing information.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   213
782
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   214
    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
   215
    """
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
   216
    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
   217
        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
   218
        return super(PartialPredicateMixIn, self).__call__(cls, *args, **kwargs)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   219
1301
4596ce9bb4dc EntitySelector base class now understand 'entity' in kwargs, new entity_implements selector
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   220
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   221
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
   222
    """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
   223
    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
   224
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   225
    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
   226
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   227
    * 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
   228
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
   229
    * 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
   230
      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
   231
      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
   232
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` 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
   234
      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
   235
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
   236
    * 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
   237
      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
   238
      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
   239
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
   240
    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
   241
    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
   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` == '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
   244
        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
   245
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
   246
      - `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
   247
        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
   248
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   249
      - `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
   250
        (this may occurs with outer join)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   251
    """
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
   252
    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
   253
        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
   254
            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
   255
                 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
   256
            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
   257
                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
   258
        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
   259
        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
   260
        self.accept_none = accept_none
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   261
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
   262
    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
   263
                 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
   264
                 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
   265
                 **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
   266
        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
   267
            return self.score_class(entity.__class__, req)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   268
        if not rset:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   269
            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
   270
        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
   271
            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
   272
        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
   273
            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
   274
                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
   275
            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
   276
                   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
   277
                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
   278
            etypes = rset.column_types(col)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   279
        else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   280
            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
   281
            # 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
   282
            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
   283
                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
   284
            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
   285
        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
   286
        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
   287
            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
   288
            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
   289
                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
   290
            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
   291
                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
   292
            score += escore
779
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   293
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   294
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   295
    def score(self, cls, req, etype):
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   296
        if etype in BASE_TYPES:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   297
            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
   298
        return self.score_class(req.vreg['etypes'].etype_class(etype), req)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   299
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   300
    def score_class(self, eclass, req):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   301
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   302
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   303
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   304
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
   305
    """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
   306
    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
   307
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   308
    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
   309
c57c8176b8c2 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
    * 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
   311
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
   312
    * 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
   313
      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
   314
c57c8176b8c2 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
    * 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
   316
      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
   317
      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
   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` == '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
   320
        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
   321
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
   322
      - `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
   323
        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
   324
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   325
      - `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
   326
        (this may occurs with outer join)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   327
5147
70181998897f more / cleaner / in code documentation of vreg, selectors and appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5143
diff changeset
   328
    .. Note::
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   329
       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
   330
       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
   331
       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
   332
       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
   333
       which may be much more costly.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   334
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   335
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
   336
    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
   337
                 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
   338
        if not rset and entity is None:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   339
            return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   340
        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
   341
        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
   342
            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
   343
        elif row is None:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   344
            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
   345
            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
   346
                accept_none = self.accept_none
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   347
            for row, rowvalue in enumerate(rset.rows):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   348
                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
   349
                    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
   350
                        return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   351
                    continue
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 650
diff changeset
   352
                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
   353
                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
   354
                    return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   355
                elif self.once_is_enough:
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   356
                    return escore
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   357
                score += escore
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   358
        else:
1994
56a235af050e col may be None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1987
diff changeset
   359
            col = col or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   360
            etype = rset.description[row][col]
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   361
            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
   362
                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
   363
        return score
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   364
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   365
    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
   366
        try:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   367
            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
   368
        except NotAnEntity:
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 634
diff changeset
   369
            return 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   370
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   371
    def score_entity(self, entity):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   372
        raise NotImplementedError()
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   373
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   374
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   375
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
   376
    """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
   377
    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
   378
    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
   379
    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
   380
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
    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
   382
    :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
   383
    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
   384
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
   385
    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
   386
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
    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
   388
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
   389
    - 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
   390
      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
   391
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
    - 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
   393
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
   394
    - 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
   395
8032
bcb87336c7d2 [doc] fix most of ReST compilation errors and warnings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   396
    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
   397
    """
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
   398
    def __init__(self, *expected, **kwargs):
774
48cb1f42e79c tell on which class the assertion's failed
sylvain.thenault@logilab.fr
parents: 770
diff changeset
   399
        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
   400
        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
   401
            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
   402
        else:
c6eb201d4410 [selectors] abstract ExpectedValueSelector now accept a set as single argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6919
diff changeset
   403
            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
   404
        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
   405
        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
   406
        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
   407
        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
   408
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   409
    def __str__(self):
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   410
        return '%s(%s)' % (self.__class__.__name__,
8510e14335e1 implements some str, fix implements selector, test and fixes
sylvain.thenault@logilab.fr
parents: 774
diff changeset
   411
                           ','.join(sorted(str(s) for s in self.expected)))
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   412
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
   413
    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
   414
        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
   415
        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
   416
        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
   417
            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
   418
        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
   419
            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
   420
        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
   421
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
   422
    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
   423
        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
   424
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
   425
    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
   426
        raise NotImplementedError()
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   427
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   428
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   429
# bare predicates ##############################################################
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   430
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   431
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
   432
    """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
   433
    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
   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
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
    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
   437
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
   438
    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
   439
    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
   440
    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
   441
    """
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   442
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
   443
    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
   444
        return frozenset(kwargs)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   445
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   446
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   447
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
   448
    """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
   449
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
   450
    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
   451
4462
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   452
    * `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
   453
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   454
    * `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
   455
      selectable.
1263
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1178
diff changeset
   456
    """
5561
58b05c314443 [selectors] ensure adaptable('IDownloadable') takes precedence over implements('Any')
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5557
diff changeset
   457
    selectable_score = 1
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   458
    def __init__(self, registry, *regids):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   459
        self.registry = registry
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   460
        self.regids = regids
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   461
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
   462
    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
   463
        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
   464
            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
   465
                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
   466
        return 0
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   467
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
class adaptable(appobject_selectable):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   470
    """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
   471
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   472
    Initializer arguments:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   473
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   474
    * `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
   475
      (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
   476
      when multiple identifiers are given.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   477
    """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   478
    def __init__(self, *regids):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   479
        super(adaptable, self).__init__('adapters', *regids)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   480
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
   481
    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
   482
        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
   483
        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
   484
        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
   485
            # 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
   486
            # 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
   487
            # 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
   488
            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
   489
                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
   490
                _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
   491
                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
   492
                    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
   493
                # 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
   494
                # 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
   495
                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
   496
        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
   497
            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
   498
        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
   499
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
    @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
   501
    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
   502
        # 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
   503
        # 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
   504
        # 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
   505
        # * 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
   506
        # * 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
   507
        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
   508
            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
   509
        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
   510
            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
   511
        return score
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   512
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
   513
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   514
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
   515
    """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
   516
    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
   517
    """
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   518
    # 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
   519
    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
   520
        self._key = key
6402
a589df8b9b66 [selector] fix iterable detection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6397
diff changeset
   521
        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
   522
            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
   523
        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
   524
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
    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
   526
        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
   527
            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
   528
        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
   529
            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
   530
                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
   531
            else:
980f4415baab [selectors] make configuration_values selector works for startup/maintainance hook
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6402
diff changeset
   532
                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
   533
            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
   534
        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
   535
6402
a589df8b9b66 [selector] fix iterable detection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6397
diff changeset
   536
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   537
# 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
   538
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   539
@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
   540
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
   541
    """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
   542
    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
   543
        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
   544
    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
   545
c57c8176b8c2 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
c57c8176b8c2 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
# 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
   548
@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
   549
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
   550
    """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
   551
    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
   552
        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
   553
    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
   554
c57c8176b8c2 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
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   556
@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
   557
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
   558
    """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
   559
    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
   560
        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
   561
    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
   562
c57c8176b8c2 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
c57c8176b8c2 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
# 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
   565
@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
   566
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
   567
    """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
   568
    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
   569
        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
   570
    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
   571
c57c8176b8c2 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
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   573
# 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
   574
@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
   575
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
   576
    """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
   577
      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
   578
    """
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
   579
    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
   580
        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
   581
    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
   582
        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
   583
    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
   584
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   585
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   586
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
   587
    """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
   588
    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
   589
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   590
    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
   591
        `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
   592
    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
   593
        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
   594
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   595
    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
   596
    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
   597
    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
   598
    """
6348
f5bd501628b0 [selectors] multi_lines_rset selector supports now optional operator for richer comparaisons
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6120
diff changeset
   599
    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
   600
        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
   601
        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
   602
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   603
    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
   604
        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
   605
            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
   606
        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
   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
    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
   609
        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
   610
c57c8176b8c2 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
c57c8176b8c2 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
class multi_columns_rset(multi_lines_rset):
5452
4ac3ea9face9 [doc] typos
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   613
    """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
   614
    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
   615
    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
   616
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   617
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   618
    def __call__(self, cls, req, rset=None, **kwargs):
8397
42ec34b3ced9 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8190
diff changeset
   619
        # '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
   620
        # 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
   621
        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
   622
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   623
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   624
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
   625
    """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
   626
    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
   627
    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
   628
    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
   629
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   630
    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
   631
    * 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
   632
    * 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
   633
    * 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
   634
    """
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
   635
    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
   636
        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
   637
        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
   638
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
    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
   640
        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
   641
            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
   642
        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
   643
        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
   644
            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
   645
            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
   646
                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
   647
            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
   648
                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
   649
        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
   650
            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
   651
        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
   652
c57c8176b8c2 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
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   654
@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
   655
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
   656
    """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
   657
    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
   658
    '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
   659
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   660
    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
   661
        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
   662
    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
   663
    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
   664
        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
   665
        (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
   666
         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
   667
        ):
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
   668
        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
   669
    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
   670
c57c8176b8c2 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
c57c8176b8c2 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
# 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
   673
@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
   674
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
   675
    """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
   676
    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
   677
    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
   678
    """
c57c8176b8c2 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
    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
   680
        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
   681
    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
   682
        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
   683
    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
   684
c57c8176b8c2 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
c57c8176b8c2 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
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
   687
    """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
   688
    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
   689
    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
   690
    *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
   691
    """
c57c8176b8c2 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
c57c8176b8c2 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
    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
   694
        # '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
   695
        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
   696
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   697
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   698
@objectify_predicate
5502
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   699
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
   700
    """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
   701
    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
   702
    """
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   703
    if rset is None:
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   704
        return 0
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   705
    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
   706
c342531032a1 [selectors] new logged_user_in_rset selector
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5490
diff changeset
   707
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   708
# 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
   709
9547
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   710
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
   711
    """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
   712
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   713
    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
   714
    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
   715
    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
   716
    """
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   717
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   718
    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
   719
        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
   720
        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
   721
            return 0
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   722
        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
   723
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   724
43aace16a953 [schema] add composite handling helpers on EntitySchema (related to #3463112)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9344
diff changeset
   725
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   726
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
   727
    """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
   728
    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
   729
    `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
   730
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   731
    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
   732
    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
   733
    """
c57c8176b8c2 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
    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
   735
        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
   736
            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
   737
        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
   738
4664
bd5ecd5b9494 #714109: [selectors] non_final_entity should implement score_class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4545
diff changeset
   739
    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
   740
        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
   741
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   742
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
   743
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
   744
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
   745
    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
   746
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
   747
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
   748
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   749
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
   750
    """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
   751
    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
   752
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
   753
    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
   754
    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
   755
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   756
    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
   757
    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
   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
    .. 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
   760
              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
   761
    """
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
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
    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
   764
        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
   765
        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
   766
        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
   767
            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
   768
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
    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
   770
        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
   771
                           ','.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
   772
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
   773
    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
   774
        # 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
   775
        try:
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
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
   777
        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
   778
            # 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
   779
            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
   780
        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
   781
            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
   782
        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
   783
            # 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
   784
            #  (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
   785
            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
   786
            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
   787
            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
   788
                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
   789
                    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
   790
                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
   791
                    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
   792
        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
   793
        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
   794
        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
   795
            # 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
   796
            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
   797
                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
   798
            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
   799
                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
   800
            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
   801
                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
   802
                    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
   803
                        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
   804
                        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
   805
        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
   806
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   807
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   808
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
   809
    """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
   810
    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
   811
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   812
    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
   813
    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
   814
6869
900cb9b1b687 [tests] new unit tests about score_entity selector (inscore machinery)
Julien Jehannet <julien@smaf.org>
parents: 6615
diff changeset
   815
    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
   816
    value at the end.
900cb9b1b687 [tests] new unit tests about score_entity selector (inscore machinery)
Julien Jehannet <julien@smaf.org>
parents: 6615
diff changeset
   817
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   818
    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
   819
    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
   820
    """
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
   821
    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
   822
        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
   823
        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
   824
            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
   825
            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
   826
                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
   827
            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
   828
                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
   829
            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
   830
        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
   831
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   832
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   833
class has_mimetype(EntityPredicate):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   834
    """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
   835
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   836
    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
   837
    only PNG images.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   838
    """
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
   839
    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
   840
        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
   841
        self.mimetype = mimetype
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   842
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   843
    def score_entity(self, entity):
5858
384d34e76d6d cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5736
diff changeset
   844
        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
   845
        if idownloadable is None:
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
        mt = idownloadable.download_content_type()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   848
        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
   849
            return 0
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   850
        return 1
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   851
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5508
diff changeset
   852
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   853
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
   854
    """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
   855
    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
   856
c57c8176b8c2 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
    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
   858
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
   859
    * `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
   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
    * `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
   862
      '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
   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
    * `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
   865
      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
   866
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   867
    * `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
   868
      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
   869
      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
   870
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
   871
    * `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
   872
      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
   873
      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
   874
c57c8176b8c2 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
      - 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
   876
        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
   877
        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
   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
      - 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
   880
        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
   881
c57c8176b8c2 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
    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
   883
    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
   884
    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
   885
    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
   886
    according to the input context.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   887
    """
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   888
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   889
    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
   890
                 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
   891
        super(relation_possible, self).__init__(**kwargs)
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   892
        self.rtype = rtype
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   893
        self.role = role
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   894
        self.target_etype = target_etype
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   895
        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
   896
        self.strict = strict
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   897
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
    # 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
   899
    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
   900
        # 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
   901
        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
   902
            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
   903
        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
   904
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   905
    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
   906
        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
   907
            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
   908
        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
   909
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   910
    def _get_rschema(self, eclass):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   911
        eschema = eclass.e_schema
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   912
        try:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   913
            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
   914
                return eschema.objrels[self.rtype]
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   915
            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
   916
                return eschema.subjrels[self.rtype]
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   917
        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
   918
            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
   919
c57c8176b8c2 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
    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
   921
        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
   922
        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
   923
            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
   924
        eschema = eclass.e_schema
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   925
        if self.target_etype is not None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   926
            try:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   927
                rdef = rschema.role_rdef(eschema, self.target_etype, self.role)
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1037
diff changeset
   928
            except KeyError:
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   929
                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
   930
            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
   931
                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
   932
            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
   933
            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
   934
                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
   935
        elif self.action:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3757
diff changeset
   936
            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
   937
        return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   938
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
   939
    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
   940
        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
   941
        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
   942
            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
   943
        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
   944
            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
   945
                try:
b0155bfd4e17 Protect against crash in the `relation_possible` predicate with ambiguous relations.
Florent Cayre <florent.cayre@logilab.fr>
parents: 8872
diff changeset
   946
                    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
   947
                                                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
   948
                except KeyError:
b0155bfd4e17 Protect against crash in the `relation_possible` predicate with ambiguous relations.
Florent Cayre <florent.cayre@logilab.fr>
parents: 8872
diff changeset
   949
                    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
   950
            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
   951
                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
   952
                    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
   953
            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
   954
                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
   955
        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
   956
            req = entity._cw
aa01eb033620 [selectors] fix dumb name error introduced in parent changeset
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5900
diff changeset
   957
            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
   958
            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
   959
                return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   960
        return 1
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   961
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
   962
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   963
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
   964
    """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
   965
    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
   966
    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
   967
    as initializer arguments.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   968
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   969
    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
   970
    customized.
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   971
    """
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
   972
    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
   973
        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
   974
                                                        action, **kwargs)
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   975
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
   976
    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
   977
        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
   978
        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
   979
        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
   980
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   981
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   982
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
   983
    """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
   984
    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
   985
    target type.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
   986
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
   987
    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
   988
c57c8176b8c2 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
    * `rtype`, the name of the relation
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
   990
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
   991
    * `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
   992
      '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
   993
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
   994
    * `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
   995
      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
   996
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
   997
    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
   998
    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
   999
    """
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
  1000
    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
  1001
        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
  1002
        self.rtype = rtype
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1003
        self.role = role
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1004
        self.target_etype = target_etype
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1005
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1006
    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
  1007
        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
  1008
        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
  1009
            return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1010
        rset = entity.related(self.rtype, self.role)
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1011
        if self.target_etype:
1011
22812cfe36b4 fix w/ rset with more than one column
sylvain.thenault@logilab.fr
parents: 876
diff changeset
  1012
            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
  1013
        return rset and 1 or 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1014
833
8c6bfd9158fb bw compat for selection for creation forms
sylvain.thenault@logilab.fr
parents: 828
diff changeset
  1015
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1016
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
  1017
    """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
  1018
    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
  1019
    expected by the initializer.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1020
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1021
    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
  1022
    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
  1023
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1024
    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
  1025
        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
  1026
                                                           **kwargs)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1027
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 835
diff changeset
  1028
    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
  1029
        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
  1030
        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
  1031
        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
  1032
01801a10c567 introduce abstract selectors to get rid of the my_selector() contagion
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 774
diff changeset
  1033
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1034
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
  1035
    """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
  1036
    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
  1037
    of 'read', 'add', 'delete', 'update').
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1038
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
  1039
    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
  1040
c57c8176b8c2 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
    * 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
  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
    * 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
  1044
      in the specified cell
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
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
    * 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
  1047
      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
  1048
    """
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
  1049
    def __init__(self, action):
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1050
        self.action = action
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1051
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1052
    # 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
  1053
    # 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
  1054
    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
  1055
        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
  1056
            return self.score_entity(entity)
788
d62fb3e9797d protect against None rset
sylvain.thenault@logilab.fr
parents: 784
diff changeset
  1057
        if rset is None:
d62fb3e9797d protect against None rset
sylvain.thenault@logilab.fr
parents: 784
diff changeset
  1058
            return 0
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1059
        if row is None:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1060
            score = 0
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1061
            need_local_check = []
2816
85f7502d32be access schema through req.vreg
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2797
diff changeset
  1062
            geteschema = req.vreg.schema.eschema
6360
1edfc0f3bb1d [selector] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6348
diff changeset
  1063
            user = req.user
1edfc0f3bb1d [selector] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6348
diff changeset
  1064
            action = self.action
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1065
            for etype in rset.column_types(0):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1066
                if etype in BASE_TYPES:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1067
                    return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1068
                eschema = geteschema(etype)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1069
                if not user.matching_groups(eschema.get_groups(action)):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1070
                    if eschema.has_local_role(action):
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1071
                        # have to ckeck local roles
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1072
                        need_local_check.append(eschema)
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1073
                        continue
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1074
                    else:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1075
                        # even a local role won't be enough
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1076
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1077
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1078
            if need_local_check:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1079
                # check local role for entities of necessary types
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1080
                for i, row in enumerate(rset):
6360
1edfc0f3bb1d [selector] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6348
diff changeset
  1081
                    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
  1082
                        continue
6364
ad9ed9803eb6 cleanup and micro-optimization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6360
diff changeset
  1083
                    # micro-optimisation instead of calling self.score(req,
ad9ed9803eb6 cleanup and micro-optimization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6360
diff changeset
  1084
                    # rset, i, col): rset may be large
ad9ed9803eb6 cleanup and micro-optimization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6360
diff changeset
  1085
                    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
  1086
                        return 0
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1087
                score += 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1088
            return score
876
f652660ae9a6 use relation_possible from within has_relation, fix another bug
sylvain.thenault@logilab.fr
parents: 839
diff changeset
  1089
        return self.score(req, rset, row, col)
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1090
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1091
    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
  1092
        if entity.cw_has_perm(self.action):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1093
            return 1
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1094
        return 0
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1095
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1096
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1097
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
  1098
    """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
  1099
    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
  1100
    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
  1101
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
  1102
    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
  1103
    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
  1104
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1105
    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
  1106
    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
  1107
    not specified.
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1108
    """
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
  1109
    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
  1110
        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
  1111
        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
  1112
c57c8176b8c2 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
    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
  1114
        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
  1115
            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
  1116
        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
  1117
c57c8176b8c2 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
    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
  1119
        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
  1120
        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
  1121
               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
  1122
            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
  1123
        return 1
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1124
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1125
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1126
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
  1127
    """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
  1128
    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
  1129
    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
  1130
    condition.
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1131
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
  1132
    `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
  1133
    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
  1134
    represent the request's user.
650
75b4c661f71b proper documentation, some bug fixes, upgrade some selectors
sylvain.thenault@logilab.fr
parents: 649
diff changeset
  1135
6871
b746dae3a004 [docstring] minor: add warning about entity cache for rql_condition selector
Julien Jehannet <julien@smaf.org>
parents: 6870
diff changeset
  1136
    .. warning::
b746dae3a004 [docstring] minor: add warning about entity cache for rql_condition selector
Julien Jehannet <julien@smaf.org>
parents: 6870
diff changeset
  1137
        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
  1138
        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
  1139
        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
  1140
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1141
    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
  1142
    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
  1143
    """
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
  1144
    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
  1145
        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
  1146
        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
  1147
        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
  1148
            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
  1149
        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
  1150
            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
  1151
        else:
6457
3234d8d6e264 [selector] more efficient rql_condition by simply retreiving COUNT()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6445
diff changeset
  1152
            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
  1153
        self.rql = rql
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1154
6870
658039c5eeac [selectors] minor: use similar __repr__ implementation for selector instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6869
diff changeset
  1155
    def __str__(self):
658039c5eeac [selectors] minor: use similar __repr__ implementation for selector instances
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6869
diff changeset
  1156
        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
  1157
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
  1158
    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
  1159
        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
  1160
            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
  1161
                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
  1162
            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
  1163
                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
  1164
        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
  1165
            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
  1166
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
  1167
    def _score(self, req, eid):
634
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1168
        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
  1169
            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
  1170
        except Unauthorized:
0badd061ce0f move cubicweb.common.selectors to cubicweb.selectors
sylvain.thenault@logilab.fr
parents:
diff changeset
  1171
            return 0
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
  1172
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
  1173
    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
  1174
        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
  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
    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
  1177
        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
  1178
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
  1179
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1180
# 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
  1181
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1182
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
  1183
    """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
  1184
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1185
    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
  1186
    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
  1187
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1188
    * 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
  1189
    * 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
  1190
      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
  1191
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1192
    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
  1193
    (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
  1194
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1195
    :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
  1196
    """
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1197
    def __init__(self, *expected):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1198
        assert expected, self
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1199
        self.expected = frozenset(expected)
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1200
        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
  1201
            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
  1202
            # 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
  1203
            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
  1204
                # 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
  1205
                # 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
  1206
                # 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
  1207
                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
  1208
                    self._validate(adapted)
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1209
            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
  1210
        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
  1211
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1212
    def _score(self, adapted):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1213
        trinfo = adapted.latest_trinfo()
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1214
        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
  1215
            statename = adapted.state
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1216
        else:
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1217
            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
  1218
        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
  1219
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1220
    def _validate(self, adapted):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1221
        wf = adapted.current_workflow
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1222
        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
  1223
        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
  1224
        if unknown:
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1225
            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
  1226
                             % (wf.name, ",".join(unknown)))
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1227
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1228
    def __str__(self):
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1229
        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
  1230
                           ','.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
  1231
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1232
9344
4da3ef764395 [predicates] allow multiple transition names in on_fire_transition (closes #3013720)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9256
diff changeset
  1233
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
  1234
    """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
  1235
    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
  1236
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1237
    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
  1238
    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
  1239
    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
  1240
    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
  1241
    but also its original state, transition, destination state, user...).
7559
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7529
diff changeset
  1242
7529
2fdc310be7cd [book] add autoload section from code and fix sphinx warnings
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 7452
diff changeset
  1243
    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
  1244
    """
9344
4da3ef764395 [predicates] allow multiple transition names in on_fire_transition (closes #3013720)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9256
diff changeset
  1245
    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
  1246
        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
  1247
    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
  1248
        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
  1249
    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
  1250
        # 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
  1251
        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
  1252
                # 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
  1253
                # 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
  1254
                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
  1255
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
  1256
    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
  1257
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1258
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1259
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
  1260
    """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
  1261
    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
  1262
    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
  1263
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1264
    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
  1265
    the web ui.
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1266
    """
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
  1267
    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
  1268
        # 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
  1269
        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
  1270
            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
  1271
            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
  1272
                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
  1273
        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
  1274
            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
  1275
        return 0
6919
8fd6921f3e7c [selectors] modify workflow selectors: is_in_state, on_transition
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6908
diff changeset
  1276
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
  1277
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1278
# 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
  1279
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1280
@objectify_predicate
5490
b7b96b8decf1 [selectors] fix no_cnx selector's prototype
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
  1281
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
  1282
    """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
  1283
    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
  1284
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
    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
  1286
    """
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
  1287
    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
  1288
        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
  1289
    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
  1290
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1291
@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
  1292
def authenticated_user(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
  1293
    """Return 1 if the user is authenticated (e.g. not the anonymous 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
  1294
c57c8176b8c2 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
    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
  1296
    """
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
  1297
    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
  1298
        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
  1299
    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
  1300
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1301
c57c8176b8c2 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
# 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
  1303
def anonymous_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
  1304
    """Return 1 if the user is not authenticated (e.g. is the anonymous 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
  1305
c57c8176b8c2 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
    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
  1307
    """
c57c8176b8c2 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 ~ 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
  1309
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1310
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
  1311
    """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
  1312
    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
  1313
    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
  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 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
  1316
    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
  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
    * 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
  1319
      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
  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
    * 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
  1322
    """
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1323
c57c8176b8c2 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
    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
  1325
        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
  1326
            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
  1327
        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
  1328
        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
  1329
            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
  1330
        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
  1331
        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
  1332
            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
  1333
                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
  1334
                    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
  1335
                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
  1336
            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
  1337
                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
  1338
        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
  1339
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1340
# 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
  1341
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6140
diff changeset
  1342
# 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
  1343
@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
  1344
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
  1345
    """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
  1346
c57c8176b8c2 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
    * *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
  1348
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1349
    * 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
  1350
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1351
    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
  1352
    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
  1353
    """
c57c8176b8c2 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
    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
  1355
        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
  1356
    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
  1357
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1358
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1359
@objectify_predicate
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1360
def contextual(cls, req, view=None, **kwargs):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1361
    """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
  1362
    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
  1363
        return 1
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1364
    return 0
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1365
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1366
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1367
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
  1368
    """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
  1369
    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
  1370
    """
c57c8176b8c2 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
    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
  1372
        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
  1373
            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
  1374
        return 1
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1375
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
  1376
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1377
class match_context(ExpectedValuePredicate):
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1378
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1379
    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
  1380
        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
  1381
            return 0
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1382
        return 1
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1383
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6120
diff changeset
  1384
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6140
diff changeset
  1385
# 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
  1386
@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
  1387
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
  1388
    """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
  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
    * 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
  1391
      `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
  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
    * 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
  1394
      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
  1395
c57c8176b8c2 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
    * 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
  1397
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1398
    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
  1399
    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
  1400
    """
c57c8176b8c2 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
    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
  1402
        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
  1403
    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
  1404
                                                    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
  1405
    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
  1406
        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
  1407
    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
  1408
1474
716f0742ee7f delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1472
diff changeset
  1409
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1410
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
  1411
    """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
  1412
    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
  1413
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1414
    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
  1415
    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
  1416
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1417
    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
  1418
    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
  1419
    """
649
e5956e9ebef1 more doc, upgrade but_etype and appobject_selectable selectors
sylvain.thenault@logilab.fr
parents: 640
diff changeset
  1420
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
  1421
    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
  1422
        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
  1423
            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
  1424
                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
  1425
        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
  1426
            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
  1427
        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
  1428
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1429
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1430
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
  1431
    """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
  1432
    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
  1433
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
    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
  1435
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
  1436
    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
  1437
    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
  1438
    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
  1439
    """
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
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
  1441
    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
  1442
        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
  1443
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1444
8751
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1445
class match_http_method(ExpectedValuePredicate):
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1446
    """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
  1447
    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
  1448
    """
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
    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
  1451
        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
  1452
1a97d46701e7 add the match_http_method predicate (closes #2559932)
David Douard <david.douard@logilab.fr>
parents: 8535
diff changeset
  1453
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1454
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
  1455
    """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
  1456
    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
  1457
    """
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1458
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1459
    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
  1460
        try:
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1461
            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
  1462
        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
  1463
            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
  1464
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1465
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1466
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
  1467
    """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
  1468
    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
  1469
    """
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1470
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1471
    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
  1472
        try:
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1473
            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
  1474
        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
  1475
            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
  1476
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 8032
diff changeset
  1477
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
  1478
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
  1479
    """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
  1480
    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
  1481
    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
  1482
    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
  1483
    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
  1484
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1485
    .. 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
  1486
              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
  1487
              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
  1488
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1489
    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
  1490
    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
  1491
    """
c57c8176b8c2 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
c57c8176b8c2 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
    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
  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 = 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
  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
            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
  1498
                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
  1499
            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
  1500
                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
  1501
            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
  1502
                # 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
  1503
                # 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
  1504
                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
  1505
                    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
  1506
                    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
  1507
                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
  1508
                    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
  1509
        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
  1510
        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
  1511
            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
  1512
            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
  1513
                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
  1514
        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
  1515
c57c8176b8c2 reorganize, cleanup and properly document base selectors. Kill the may_add_relation selector.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4458
diff changeset
  1516
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1517
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
  1518
    """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
  1519
    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
  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
    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
  1522
    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
  1523
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1524
     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
  1525
                               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
  1526
    """
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
  1527
    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
  1528
        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
  1529
        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
  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
    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
  1532
        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
  1533
30582ba8b368 [selectors] move selectors according to their type, add missing ones to documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6389
diff changeset
  1534
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1535
# 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
  1536
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1537
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
  1538
    """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
  1539
    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
  1540
    """
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
    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
  1542
        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
  1543
        # 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
  1544
        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
  1545
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
    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
  1547
        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
  1548
            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
  1549
        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
  1550
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
  1551
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
  1552
@objectify_predicate
5480
2d5c46e78ae9 [css] introducing scale and rhythm composition
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5452
diff changeset
  1553
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
  1554
    """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
  1555
    return req.vreg.config.debugmode and 1 or 0