--- a/src/pyams_utils/container.py Thu Jun 14 08:58:27 2018 +0200
+++ b/src/pyams_utils/container.py Thu Jun 14 13:57:57 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
--- a/src/pyams_utils/include.py Thu Jun 14 08:58:27 2018 +0200
+++ b/src/pyams_utils/include.py Thu Jun 14 13:57:57 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