111 TRACED_OIDS = () |
111 TRACED_OIDS = () |
112 return traceback is None |
112 return traceback is None |
113 |
113 |
114 |
114 |
115 # abstract selectors ########################################################## |
115 # abstract selectors ########################################################## |
116 |
116 class PartialSelectorMixIn(object): |
117 class AbstractSelectorMixIn(object): |
117 """convenience mix-in for selectors that will look into the containing |
118 """convenience mix-in for selectors that depends on class attributes |
118 class to find missing information. |
|
119 |
119 cf. `cubicweb.web.action.LinkToEntityAction` for instance |
120 cf. `cubicweb.web.action.LinkToEntityAction` for instance |
120 """ |
121 """ |
121 def __call__(self, cls, *args, **kwargs): |
122 def __call__(self, cls, *args, **kwargs): |
122 self.concretize(cls) |
123 self.complete(cls) |
123 return super(AbstractSelectorMixIn, self).__call__(cls, *args, **kwargs) |
124 return super(PartialSelectorMixIn, self).__call__(cls, *args, **kwargs) |
124 |
|
125 |
125 |
126 class EClassSelector(Selector): |
126 class EClassSelector(Selector): |
127 """abstract class for selectors working on the entity classes of the result |
127 """abstract class for selectors working on the entity classes of the result |
128 set. Its __call__ method has the following behaviour: |
128 set. Its __call__ method has the following behaviour: |
129 |
129 |
618 return int(self.target_etype in rschema.subjects(eschema)) |
618 return int(self.target_etype in rschema.subjects(eschema)) |
619 except KeyError, ex: |
619 except KeyError, ex: |
620 return 0 |
620 return 0 |
621 return 1 |
621 return 1 |
622 |
622 |
623 |
623 class partial_relation_possible(PartialSelectorMixIn, relation_possible): |
624 class abstract_relation_possible(AbstractSelectorMixIn, relation_possible): |
624 """partial version of the relation_possible selector |
|
625 |
|
626 The selector will look for class attributes to find its missing |
|
627 information. The list of attributes required on the class |
|
628 for this selector are: |
|
629 |
|
630 - `rtype`: same as `rtype` parameter of the `relation_possible` selector |
|
631 |
|
632 - `role`: this attribute will be passed to the `cubicweb.role` function |
|
633 to determine the role of class in the relation |
|
634 |
|
635 - `etype` (optional): the entity type on the other side of the relation |
|
636 |
|
637 :param action: a relation schema action (one of 'read', 'add', 'delete') |
|
638 which must be granted to the logged user, else a 0 score will |
|
639 be returned |
|
640 """ |
625 def __init__(self, action='read', once_is_enough=False): |
641 def __init__(self, action='read', once_is_enough=False): |
626 super(abstract_relation_possible, self).__init__(None, None, None, |
642 super(partial_relation_possible, self).__init__(None, None, None, |
627 action, once_is_enough) |
643 action, once_is_enough) |
628 |
644 |
629 def concretize(self, cls): |
645 def complete(self, cls): |
630 self.rtype = cls.rtype |
646 self.rtype = cls.rtype |
631 self.role = role(cls) |
647 self.role = role(cls) |
632 self.target_etype = getattr(cls, 'etype', None) |
648 self.target_etype = getattr(cls, 'etype', None) |
633 |
649 |
634 |
650 |
675 return 0 |
691 return 0 |
676 elif not rschema.has_perm(entity.req, 'add', toeid=entity.eid): |
692 elif not rschema.has_perm(entity.req, 'add', toeid=entity.eid): |
677 return 0 |
693 return 0 |
678 return 1 |
694 return 1 |
679 |
695 |
680 class abstract_may_add_relation(AbstractSelectorMixIn, may_add_relation): |
696 class partial_may_add_relation(PartialSelectorMixIn, may_add_relation): |
|
697 """partial version of the may_add_relation selector |
|
698 |
|
699 The selector will look for class attributes to find its missing |
|
700 information. The list of attributes required on the class |
|
701 for this selector are: |
|
702 |
|
703 - `rtype`: same as `rtype` parameter of the `relation_possible` selector |
|
704 |
|
705 - `role`: this attribute will be passed to the `cubicweb.role` function |
|
706 to determine the role of class in the relation. |
|
707 |
|
708 :param action: a relation schema action (one of 'read', 'add', 'delete') |
|
709 which must be granted to the logged user, else a 0 score will |
|
710 be returned |
|
711 """ |
681 def __init__(self, once_is_enough=False): |
712 def __init__(self, once_is_enough=False): |
682 super(abstract_may_add_relation, self).__init__(None, None, once_is_enough) |
713 super(partial_may_add_relation, self).__init__(None, None, once_is_enough) |
683 |
714 |
684 def concretize(self, cls): |
715 def complete(self, cls): |
685 self.rtype = cls.rtype |
716 self.rtype = cls.rtype |
686 self.role = role(cls) |
717 self.role = role(cls) |
687 |
718 |
688 |
719 |
689 class has_related_entities(EntitySelector): |
720 class has_related_entities(EntitySelector): |
711 if self.target_etype: |
742 if self.target_etype: |
712 return any(x for x, in rset.description if x == self.target_etype) |
743 return any(x for x, in rset.description if x == self.target_etype) |
713 return rset and 1 or 0 |
744 return rset and 1 or 0 |
714 |
745 |
715 |
746 |
716 class abstract_has_related_entities(AbstractSelectorMixIn, has_related_entities): |
747 class partial_has_related_entities(PartialSelectorMixIn, has_related_entities): |
|
748 """partial version of the has_related_entities selector |
|
749 |
|
750 The selector will look for class attributes to find its missing |
|
751 information. The list of attributes required on the class |
|
752 for this selector are: |
|
753 |
|
754 - `rtype`: same as `rtype` parameter of the `relation_possible` selector |
|
755 |
|
756 - `role`: this attribute will be passed to the `cubicweb.role` function |
|
757 to determine the role of class in the relation. |
|
758 |
|
759 - `etype` (optional): the entity type on the other side of the relation |
|
760 |
|
761 :param action: a relation schema action (one of 'read', 'add', 'delete') |
|
762 which must be granted to the logged user, else a 0 score will |
|
763 be returned |
|
764 """ |
717 def __init__(self, once_is_enough=False): |
765 def __init__(self, once_is_enough=False): |
718 super(abstract_has_related_entities, self).__init__(None, None, |
766 super(partial_has_related_entities, self).__init__(None, None, |
719 None, once_is_enough) |
767 None, once_is_enough) |
720 def concretize(self, cls): |
768 def complete(self, cls): |
721 self.rtype = cls.rtype |
769 self.rtype = cls.rtype |
722 self.role = role(cls) |
770 self.role = role(cls) |
723 self.target_etype = getattr(cls, 'etype', None) |
771 self.target_etype = getattr(cls, 'etype', None) |
724 |
772 |
725 |
773 |