def saveSchedule(self): session = Session() sitting_id = self.sitting.sitting_id record_keys = [] planned_index = 1 def add_planned_index(obj, index): """add planned order key for non text record types """ if not (model_interfaces.IScheduleText.providedBy(obj.item)): obj.planned_order = planned_index index = index + 1 return index for (index, data_item) in enumerate(self.data): real_index = index + 1 data_schedule_id = data_item.get("schedule_id") data_item_id = data_item.get("item_id") data_item_type = data_item.get("item_type") schedule_item_type = data_item_type data_item_text = data_item.get("item_text") data_item_wf_status = data_item.get("wf_status") if not data_item_id: # create text record before inserting into schedule text_record = domain.AgendaTextRecord( text=data_item_text, record_type=data_item_type, language=get_default_language()) session.add(text_record) session.flush() notify(ObjectCreatedEvent(text_record)) data_item_id = domain.get_mapped_object_id(text_record) schedule_item_type = domain.AgendaTextRecord.type schedule_record = domain.ItemSchedule( item_id=data_item_id, item_type=schedule_item_type, real_order=real_index, sitting_id=sitting_id) session.add(schedule_record) session.flush() notify(ObjectCreatedEvent(schedule_record)) else: if data_schedule_id: current_record = removeSecurityProxy( self.context.get(getItemKey(data_schedule_id))) current_record.real_order = real_index planned_index = add_planned_index(current_record, planned_index) session.add(current_record) session.flush() notify(ObjectModifiedEvent(current_record)) #workflow operations wfc = IWorkflowController(current_record.item, None) if wfc: if wfc and data_item_wf_status: try: wfc.workflow.get_transition( data_item_wf_status) wfc.fireTransition(data_item_wf_status) except InvalidTransitionError: log.error( "Invalid transition [%s] for object: [%s] ", data_item_wf_status, current_record) wfc.fireAutomatic() #update text for text records text_record = removeSecurityProxy(current_record.item) if model_interfaces.IScheduleText.providedBy(text_record): schedule_item_type = domain.AgendaTextRecord.type if text_record.text != data_item_text: text_record.text = data_item_text session.add(text_record) session.flush() notify(ObjectModifiedEvent(text_record)) else: schedule_record = domain.ItemSchedule( item_id=data_item_id, item_type=data_item_type, real_order=real_index, sitting_id=sitting_id) planned_index = add_planned_index(schedule_record, planned_index) session.add(schedule_record) session.flush() notify(ObjectCreatedEvent(schedule_record)) record_keys.append(self.RECORD_KEY % (schedule_item_type, data_item_id)) records_to_delete = filter( lambda item: (self.RECORD_KEY % (item.item_type, item.item_id) not in record_keys), [removeSecurityProxy(rec) for rec in self.context.values()]) map(session.delete, records_to_delete) map(lambda deleted: notify(ObjectRemovedEvent(deleted)), records_to_delete)
def __delitem__(self, key): l = self.__len item = self.__data[key] del self.__data[key] l.change(-1) notify(ObjectRemovedEvent(item, self, item.__name__))
def handle_delete_server(self, action, data): for id in self.request.form.get("serverId", []): if id in self.storage.servers: notify(ObjectRemovedEvent(self.storage.servers[id])) del self.storage.servers[id] return self.request.response.redirect(self.nextURL())
def handle_delete_property(self, action, data): for id in self.request.form.get("propertyId", []): if id in self.storage.schema: notify(ObjectRemovedEvent(self.storage.schema[id])) del self.storage.schema[id] return self.request.response.redirect(self.nextURL())
def dispatch_event(obj, event): sm = obj._sm if sm is not None: for k, v in sm.items(): notify(ObjectRemovedEvent(v, sm, k))
def __set__(self, instance, value): # pylint: disable=too-many-locals,too-many-statements,too-many-branches registry = get_current_registry() for lang in value: lang_value = value[lang] if (lang_value is TO_BE_DELETED) or (lang_value is NOT_CHANGED): continue if lang_value is not None: filename = None # file upload data converter returns a tuple containing # filename and buffered IO stream extracted from FieldStorage... if isinstance(lang_value, tuple): filename, lang_value = lang_value # initialize file through factory if not IFile.providedBy(lang_value): factory = self.__klass or FileFactory file = factory(lang_value, **self.__args) registry.notify(ObjectCreatedEvent(file)) if not file.get_size(): lang_value.seek(0) # because factory may read until end of file... file.data = lang_value lang_value = file if filename is not None: info = IFileInfo(lang_value) if info is not None: info.filename = filename value[lang] = lang_value field = self.__field.bind(instance) field.validate(value) if field.readonly and instance.__dict__.has_key(self.__name): raise ValueError(self.__name, "Field is readonly") old_value = instance.__dict__.get(self.__name, _MARKER) if old_value != value: # check for previous value if old_value is _MARKER: old_value = {} for lang in value: new_lang_value = value.get(lang) if new_lang_value is NOT_CHANGED: continue old_lang_value = old_value.get(lang, _MARKER) if (old_lang_value is not _MARKER) and (old_lang_value is not None): registry.notify(ObjectRemovedEvent(old_lang_value)) attrname = '{0}::{1}'.format(self.__name, lang) if new_lang_value is TO_BE_DELETED: if (self.__name in instance.__dict__) and (lang in old_value): del old_value[lang] attributes = get_instance_attributes(instance) if attributes and (attrname in attributes): attributes.remove(attrname) else: # set name of new value name = '++i18n++{0}:{1}'.format(self.__name, lang) if new_lang_value is not None: locate(new_lang_value, instance, name) old_value[lang] = new_lang_value # store file attributes of instance if not IFileFieldContainer.providedBy(instance): alsoProvides(instance, IFileFieldContainer) attributes = get_instance_attributes(instance) attributes.add(attrname) registry.notify(ObjectAddedEvent(new_lang_value, instance, name)) instance.__dict__[self.__name] = old_value
def uncontained(object, container, name=None): """Clear the containment relationship between the `object` and the `container`. If we run this using the testing framework, we'll use `getEvents` to track the events generated: >>> from zope.component.eventtesting import getEvents >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent >>> from zope.lifecycleevent.interfaces import IObjectRemovedEvent We'll start by creating a container with an item: >>> class Item(Contained): ... pass >>> item = Item() >>> container = {u'foo': item} >>> x, event = containedEvent(item, container, u'foo') >>> item.__parent__ is container 1 >>> item.__name__ u'foo' Now we'll remove the item. It's parent and name are cleared: >>> uncontained(item, container, u'foo') >>> item.__parent__ >>> item.__name__ We now have a new removed event: >>> len(getEvents(IObjectRemovedEvent)) 1 >>> event = getEvents(IObjectRemovedEvent)[-1] >>> event.object is item 1 >>> event.oldParent is container 1 >>> event.oldName u'foo' >>> event.newParent >>> event.newName As well as a modification event for the container: >>> len(getEvents(IObjectModifiedEvent)) 1 >>> getEvents(IObjectModifiedEvent)[-1].object is container 1 Now if we call uncontained again: >>> uncontained(item, container, u'foo') We won't get any new events, because __parent__ and __name__ are None: >>> len(getEvents(IObjectRemovedEvent)) 1 >>> len(getEvents(IObjectModifiedEvent)) 1 But, if either the name or parent are not ``None`` and they are not the container and the old name, we'll get a modified event but not a removed event. >>> item.__parent__, item.__name__ = container, None >>> uncontained(item, container, u'foo') >>> len(getEvents(IObjectRemovedEvent)) 1 >>> len(getEvents(IObjectModifiedEvent)) 2 >>> item.__parent__, item.__name__ = None, u'bar' >>> uncontained(item, container, u'foo') >>> len(getEvents(IObjectRemovedEvent)) 1 >>> len(getEvents(IObjectModifiedEvent)) 3 If one tries to delete a Broken object, we allow them to do just that. >>> class Broken(object): ... __Broken_state__ = {} >>> broken = Broken() >>> broken.__Broken_state__['__name__'] = u'bar' >>> broken.__Broken_state__['__parent__'] = container >>> container[u'bar'] = broken >>> uncontained(broken, container, u'bar') >>> len(getEvents(IObjectRemovedEvent)) 2 """ try: oldparent = object.__parent__ oldname = object.__name__ except AttributeError: # The old object doesn't implements IContained # Maybe we're converting old data: if hasattr(object, '__Broken_state__'): state = object.__Broken_state__ oldparent = state['__parent__'] oldname = state['__name__'] else: if not fixing_up: raise oldparent = None oldname = None if oldparent is not container or oldname != name: if oldparent is not None or oldname is not None: notifyContainerModified(container) return event = ObjectRemovedEvent(object, oldparent, oldname) notify(event) if not IBroken.providedBy(object): object.__parent__ = None object.__name__ = None notifyContainerModified(container)
def saveSchedule(self): session = Session() group_sitting_id = self.sitting.group_sitting_id group_id = self.sitting.group_id record_keys = [] for (index, data_item_text) in enumerate(self.data): data_item = json.loads(data_item_text) actual_index = index + 1 data_schedule_id = data_item.get("schedule_id") data_item_id = data_item.get("item_id") data_item_type = data_item.get("item_type") data_item_text = data_item.get("item_text") if not data_item_id: # create text record before inserting into schedule if data_item_type == u"text": text_record = domain.ScheduleText( text=data_item_text, group_id=group_id, language=get_default_language() ) session.add(text_record) session.flush() notify(ObjectCreatedEvent(text_record)) data_item_id = text_record.schedule_text_id elif data_item_type == u"heading": heading_record = domain.Heading( text=data_item_text, group_id=group_id, language=get_default_language() ) session.add(heading_record) session.flush() notify(ObjectCreatedEvent(heading_record)) data_item_id = heading_record.heading_id schedule_record = domain.ItemSchedule( item_id=data_item_id, item_type=data_item_type, planned_order=actual_index, group_sitting_id=group_sitting_id ) session.add(schedule_record) session.flush() notify(ObjectCreatedEvent(schedule_record)) else: if data_schedule_id: current_record = removeSecurityProxy( self.context.get(getItemKey(data_schedule_id)) ) current_record.planned_order = actual_index session.add(current_record) session.flush() notify(ObjectModifiedEvent(current_record)) #update text for text records #!+INTERFACES(Apply this behaviour via shared interface) if data_item_type in [u"text", u"heading"]: text_record = removeSecurityProxy(current_record.item) if text_record.text != data_item_text: text_record.text = data_item_text session.add(text_record) session.flush() notify(ObjectModifiedEvent(text_record)) else: schedule_record = domain.ItemSchedule( item_id=data_item_id, item_type=data_item_type, planned_order=actual_index, group_sitting_id=group_sitting_id ) session.add(schedule_record) session.flush() notify(ObjectCreatedEvent(schedule_record)) record_keys.append(self.RECORD_KEY % (data_item_type, data_item_id)) records_to_delete = filter( lambda item:(self.RECORD_KEY % (item.item_type, item.item_id) not in record_keys ), [removeSecurityProxy(rec) for rec in self.context.values()] ) map(session.delete, records_to_delete) map(lambda deleted:notify(ObjectRemovedEvent(deleted)), records_to_delete )
def testIgnoreDeletedEvents(self): class Content(object): __parent__ = None __name__ = None handlers.modified(ObjectRemovedEvent(Content())) self.assertFalse(self.called)
def clear(self): deleted = list(self._links.items()) self._links.clear() self._byrole.clear() for name, link in deleted: notify(ObjectRemovedEvent(link, self._links, name))
def notifyDelete(self, obj): obj.reindexObject() obj.aq_parent.reindexObject() zope.event.notify(ObjectRemovedEvent(obj))