# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1234961075 -3600 # Node ID 33db07c66789193811e79a3302a51031cb8b831d # Parent 45d816326626070221dffa986969e40b083c4f9b# Parent 01801a10c5670ff1b79588a0a6abdabe89219379 merge diff -r 45d816326626 -r 33db07c66789 selectors.py --- a/selectors.py Wed Feb 18 13:44:23 2009 +0100 +++ b/selectors.py Wed Feb 18 13:44:35 2009 +0100 @@ -113,6 +113,13 @@ # abstract selectors ########################################################## +class AbstractSelectorMixIn(object): + """convenience mix-in for selectors that depends on class attributes + cf. `cubicweb.web.action.LinkToEntityAction` for instance + """ + def __call__(self, cls, *args, **kwargs): + self.concretize(cls) + super(AbstractSelectorMixIn, self).__call__(cls, *args, **kwargs) class EClassSelector(Selector): """abstract class for selectors working on the entity classes of the result @@ -309,6 +316,8 @@ """accept result set where entities in the specified column (or 0) are all of the same type """ + if rset is None: + return 0 if len(rset.column_types(col)) != 1: return 0 return 1 @@ -612,6 +621,15 @@ return 0 return 1 +class abstract_relation_possible(AbstractSelectorMixIn, relation_possible): + def __init__(self, action='read', once_is_enough=False): + super(abstract_relation_possible, self).__init__(None, None, None, + action, once_is_enough) + + def concretize(self, cls): + self.rtype = cls.rtype + self.role = role(cls) + self.target_etype = getattr(cls, 'etype', None) class has_editable_relation(EntitySelector): """accept if some relations for an entity found in the result set is @@ -658,7 +676,15 @@ return 0 return 1 +class abstract_may_add_relation(AbstractSelectorMixIn, may_add_relation): + def __init__(self, once_is_enough=False): + super(abstract_may_add_relation, self).__init__(None, None, once_is_enough) + def concretize(self, cls): + self.rtype = cls.rtype + self.role = role(cls) + + class has_related_entities(EntitySelector): """accept if entity found in the result set has some linked entities using the specified relation (optionaly filtered according to the specified target @@ -685,7 +711,16 @@ return any(x for x, in rset.description if x == self.target_etype) return bool(rset) - +class abstract_has_related_entities(AbstractSelectorMixIn, has_related_entities): + def __init__(self, once_is_enough=False): + super(abstract_has_related_entities, self).__init__(None, None, + None, once_is_enough) + def concretize(self, cls): + self.rtype = cls.rtype + self.role = role(cls) + self.target_etype = getattr(cls, 'etype', None) + + class has_permission(EntitySelector): """accept if user has the permission to do the requested action on a result set entity. diff -r 45d816326626 -r 33db07c66789 web/action.py --- a/web/action.py Wed Feb 18 13:44:23 2009 +0100 +++ b/web/action.py Wed Feb 18 13:44:35 2009 +0100 @@ -6,10 +6,9 @@ """ __docformat__ = "restructuredtext en" -from cubicweb import role, target -from cubicweb.vregistry import objectify_selector -from cubicweb.selectors import (relation_possible, match_search_state, - one_line_rset, may_add_relation, yes, +from cubicweb import target +from cubicweb.selectors import (abstract_relation_possible, match_search_state, + one_line_rset, abstract_may_add_relation, yes, accepts_compat, condition_compat, deprecate) from cubicweb.appobject import AppRsetObject from cubicweb.common.registerers import accepts_registerer @@ -73,15 +72,9 @@ using .etype, .rtype and .target attributes to check if the action apply and if the logged user has access to it """ - @objectify_selector - def my_selector(cls, req, rset, row=None, col=0, **kwargs): - selector = (match_search_state('normal') & one_line_rset() - & relation_possible(cls.rtype, role(cls), cls.etype, - action='add') - & may_add_relation(cls.rtype, role(cls))) - return selector(cls, req, rset, row, col, **kwargs) - - __select__ = my_selector() + __select__ = (match_search_state('normal') & one_line_rset() + & abstract_relation_possible(action='add') + & abstract_may_add_relation()) registered = accepts_compat(Action.registered) category = 'addrelated' diff -r 45d816326626 -r 33db07c66789 web/box.py --- a/web/box.py Wed Feb 18 13:44:23 2009 +0100 +++ b/web/box.py Wed Feb 18 13:44:35 2009 +0100 @@ -10,9 +10,8 @@ from logilab.mtconverter import html_escape from cubicweb import Unauthorized, role as get_role -from cubicweb.vregistry import objectify_selector from cubicweb.selectors import (one_line_rset, primary_view, - match_context_prop, has_related_entities, + match_context_prop, abstract_has_related_entities, accepts_compat, has_relation_compat, condition_compat) from cubicweb.view import Template, ReloadableMixIn @@ -146,12 +145,7 @@ class RelatedEntityBoxTemplate(EntityBoxTemplate): - # XXX find a way to generalize access to cls.rtype - @objectify_selector - def my_selector(cls, req, rset, row=None, col=0, **kwargs): - return EntityBoxTemplate.__select__ & has_related_entities(cls.rtype) - - __select__ = my_selector + __select__ = EntityBoxTemplate.__select__ & abstract_has_related_entities() def cell_call(self, row, col, **kwargs): entity = self.entity(row, col) diff -r 45d816326626 -r 33db07c66789 web/facet.py --- a/web/facet.py Wed Feb 18 13:44:23 2009 +0100 +++ b/web/facet.py Wed Feb 18 13:44:35 2009 +0100 @@ -19,8 +19,7 @@ from rql import parse, nodes from cubicweb import Unauthorized, typed_eid -from cubicweb.vregistry import objectify_selector -from cubicweb.selectors import match_context_prop, one_has_relation +from cubicweb.selectors import match_context_prop, abstract_relation_possible from cubicweb.appobject import AppRsetObject from cubicweb.common.registerers import priority_registerer from cubicweb.web.htmlwidgets import HTMLWidget @@ -334,14 +333,7 @@ class RelationFacet(VocabularyFacet): - # XXX find a way to generalize access to cls.rtype - @objectify_selector - def my_selector(cls, req, rset, row=None, col=0, **kwargs): - selector = (relation_possible(cls.rtype, role(cls)) - & match_context_prop()) - return selector(cls, req, rset, row, col, **kwargs) - - __select__ = my_selector() + __select__ = abstract_relation_possible() & match_context_prop() # class attributes to configure the rel ation facet rtype = None role = 'subject' diff -r 45d816326626 -r 33db07c66789 web/views/tabs.py --- a/web/views/tabs.py Wed Feb 18 13:44:23 2009 +0100 +++ b/web/views/tabs.py Wed Feb 18 13:44:35 2009 +0100 @@ -11,8 +11,7 @@ from logilab.mtconverter import html_escape from cubicweb import NoSelectableObject, role -from cubicweb.vregistry import objectify_selector -from cubicweb.selectors import has_related_entities +from cubicweb.selectors import abstract_has_related_entities from cubicweb.common.view import EntityView from cubicweb.common.utils import HTMLHead from cubicweb.common.uilib import rql_for_eid @@ -144,14 +143,8 @@ class ProjectScreenshotTab(DataDependantTab, ProjectScreenshotsView): id = 'screenshots_tab' """ - # XXX needs to be generalized - @objectify_selector - def my_selector(cls, req, rset, row=None, col=0, **kwargs): - selector = (EntityView.__select__ & - has_related_entities(cls.rtype, role(cls))) - return selector(cls, req, rset, row=None, col=0, **kwargs) - - __select__ = my_selector() + __select__ = EntityView.__select__ & abstract_has_related_entities() + vid = 'list' def cell_call(self, row, col):