def makeChange(self, item, change): event = EventStamp(item) changeType = change[1] if changeType == 'set': EventStamp(item).changeThis(change[2], change[3]) return change[2] elif changeType in ('addStamp', 'removeStamp'): event.changeThis() method = getattr(change[0], change[1]) return method(item, *change[2:]) elif changeType == 'add' and change[2] is schema.ns("osaf.pim", item.itsView).trashCollection: event.deleteThis() elif changeType in ('add', 'append', 'remove'): attrName, newValue = _multiChange(item, change) EventStamp(item).changeThis(attrName, newValue) return attrName
def appendChange(self, desc, op, attr, *args): super(RecurrenceProxy, self).appendChange(desc, op, attr, *args) item = self.proxiedItem if (not stamping.has_stamp(item, EventStamp) or EventStamp(item).rruleset is None): super(RecurrenceProxy, self).makeChanges() elif self.changing is not None: self.makeChanges()
def makeChange(self, item, change): # easy for set, not too bad for stamp addition, del is maybe # tricky, and add/remove require duplicating reflists event = EventStamp(item) changeType = change[1] if changeType == 'set': attr = change[2] self._updateEdited( item for item in event.modifications if not item.hasModifiedAttribute(attr) ) event.changeAll(attr, change[3]) return attr elif changeType == 'addStamp': self._updateEdited( item for item in event.modifications if not stamping.has_stamp(item, change[2]) ) event.addStampToAll(change[2].stamp_type) return stamping.Stamp.stamp_types.name elif changeType == 'removeStamp': self._updateEdited( item for item in event.modifications if stamping.has_stamp(item, change[2]) ) event.removeStampFromAll(change[2].stamp_type) return stamping.Stamp.stamp_types.name elif changeType in ('add', 'remove', 'append'): attr = change[0].descriptor.name self._updateEdited( item for item in event.modifications if not item.hasModifiedAttribute(attr) ) masterItem = event.getMaster().itsItem attrName, newValue = _multiChange(masterItem, change) with EventStamp(masterItem).noRecurrenceChanges(): setattr(masterItem, attrName, newValue) return attrName elif (changeType == 'delete' and change[0].descriptor.name == EventStamp.rruleset.name): event.removeRecurrence() return EventStamp.rruleset.name else: assert False
def markProxyEdited(self, proxy, attrs): if self.editedItems: for item in self.editedItems: if not reminders.isDead(item): with EventStamp(item).noRecurrenceChanges(): for attr in self.EDIT_ATTRIBUTES: if item.hasLocalAttributeValue(attr): delattr(item, attr) del self.editedItems super(CHANGE_ALL, self).markProxyEdited(proxy, attrs)
def makeChange(self, item, change): event = EventStamp(item) changeType = change[1] if changeType == 'set': EventStamp(item).changeThis(change[2], change[3]) return change[2] elif changeType in ('addStamp', 'removeStamp'): event.changeThis() method = getattr(change[0], change[1]) return method(item, *change[2:]) elif changeType == 'add' and change[2] is schema.ns( "osaf.pim", item.itsView).trashCollection: event.deleteThis() elif changeType in ('add', 'append', 'remove'): attrName, newValue = _multiChange(item, change) EventStamp(item).changeThis(attrName, newValue) return attrName
def makeChange(self, item, change): event = EventStamp(item) changeType = change[1] # as above, for CHANGE_ALL if changeType == 'set': attr = change[2] event.changeThisAndFuture(attr, change[3]) self._updateEdited(item for item in event.modifications if not item.hasModifiedAttribute(attr)) return attr elif changeType == 'add' and change[2] is schema.ns( "osaf.pim", item.itsView).trashCollection: event.deleteThisAndFuture() elif changeType in ('addStamp', 'removeStamp', 'add', 'remove', 'append'): event.changeThisAndFuture() return super(CHANGE_FUTURE, self).makeChange(item, change) else: assert False
def makeChange(self, item, change): event = EventStamp(item) changeType = change[1] # as above, for CHANGE_ALL if changeType == 'set': attr = change[2] event.changeThisAndFuture(attr, change[3]) self._updateEdited( item for item in event.modifications if not item.hasModifiedAttribute(attr) ) return attr elif changeType == 'add' and change[2] is schema.ns("osaf.pim", item.itsView).trashCollection: event.deleteThisAndFuture() elif changeType in ('addStamp', 'removeStamp', 'add', 'remove', 'append'): event.changeThisAndFuture() return super(CHANGE_FUTURE, self).makeChange(item, change) else: assert False
def installParcel(parcel, oldVersion=None): view = parcel.itsView # Create our one collection of indexDefinition mappings; when each gets # created, its __init__ will add it to this collection automagically. AllIndexDefinitions.update(parcel, "allIndexDefinitions") Reference.update(parcel, "currentContact") MailPreferences.update(parcel, "MailPrefs") Reference.update(parcel, "currentMeEmailAddress") cur = Reference.update(parcel, "currentIncomingAccount") cur1 = Reference.update(parcel, "currentOutgoingAccount") if cur.item is None: cur.item = IMAPAccount( itsView=view, displayName=_(u"Incoming Mail"), replyToAddress=EmailAddress(itsView=view), password=password.Password(itsView=view), ) if cur1.item is None: cur1.item = SMTPAccount(itsView=view, displayName=_(u"Outgoing Mail"), password=password.Password(itsView=view)) trashCollection = ListCollection.update(parcel, "trashCollection", displayName=_(u"Trash")) notes = KindCollection.update(parcel, "noteCollection", kind=Note.getKind(view), recursive=True) mine = UnionCollection.update(parcel, "mine") # it would be nice to get rid of these intermediate fully-fledged # item collections, and replace them with lower level Set objects mineNotes = IntersectionCollection.update(parcel, "mineNotes", sources=[mine, notes]) nonOccurrenceFilter = NonOccurrenceFilter(None, parcel) nonRecurringNotes = FilteredCollection.update( parcel, "nonRecurringNotes", source=mineNotes, filterMethod=(nonOccurrenceFilter, "isNonOccurrence"), filterAttributes=[EventStamp.occurrenceFor.name, EventStamp.modificationFor.name, EventStamp.occurrences.name], ) nonRecurringNotes.addIndex("__adhoc__", "numeric") allContentItems = KindCollection.update(parcel, "allContentItems", kind=ContentItem.getKind(view), recursive=True) contentItems = FilteredCollection.update( parcel, "contentItems", source=allContentItems, filterMethod=(nonOccurrenceFilter, "isNotPureOccurrence"), filterAttributes=[EventStamp.occurrenceFor.name, EventStamp.modificationFor.name], ) allReminders = KindCollection.update(parcel, "allReminders", kind=Reminder.getKind(view), recursive=True) allFutureReminders = FilteredCollection.update( parcel, "allFutureReminders", source=allReminders, filterMethod=(UnexpiredFilter(None, parcel), "notExpired"), filterAttributes=[UnexpiredFilter.findValuePair[0]], ) allFutureReminders.addIndex( "reminderPoll", "method", method=(UnexpiredFilter(None, parcel), "compare"), monitor=[UnexpiredFilter.findValuePair[0]], ) # the "All" / "My" collection allCollection = SmartCollection.update( parcel, "allCollection", displayName=_(u"Dashboard"), source=nonRecurringNotes, exclusions=trashCollection, trash=None, ) # kludge to improve on bug 4144 (not a good long term fix but fine for 0.6) allCollection.addIndex("__adhoc__", "numeric") events = EventStamp.getCollection(view) eventComparator = EventComparator.update(parcel, "eventComparator") EventStamp.addIndex( events, "effectiveStart", "method", method=(eventComparator, "cmpStartTime"), monitor=(EventStamp.startTime, EventStamp.allDay, EventStamp.anyTime), kind=ContentItem.getKind(view), ) EventStamp.addIndex( events, "effectiveEnd", "method", method=(eventComparator, "cmpEndTime"), monitor=(EventStamp.startTime, EventStamp.allDay, EventStamp.anyTime, EventStamp.duration), kind=ContentItem.getKind(view), ) # floatingEvents need to be reindexed in effectiveStart and effectiveEnd # when the floating timezone changes filterAttributes = [entry[0] for entry in _FILTER_ATTRIBUTES] floatingEvents = FilteredCollection.update( parcel, "floatingEvents", source=events, filterMethod=(FloatingEventFilter(None, parcel), "isFloatingEvent"), filterAttributes=filterAttributes, ) floatingEvents.addIndex("__adhoc__", "numeric") # UTCEvents need to be reindexed in effectiveStartNoTZ and effectiveEndNoTZ # when the floating timezone changes, because UTC events are treated # specially UTCEvents = FilteredCollection.update( parcel, "UTCEvents", source=events, filterMethod=(UTCEventFilter(None, parcel), "isUTCEvent"), filterAttributes=filterAttributes, ) UTCEvents.addIndex("__adhoc__", "numeric") longEvents = FilteredCollection.update( parcel, "longEvents", source=events, filterMethod=(LongEventFilter(None, parcel), "isLongEvent"), filterAttributes=[EventStamp.duration.name], ) longEvents.addIndex("effectiveStart", "subindex", superindex=(events, events.__collection__, "effectiveStart")) longEvents.addIndex("effectiveEnd", "subindex", superindex=(events, events.__collection__, "effectiveEnd")) filterAttributes = (EventStamp.rruleset.name, EventStamp.occurrences.name) masterFilter = "view.hasTrueValues(uuid, '%s', '%s')" % filterAttributes nonMasterFilter = "not " + masterFilter masterEvents = FilteredCollection.update( parcel, "masterEvents", source=events, filterExpression=masterFilter, filterAttributes=list(filterAttributes) ) nonMasterEvents = FilteredCollection.update( parcel, "nonMasterEvents", source=events, filterExpression=nonMasterFilter, filterAttributes=list(filterAttributes), ) MasterEventWatcher.update(parcel, "masterEventWatcher", targetCollection=masterEvents) EventStamp.addIndex( masterEvents, "recurrenceEnd", "method", method=(eventComparator, "cmpRecurEnd"), monitor=(EventStamp.recurrenceEnd,), ) EventStamp.addIndex( masterEvents, "effectiveStart", "subindex", superindex=(events, events.__collection__, "effectiveStart") ) locations = KindCollection.update(parcel, "locations", kind=Location.getKind(view), recursive=True) locations.addIndex("locationName", "value", attribute="displayName", nodefer=True) mailCollection = mail.MailStamp.getCollection(view) kind = mail.EmailAddress.getKind(view) emailAddressCollection = KindCollection.update(parcel, "emailAddressCollection", kind=kind, recursive=True) emailComparator = EmailComparator.update(parcel, "emailComparator") emailAddressCollection.addIndex( "emailAddress", "method", method=(emailComparator, "cmpAddress"), monitor="emailAddress", nodefer=True ) emailAddressCollection.addIndex( "fullName", "method", method=(emailComparator, "cmpFullName"), monitor="fullName", nodefer=True ) emailAddressCollection.addIndex( "both", "method", method=(emailComparator, "cmpBoth"), monitor=("emailAddress", "fullName"), nodefer=True, kind=kind, ) # Contains all current me addresses (that is, referenced by an account) currentMeEmailAddresses = ListCollection.update(parcel, "currentMeEmailAddresses") currentMeEmailAddresses.addIndex( "emailAddress", "method", method=(emailComparator, "cmpAddress"), monitor="emailAddress" ) # Contains all current and former me addresses meEmailAddressCollection = ListCollection.update(parcel, "meEmailAddressCollection") meEmailAddressCollection.addIndex( "emailAddress", "method", method=(emailComparator, "cmpAddress"), monitor="emailAddress" ) inSource = ToMeFilter.makeCollection(parcel, "inSource", mailCollection) # this index must be added to shield from the duplicate # source (mailCollection) that is going to be in mine inSource.addIndex("__adhoc__", "numeric") # The "In" collection inCollection = SmartCollection.update( parcel, "inCollection", displayName=_(u"In"), source=inSource, trash=trashCollection, visible=True ) mine.addSource(inCollection) outSource = FromMeFilter.makeCollection(parcel, "outSource", mailCollection) # this index must be added to shield from the duplicate # source (mailCollection) that is going to be in mine outSource.addIndex("__adhoc__", "numeric") # The "Out" collection outCollection = SmartCollection.update( parcel, "outCollection", displayName=_(u"Out"), visible=True, source=outSource, trash=trashCollection ) mine.addSource(outCollection) allEventsCollection = IntersectionCollection.update(parcel, "allEventsCollection", sources=[allCollection, events]) searchResultsUnfiltered = SmartCollection.update(parcel, "searchResultsUnfiltered", displayName=messages.UNTITLED) searchResults = DifferenceCollection.update( parcel, "searchResults", sources=[searchResultsUnfiltered, masterEvents], displayName=messages.UNTITLED ) TriageStatusReminder.update(parcel, "triageStatusReminder") startup.Startup.update(parcel, "installWatchers", invoke=__name__ + ".installWatchers") tzInstallParcel(parcel)
def installParcel(parcel, oldVersion=None): view = parcel.itsView # Create our one collection of indexDefinition mappings; when each gets # created, its __init__ will add it to this collection automagically. AllIndexDefinitions.update(parcel, "allIndexDefinitions") Reference.update(parcel, 'currentContact') MailPreferences.update(parcel, 'MailPrefs') Reference.update(parcel, 'currentMeEmailAddress') cur = Reference.update(parcel, 'currentIncomingAccount') cur1 = Reference.update(parcel, 'currentOutgoingAccount') if cur.item is None: cur.item = IMAPAccount(itsView=view, displayName=_(u'Incoming Mail'), replyToAddress=EmailAddress(itsView=view), password=password.Password(itsView=view)) if cur1.item is None: cur1.item = SMTPAccount( itsView=view, displayName=_(u'Outgoing Mail'), password=password.Password(itsView=view), ) trashCollection = ListCollection.update(parcel, 'trashCollection', displayName=_(u"Trash")) notes = KindCollection.update(parcel, 'noteCollection', kind=Note.getKind(view), recursive=True) mine = UnionCollection.update(parcel, 'mine') # it would be nice to get rid of these intermediate fully-fledged # item collections, and replace them with lower level Set objects mineNotes = IntersectionCollection.update(parcel, 'mineNotes', sources=[mine, notes]) nonOccurrenceFilter = NonOccurrenceFilter(None, parcel) nonRecurringNotes = FilteredCollection.update( parcel, 'nonRecurringNotes', source=mineNotes, filterMethod=(nonOccurrenceFilter, 'isNonOccurrence'), filterAttributes=[ EventStamp.occurrenceFor.name, EventStamp.modificationFor.name, EventStamp.occurrences.name ]) nonRecurringNotes.addIndex('__adhoc__', 'numeric') allContentItems = KindCollection.update(parcel, 'allContentItems', kind=ContentItem.getKind(view), recursive=True) contentItems = FilteredCollection.update( parcel, 'contentItems', source=allContentItems, filterMethod=(nonOccurrenceFilter, 'isNotPureOccurrence'), filterAttributes=[ EventStamp.occurrenceFor.name, EventStamp.modificationFor.name ]) allReminders = KindCollection.update(parcel, 'allReminders', kind=Reminder.getKind(view), recursive=True) allFutureReminders = FilteredCollection.update( parcel, 'allFutureReminders', source=allReminders, filterMethod=(UnexpiredFilter(None, parcel), 'notExpired'), filterAttributes=[UnexpiredFilter.findValuePair[0]], ) allFutureReminders.addIndex('reminderPoll', 'method', method=(UnexpiredFilter(None, parcel), 'compare'), monitor=[UnexpiredFilter.findValuePair[0]]) # the "All" / "My" collection allCollection = SmartCollection.update( parcel, 'allCollection', displayName=_(u"Dashboard"), source=nonRecurringNotes, exclusions=trashCollection, trash=None, ) # kludge to improve on bug 4144 (not a good long term fix but fine for 0.6) allCollection.addIndex('__adhoc__', 'numeric') events = EventStamp.getCollection(view) eventComparator = EventComparator.update(parcel, 'eventComparator') EventStamp.addIndex(events, 'effectiveStart', 'method', method=(eventComparator, 'cmpStartTime'), monitor=(EventStamp.startTime, EventStamp.allDay, EventStamp.anyTime), kind=ContentItem.getKind(view)) EventStamp.addIndex(events, 'effectiveEnd', 'method', method=(eventComparator, 'cmpEndTime'), monitor=(EventStamp.startTime, EventStamp.allDay, EventStamp.anyTime, EventStamp.duration), kind=ContentItem.getKind(view)) # floatingEvents need to be reindexed in effectiveStart and effectiveEnd # when the floating timezone changes filterAttributes = [entry[0] for entry in _FILTER_ATTRIBUTES] floatingEvents = FilteredCollection.update( parcel, 'floatingEvents', source=events, filterMethod=(FloatingEventFilter(None, parcel), 'isFloatingEvent'), filterAttributes=filterAttributes) floatingEvents.addIndex('__adhoc__', 'numeric') # UTCEvents need to be reindexed in effectiveStartNoTZ and effectiveEndNoTZ # when the floating timezone changes, because UTC events are treated # specially UTCEvents = FilteredCollection.update(parcel, 'UTCEvents', source=events, filterMethod=(UTCEventFilter( None, parcel), 'isUTCEvent'), filterAttributes=filterAttributes) UTCEvents.addIndex('__adhoc__', 'numeric') longEvents = FilteredCollection.update( parcel, 'longEvents', source=events, filterMethod=(LongEventFilter(None, parcel), 'isLongEvent'), filterAttributes=[EventStamp.duration.name]) longEvents.addIndex('effectiveStart', 'subindex', superindex=(events, events.__collection__, 'effectiveStart')) longEvents.addIndex('effectiveEnd', 'subindex', superindex=(events, events.__collection__, 'effectiveEnd')) filterAttributes = (EventStamp.rruleset.name, EventStamp.occurrences.name) masterFilter = "view.hasTrueValues(uuid, '%s', '%s')" % filterAttributes nonMasterFilter = "not " + masterFilter masterEvents = FilteredCollection.update( parcel, 'masterEvents', source=events, filterExpression=masterFilter, filterAttributes=list(filterAttributes)) nonMasterEvents = FilteredCollection.update( parcel, 'nonMasterEvents', source=events, filterExpression=nonMasterFilter, filterAttributes=list(filterAttributes)) MasterEventWatcher.update(parcel, 'masterEventWatcher', targetCollection=masterEvents) EventStamp.addIndex(masterEvents, "recurrenceEnd", 'method', method=(eventComparator, 'cmpRecurEnd'), monitor=(EventStamp.recurrenceEnd, )) EventStamp.addIndex(masterEvents, 'effectiveStart', 'subindex', superindex=(events, events.__collection__, 'effectiveStart')) locations = KindCollection.update(parcel, 'locations', kind=Location.getKind(view), recursive=True) locations.addIndex('locationName', 'value', attribute='displayName', nodefer=True) mailCollection = mail.MailStamp.getCollection(view) kind = mail.EmailAddress.getKind(view) emailAddressCollection = \ KindCollection.update(parcel, 'emailAddressCollection', kind=kind, recursive=True) emailComparator = EmailComparator.update(parcel, 'emailComparator') emailAddressCollection.addIndex('emailAddress', 'method', method=(emailComparator, 'cmpAddress'), monitor='emailAddress', nodefer=True) emailAddressCollection.addIndex('fullName', 'method', method=(emailComparator, 'cmpFullName'), monitor='fullName', nodefer=True) emailAddressCollection.addIndex('both', 'method', method=(emailComparator, 'cmpBoth'), monitor=('emailAddress', 'fullName'), nodefer=True, kind=kind) # Contains all current me addresses (that is, referenced by an account) currentMeEmailAddresses = ListCollection.update(parcel, 'currentMeEmailAddresses') currentMeEmailAddresses.addIndex('emailAddress', 'method', method=(emailComparator, 'cmpAddress'), monitor='emailAddress') # Contains all current and former me addresses meEmailAddressCollection = ListCollection.update( parcel, 'meEmailAddressCollection') meEmailAddressCollection.addIndex('emailAddress', 'method', method=(emailComparator, 'cmpAddress'), monitor='emailAddress') inSource = ToMeFilter.makeCollection(parcel, 'inSource', mailCollection) # this index must be added to shield from the duplicate # source (mailCollection) that is going to be in mine inSource.addIndex('__adhoc__', 'numeric') # The "In" collection inCollection = SmartCollection.update(parcel, 'inCollection', displayName=_(u"In"), source=inSource, trash=trashCollection, visible=True) mine.addSource(inCollection) outSource = FromMeFilter.makeCollection(parcel, 'outSource', mailCollection) # this index must be added to shield from the duplicate # source (mailCollection) that is going to be in mine outSource.addIndex('__adhoc__', 'numeric') # The "Out" collection outCollection = SmartCollection.update( parcel, 'outCollection', displayName=_(u"Out"), visible=True, source=outSource, trash=trashCollection, ) mine.addSource(outCollection) allEventsCollection = IntersectionCollection.update( parcel, 'allEventsCollection', sources=[allCollection, events]) searchResultsUnfiltered = SmartCollection.update( parcel, 'searchResultsUnfiltered', displayName=messages.UNTITLED) searchResults = DifferenceCollection.update( parcel, 'searchResults', sources=[searchResultsUnfiltered, masterEvents], displayName=messages.UNTITLED) TriageStatusReminder.update(parcel, 'triageStatusReminder') startup.Startup.update(parcel, "installWatchers", invoke=__name__ + ".installWatchers") tzInstallParcel(parcel)
def makeChange(self, item, change): # easy for set, not too bad for stamp addition, del is maybe # tricky, and add/remove require duplicating reflists event = EventStamp(item) changeType = change[1] if changeType == 'set': attr = change[2] self._updateEdited(item for item in event.modifications if not item.hasModifiedAttribute(attr)) event.changeAll(attr, change[3]) return attr elif changeType == 'addStamp': self._updateEdited(item for item in event.modifications if not stamping.has_stamp(item, change[2])) event.addStampToAll(change[2].stamp_type) return stamping.Stamp.stamp_types.name elif changeType == 'removeStamp': self._updateEdited(item for item in event.modifications if stamping.has_stamp(item, change[2])) event.removeStampFromAll(change[2].stamp_type) return stamping.Stamp.stamp_types.name elif changeType in ('add', 'remove', 'append'): attr = change[0].descriptor.name self._updateEdited(item for item in event.modifications if not item.hasModifiedAttribute(attr)) masterItem = event.getMaster().itsItem attrName, newValue = _multiChange(masterItem, change) with EventStamp(masterItem).noRecurrenceChanges(): setattr(masterItem, attrName, newValue) return attrName elif (changeType == 'delete' and change[0].descriptor.name == EventStamp.rruleset.name): event.removeRecurrence() return EventStamp.rruleset.name else: assert False