--- 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.
--- 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'
--- 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)
--- 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'
--- 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):