selectors.py
changeset 11057 0b59724cb3f2
parent 11052 058bb3dc685f
child 11058 23eb30449fe5
equal deleted inserted replaced
11052:058bb3dc685f 11057:0b59724cb3f2
     1 # copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     3 #
       
     4 # This file is part of CubicWeb.
       
     5 #
       
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
       
     7 # terms of the GNU Lesser General Public License as published by the Free
       
     8 # Software Foundation, either version 2.1 of the License, or (at your option)
       
     9 # any later version.
       
    10 #
       
    11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT
       
    12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
       
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
       
    14 # details.
       
    15 #
       
    16 # You should have received a copy of the GNU Lesser General Public License along
       
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
       
    18 
       
    19 from warnings import warn
       
    20 
       
    21 from six import string_types
       
    22 
       
    23 from logilab.common.deprecation import deprecated, class_renamed
       
    24 
       
    25 from cubicweb.predicates import *
       
    26 
       
    27 
       
    28 warn('[3.15] cubicweb.selectors renamed into cubicweb.predicates',
       
    29      DeprecationWarning, stacklevel=2)
       
    30 
       
    31 # XXX pre 3.15 bw compat
       
    32 from cubicweb.appobject import (objectify_selector, traced_selection,
       
    33                                 lltrace, yes)
       
    34 
       
    35 ExpectedValueSelector = class_renamed('ExpectedValueSelector',
       
    36                                       ExpectedValuePredicate)
       
    37 EClassSelector = class_renamed('EClassSelector', EClassPredicate)
       
    38 EntitySelector = class_renamed('EntitySelector', EntityPredicate)
       
    39 
       
    40 
       
    41 class on_transition(is_in_state):
       
    42     """Return 1 if entity is in one of the transitions given as argument list
       
    43 
       
    44     Especially useful to match passed transition to enable notifications when
       
    45     your workflow allows several transition to the same states.
       
    46 
       
    47     Note that if workflow `change_state` adapter method is used, this predicate
       
    48     will not be triggered.
       
    49 
       
    50     You should use this instead of your own :class:`score_entity` predicate to
       
    51     avoid some gotchas:
       
    52 
       
    53     * possible views gives a fake entity with no state
       
    54     * you must use the latest tr info thru the workflow adapter for repository
       
    55       side checking of the current state
       
    56 
       
    57     In debug mode, this predicate can raise:
       
    58     :raises: :exc:`ValueError` for unknown transition names
       
    59         (etype workflow only not checked in custom workflow)
       
    60 
       
    61     :rtype: int
       
    62     """
       
    63     @deprecated('[3.12] on_transition is deprecated, you should rather use '
       
    64                 'on_fire_transition(etype, trname)')
       
    65     def __init__(self, *expected):
       
    66         super(on_transition, self).__init__(*expected)
       
    67 
       
    68     def _score(self, adapted):
       
    69         trinfo = adapted.latest_trinfo()
       
    70         if trinfo and trinfo.by_transition:
       
    71             return trinfo.by_transition[0].name in self.expected
       
    72 
       
    73     def _validate(self, adapted):
       
    74         wf = adapted.current_workflow
       
    75         valid = [n.name for n in wf.reverse_transition_of]
       
    76         unknown = sorted(self.expected.difference(valid))
       
    77         if unknown:
       
    78             raise ValueError("%s: unknown transition(s): %s"
       
    79                              % (wf.name, ",".join(unknown)))
       
    80 
       
    81 
       
    82 entity_implements = class_renamed('entity_implements', is_instance)
       
    83 
       
    84 class _but_etype(EntityPredicate):
       
    85     """accept if the given entity types are not found in the result set.
       
    86 
       
    87     See `EntityPredicate` documentation for behaviour when row is not specified.
       
    88 
       
    89     :param *etypes: entity types (`string_types`) which should be refused
       
    90     """
       
    91     def __init__(self, *etypes):
       
    92         super(_but_etype, self).__init__()
       
    93         self.but_etypes = etypes
       
    94 
       
    95     def score(self, req, rset, row, col):
       
    96         if rset.description[row][col] in self.but_etypes:
       
    97             return 0
       
    98         return 1
       
    99 
       
   100 but_etype = class_renamed('but_etype', _but_etype, 'use ~is_instance(*etypes) instead')
       
   101 
       
   102 # XXX deprecated the one_* variants of predicates below w/ multi_xxx(nb=1)?
       
   103 #     take care at the implementation though (looking for the 'row' argument's
       
   104 #     value)
       
   105 two_lines_rset = class_renamed('two_lines_rset', multi_lines_rset)
       
   106 two_cols_rset = class_renamed('two_cols_rset', multi_columns_rset)
       
   107 two_etypes_rset = class_renamed('two_etypes_rset', multi_etypes_rset)