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