# HG changeset patch # User Damien Correia # Date 1528991394 -7200 # Node ID b63d9050929da873deca3794b4cabc036b3d6da8 # Parent 1284a943f9799ed53fd4a5970cadb0fd96ae09f7# Parent c0db0561ded3936ab9f2615c2c2d84e2cdf45f1d merge default diff -r 1284a943f979 -r b63d9050929d src/pyams_utils/adapter.py --- a/src/pyams_utils/adapter.py Thu Jun 14 10:41:06 2018 +0200 +++ b/src/pyams_utils/adapter.py Thu Jun 14 17:49:54 2018 +0200 @@ -31,8 +31,9 @@ from zope.annotation.interfaces import IAnnotations # import packages +from pyams_utils.factory import get_object_factory from pyams_utils.registry import get_current_registry -from zope.interface import implementedBy, alsoProvides +from zope.interface import implementedBy, alsoProvides, Interface from zope.lifecycleevent import ObjectCreatedEvent from zope.location import locate as zope_locate @@ -157,6 +158,9 @@ elif factory is None: return None else: + if issubclass(factory, Interface): + factory = get_object_factory(factory) + assert factory is not None, "Missing object factory" adapter = annotations[key] = factory() if markers: if not isinstance(markers, (list, tuple, set)): diff -r 1284a943f979 -r b63d9050929d src/pyams_utils/container.py --- a/src/pyams_utils/container.py Thu Jun 14 10:41:06 2018 +0200 +++ b/src/pyams_utils/container.py Thu Jun 14 17:49:54 2018 +0200 @@ -17,6 +17,7 @@ # import interfaces from zope.container.interfaces import IContainer, IContained +from zope.lifecycleevent.interfaces import IObjectMovedEvent from zope.location.interfaces import ISublocations # import packages @@ -38,6 +39,44 @@ self._order = PersistentList() +class ParentSelector(object): + """Interface based parent selector + + This selector can be used as a subscriber predicate on IObjectAddedEvent to define + an interface that the new parent must support for the event to be applied:: + + .. code-block:: python + + from pyams_utils.interfaces.site import ISiteRoot + + @subscriber(IObjectAddedEvent, parent_selector=ISiteRoot) + def siteroot_object_added_event_handler(event): + '''This is an event handler for an ISiteRoot object added event''' + """ + + def __init__(self, ifaces, config): + if not isinstance(ifaces, (list, tuple, set)): + ifaces = (ifaces,) + self.interfaces = ifaces + + def text(self): + return 'parent_selector = %s' % str(self.interfaces) + + phash = text + + def __call__(self, event): + if not IObjectMovedEvent.providedBy(event): + return False + for intf in self.interfaces: + try: + if intf.providedBy(event.newParent): + return True + except (AttributeError, TypeError): + if isinstance(event.newParent, intf): + return True + return False + + @adapter_config(context=IContained, provides=ISublocations) class ContainerSublocationsAdapter(ContextAdapter): """Contained object sub-locations adapter diff -r 1284a943f979 -r b63d9050929d src/pyams_utils/include.py --- a/src/pyams_utils/include.py Thu Jun 14 10:41:06 2018 +0200 +++ b/src/pyams_utils/include.py Thu Jun 14 17:49:54 2018 +0200 @@ -22,6 +22,7 @@ # import packages from chameleon import PageTemplateFile +from pyams_utils.container import ParentSelector from pyams_utils.context import ContextSelector from pyams_utils.request import get_annotations, get_debug, RequestSelector from pyams_utils.site import site_factory @@ -50,6 +51,7 @@ # add custom subscriber predicate to filter events via supported interface(s) config.add_subscriber_predicate('context_selector', ContextSelector) + config.add_subscriber_predicate('parent_selector', ParentSelector) config.add_subscriber_predicate('request_selector', RequestSelector) # load registry components