def __delSublocations(self, obj): subs = ISublocations(obj, None) if subs is not None: for sub in subs.sublocations(): sub._v_del = True if ISublocations(sub, None): self.__delSublocations(sub)
def getContentKey(self): """Create a unique string to identify the content for a cookie key, hopefully this will work in zope 2 and 3.""" key = getattr(self, '_key_cache', None) if key: return key key = [] if not hasattr(self.context, '__parent__'): subloc = None else: subloc = ISublocations(self.context.aq_inner.__parent__, alternative=None) if subloc is not None: for s in subloc.sublocations(): key.append(s.__name__) key.insert(0, self.context.__name__) else: try: key.extend(self.context.getPhysicalPath()) except AttributeError: pass if not key: # A cheap alternative key = KEYBASE + str(self.context) else: key = KEYBASE + '-'.join(key) self._key_cache = key return key
def handle_removed_object(event): """Notify IntId utility for removed objects This subscriber is used for all persistent objects to be unregistered from all locally registered IIntIds utilities. """ registry = get_current_registry() locations = ISublocations(event.object, None) if locations is not None: for location in locations.sublocations(): # pylint: disable=too-many-function-args registry.notify(ObjectRemovedEvent(location)) utilities = tuple(get_all_utilities_registered_for(IIntIds)) if utilities: try: key = IKeyReference(event.object, None) except NotYet: pass else: # Register only objects that adapt to key reference if key is not None: # Notify the catalogs that this object is about to be removed. registry.notify(IntIdRemovedEvent(event.object, event)) for utility in utilities: try: utility.unregister(key) except KeyError: pass
def find_objects_matching(root, condition, ignore_root=False, with_depth=False, initial_depth=0): """Find all objects in root that match the condition The condition is a Python callable object that takes an object as argument and must return a boolean result. All sub-objects of the root will also be searched recursively. :param object root: the parent object from which search is started :param callable condition: a callable object which may return true for a given object to be selected :param boolean ignore_root: if *True*, the root object will not be returned, even if it matches the given condition :param boolean with_depth: if *True*, iterator elements will be made of tuples made of found elements and their respective depth :param int initial_depth: initial depth of the root element; this argument is mainly used when function is called recursively :return: an iterator for all root's sub-objects matching condition """ if (not ignore_root) and condition(root): yield (root, initial_depth) if with_depth else root locations = ISublocations(root, None) if locations is not None: for location in locations.sublocations(): # pylint: disable=too-many-function-args if condition(location): yield (location, initial_depth + 1) if with_depth else location yield from find_objects_matching(location, condition, ignore_root=True, with_depth=with_depth, initial_depth=initial_depth + 1)
def dispatchToSublocations(object, event): """Dispatch an event to sublocations of a given object When a move event happens for an object, it's important to notify subobjects as well. """ subs = ISublocations(object, None) if subs is not None: for sub in subs.sublocations(): for ignored in zope.component.subscribers((sub, event), None): pass # They do work in the adapter fetch
def _find_recur(self, root, seen): # This could be better if we memorized the utilities earlier, # and applied that to _utilities_up_tree. As it is, this is something like # O(n^2) if IWebhookSubscriptionManager.providedBy(root): yield root subs = ISublocations(root, None) if subs is None: return for sub in subs.sublocations(): # pylint:disable=too-many-function-args for m in self._find_recur(sub, seen): yield m
def dispatchToSublocations(object, event): """Dispatches an event to sublocations of a given object. This handler is used to dispatch copy events to sublocations. To illustrate, we'll first create a hierarchy of objects: >>> class L(object): ... def __init__(self, name): ... self.__name__ = name ... self.__parent__ = None ... def __repr__(self): ... return '%s(%s)' % (self.__class__.__name__, self.__name__) >>> class C(L): ... implements(ISublocations) ... def __init__(self, name, *subs): ... L.__init__(self, name) ... self.subs = subs ... for sub in subs: ... sub.__parent__ = self ... def sublocations(self): ... return self.subs >>> c = C(1, ... C(11, ... L(111), ... L(112), ... ), ... C(12, ... L(121), ... L(122), ... L(123), ... L(124), ... ), ... L(13), ... ) and a handler for copy events that records the objects it's seen: >>> seen = [] >>> def handler(ob, event): ... seen.append((ob, event.object)) Finally, we need to register our handler for copy events: >>> from zope.lifecycleevent.interfaces import IObjectCopiedEvent >>> gsm = zope.component.getGlobalSiteManager() >>> gsm.registerHandler(handler, [None, IObjectCopiedEvent]) and this function as a dispatcher: >>> gsm.registerHandler(dispatchToSublocations, ... [None, IObjectCopiedEvent]) When we notify that our root object has been copied: >>> notify(ObjectCopiedEvent(c, L(''))) we see that our handler has seen all of the subobjects: >>> seenreprs = map(repr, seen) >>> seenreprs.sort() >>> seenreprs #doctest: +NORMALIZE_WHITESPACE ['(C(1), C(1))', '(C(11), C(1))', '(C(12), C(1))', '(L(111), C(1))', '(L(112), C(1))', '(L(121), C(1))', '(L(122), C(1))', '(L(123), C(1))', '(L(124), C(1))', '(L(13), C(1))'] """ subs = ISublocations(object, None) if subs is not None: for sub in subs.sublocations(): for ignored in zope.component.subscribers((sub, event), None): pass # They do work in the adapter fetch
def dispatchToSublocations(object, event): # pylint:disable=redefined-builtin """Dispatch an event to sublocations of a given object When a move event happens for an object, it's important to notify subobjects as well. We do this based on locations. Suppose, for example, that we define some location objects. >>> @zope.interface.implementer(ILocation) ... class L(object): ... def __init__(self, name): ... self.__name__ = name ... self.__parent__ = None ... def __repr__(self): ... return '%s(%s)' % ( ... self.__class__.__name__, str(self.__name__)) >>> @zope.interface.implementer(ISublocations) ... class C(L): ... def __init__(self, name, *subs): ... L.__init__(self, name) ... self.subs = subs ... for sub in subs: ... sub.__parent__ = self ... def sublocations(self): ... return self.subs >>> c = C(1, ... C(11, ... L(111), ... L(112), ... ), ... C(12, ... L(121), ... L(122), ... L(123), ... L(124), ... ), ... L(13), ... ) Now, if we call the dispatcher, it should call event handlers for all of the objects. Lets create an event handler that records the objects it sees: >>> seen = [] >>> def handler(ob, event): ... seen.append((ob, event.object)) Note that we record the the object the handler is called on as well as the event object: Now we'll register it: >>> from zope import component >>> from zope.lifecycleevent.interfaces import IObjectMovedEvent >>> component.provideHandler(handler, [None, IObjectMovedEvent]) We also register our dispatcher: >>> component.provideHandler(dispatchToSublocations, ... [None, IObjectMovedEvent]) We can then call the dispatcher for the root object: >>> event = ObjectRemovedEvent(c) >>> dispatchToSublocations(c, event) Now, we should have seen all of the subobjects: >>> seenreprs = sorted(map(repr, seen)) >>> seenreprs ['(C(11), C(1))', '(C(12), C(1))', '(L(111), C(1))',""" \ """ '(L(112), C(1))', '(L(121), C(1))', '(L(122), C(1))',""" \ """ '(L(123), C(1))', '(L(124), C(1))', '(L(13), C(1))'] We see that we get entries for each of the subobjects and that,for each entry, the event object is top object. This suggests that location event handlers need to be aware that the objects they are called on and the event objects could be different. """ subs = ISublocations(object, None) if subs is not None: for sub in subs.sublocations(): zope.component.handle(sub, event)
def dispatchToSublocations(object, event): """Dispatch an event to sublocations of a given object When a move event happens for an object, it's important to notify subobjects as well. We do this based on locations. Suppose, for example, that we define some location objects. >>> @zope.interface.implementer(ILocation) ... class L(object): ... def __init__(self, name): ... self.__name__ = name ... self.__parent__ = None ... def __repr__(self): ... return '%s(%s)' % ( ... self.__class__.__name__, str(self.__name__)) >>> @zope.interface.implementer(ISublocations) ... class C(L): ... def __init__(self, name, *subs): ... L.__init__(self, name) ... self.subs = subs ... for sub in subs: ... sub.__parent__ = self ... def sublocations(self): ... return self.subs >>> c = C(1, ... C(11, ... L(111), ... L(112), ... ), ... C(12, ... L(121), ... L(122), ... L(123), ... L(124), ... ), ... L(13), ... ) Now, if we call the dispatcher, it should call event handlers for all of the objects. Lets create an event handler that records the objects it sees: >>> seen = [] >>> def handler(ob, event): ... seen.append((ob, event.object)) Note that we record the the object the handler is called on as well as the event object: Now we'll register it: >>> from zope import component >>> from zope.lifecycleevent.interfaces import IObjectMovedEvent >>> component.provideHandler(handler, [None, IObjectMovedEvent]) We also register our dispatcher: >>> component.provideHandler(dispatchToSublocations, ... [None, IObjectMovedEvent]) We can then call the dispatcher for the root object: >>> event = ObjectRemovedEvent(c) >>> dispatchToSublocations(c, event) Now, we should have seen all of the subobjects: >>> seenreprs = sorted(map(repr, seen)) >>> seenreprs ['(C(11), C(1))', '(C(12), C(1))', '(L(111), C(1))',""" \ """ '(L(112), C(1))', '(L(121), C(1))', '(L(122), C(1))',""" \ """ '(L(123), C(1))', '(L(124), C(1))', '(L(13), C(1))'] We see that we get entries for each of the subobjects and that,for each entry, the event object is top object. This suggests that location event handlers need to be aware that the objects they are called on and the event objects could be different. """ subs = ISublocations(object, None) if subs is not None: for sub in subs.sublocations(): zope.component.handle(sub, event)