25 from operator import eq |
25 from operator import eq |
26 |
26 |
27 from six import string_types, integer_types |
27 from six import string_types, integer_types |
28 from six.moves import range |
28 from six.moves import range |
29 |
29 |
30 from logilab.common.deprecation import deprecated |
30 from logilab.common.registry import Predicate, objectify_predicate |
31 from logilab.common.registry import Predicate, objectify_predicate, yes |
|
32 |
31 |
33 from yams.schema import BASE_TYPES, role_name |
32 from yams.schema import BASE_TYPES, role_name |
34 from rql.nodes import Function |
33 from rql.nodes import Function |
35 |
34 |
36 from cubicweb import (Unauthorized, NoSelectableObject, NotAnEntity, |
35 from cubicweb import (Unauthorized, NoSelectableObject, NotAnEntity, |
37 CW_EVENT_MANAGER, role) |
36 CW_EVENT_MANAGER, role) |
38 from cubicweb.uilib import eid_param |
37 from cubicweb.uilib import eid_param |
39 from cubicweb.schema import split_expression |
38 from cubicweb.schema import split_expression |
40 |
39 |
41 yes = deprecated('[3.15] import yes() from use logilab.common.registry')(yes) |
|
42 |
|
43 |
40 |
44 # abstract predicates / mixin helpers ########################################### |
41 # abstract predicates / mixin helpers ########################################### |
45 |
42 |
46 class PartialPredicateMixIn(object): |
43 class PartialPredicateMixIn(object): |
47 """convenience mix-in for predicates that will look into the containing |
44 """convenience mix-in for predicates that will look into the containing |
83 returned |
80 returned |
84 |
81 |
85 - `accept_none` is False and some cell in the column has a None value |
82 - `accept_none` is False and some cell in the column has a None value |
86 (this may occurs with outer join) |
83 (this may occurs with outer join) |
87 """ |
84 """ |
88 def __init__(self, once_is_enough=None, accept_none=True, mode='all'): |
85 def __init__(self, accept_none=True, mode='all'): |
89 if once_is_enough is not None: |
|
90 warn("[3.14] once_is_enough is deprecated, use mode='any'", |
|
91 DeprecationWarning, stacklevel=2) |
|
92 if once_is_enough: |
|
93 mode = 'any' |
|
94 assert mode in ('any', 'all'), 'bad mode %s' % mode |
86 assert mode in ('any', 'all'), 'bad mode %s' % mode |
95 self.once_is_enough = mode == 'any' |
87 self.once_is_enough = mode == 'any' |
96 self.accept_none = accept_none |
88 self.accept_none = accept_none |
97 |
89 |
98 def __call__(self, cls, req, rset=None, row=None, col=0, entity=None, |
90 def __call__(self, cls, req, rset=None, row=None, col=0, entity=None, |
670 value at the end. |
662 value at the end. |
671 |
663 |
672 See :class:`~cubicweb.predicates.EntityPredicate` documentation for entity |
664 See :class:`~cubicweb.predicates.EntityPredicate` documentation for entity |
673 lookup / score rules according to the input context. |
665 lookup / score rules according to the input context. |
674 """ |
666 """ |
675 def __init__(self, scorefunc, once_is_enough=None, mode='all'): |
667 def __init__(self, scorefunc, mode='all'): |
676 super(score_entity, self).__init__(mode=mode, once_is_enough=once_is_enough) |
668 super(score_entity, self).__init__(mode=mode) |
677 def intscore(*args, **kwargs): |
669 def intscore(*args, **kwargs): |
678 score = scorefunc(*args, **kwargs) |
670 score = scorefunc(*args, **kwargs) |
679 if not score: |
671 if not score: |
680 return 0 |
672 return 0 |
681 if isinstance(score, integer_types): |
673 if isinstance(score, integer_types): |
688 """Return 1 if the entity adapt to IDownloadable and has the given MIME type. |
680 """Return 1 if the entity adapt to IDownloadable and has the given MIME type. |
689 |
681 |
690 You can give 'image/' to match any image for instance, or 'image/png' to match |
682 You can give 'image/' to match any image for instance, or 'image/png' to match |
691 only PNG images. |
683 only PNG images. |
692 """ |
684 """ |
693 def __init__(self, mimetype, once_is_enough=None, mode='all'): |
685 def __init__(self, mimetype, mode='all'): |
694 super(has_mimetype, self).__init__(mode=mode, once_is_enough=once_is_enough) |
686 super(has_mimetype, self).__init__(mode=mode) |
695 self.mimetype = mimetype |
687 self.mimetype = mimetype |
696 |
688 |
697 def score_entity(self, entity): |
689 def score_entity(self, entity): |
698 idownloadable = entity.cw_adapt_to('IDownloadable') |
690 idownloadable = entity.cw_adapt_to('IDownloadable') |
699 if idownloadable is None: |
691 if idownloadable is None: |
993 benefit from the ORM's request entities cache. |
985 benefit from the ORM's request entities cache. |
994 |
986 |
995 See :class:`~cubicweb.predicates.EntityPredicate` documentation for entity |
987 See :class:`~cubicweb.predicates.EntityPredicate` documentation for entity |
996 lookup / score rules according to the input context. |
988 lookup / score rules according to the input context. |
997 """ |
989 """ |
998 def __init__(self, expression, once_is_enough=None, mode='all', user_condition=False): |
990 def __init__(self, expression, mode='all', user_condition=False): |
999 super(rql_condition, self).__init__(mode=mode, once_is_enough=once_is_enough) |
991 super(rql_condition, self).__init__(mode=mode) |
1000 self.user_condition = user_condition |
992 self.user_condition = user_condition |
1001 if user_condition: |
993 if user_condition: |
1002 rql = 'Any COUNT(U) WHERE U eid %%(u)s, %s' % expression |
994 rql = 'Any COUNT(U) WHERE U eid %%(u)s, %s' % expression |
1003 elif 'U' in frozenset(split_expression(expression)): |
995 elif 'U' in frozenset(split_expression(expression)): |
1004 rql = 'Any COUNT(X) WHERE X eid %%(x)s, U eid %%(u)s, %s' % expression |
996 rql = 'Any COUNT(X) WHERE X eid %%(x)s, U eid %%(u)s, %s' % expression |
1389 which will not score at edit time:: |
1381 which will not score at edit time:: |
1390 |
1382 |
1391 is_instance('Version') & (match_transition('ready') | |
1383 is_instance('Version') & (match_transition('ready') | |
1392 attribute_edited('publication_date')) |
1384 attribute_edited('publication_date')) |
1393 """ |
1385 """ |
1394 def __init__(self, attribute, once_is_enough=None, mode='all'): |
1386 def __init__(self, attribute, mode='all'): |
1395 super(attribute_edited, self).__init__(mode=mode, once_is_enough=once_is_enough) |
1387 super(attribute_edited, self).__init__(mode=mode) |
1396 self._attribute = attribute |
1388 self._attribute = attribute |
1397 |
1389 |
1398 def score_entity(self, entity): |
1390 def score_entity(self, entity): |
1399 return eid_param(role_name(self._attribute, 'subject'), entity.eid) in entity._cw.form |
1391 return eid_param(role_name(self._attribute, 'subject'), entity.eid) in entity._cw.form |
1400 |
1392 |