selectors.py
branchtls-sprint
changeset 838 f2c56312b03a
parent 835 7dcb11dd443e
child 839 3a76e0a2a0b0
equal deleted inserted replaced
836:2ca048a43240 838:f2c56312b03a
   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