def testSimple(self): self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060213T000000", "SUMMARY:A ToDo", "UID:4A7707B5-6E87-49ED-8871-7A0BD37F0349", "SEQUENCE:2", "DTSTAMP:20060227T163229Z", "END:VTODO", "END:VCALENDAR" ) self.failUnlessEqual(1, len(self.items)) item = self.items[0] self.failIf(pim.has_stamp(item, pim.TaskStamp)) self.failUnless(pim.has_stamp(item, pim.EventStamp)) self.failUnlessEqual(item.displayName, u"A ToDo") self.failUnlessEqual(item.triageStatus, pim.TriageEnum.now) self.failIf(item.needsReply)
def testDueDate(self): self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060213T000000", "SUMMARY:Deferred ToDo", "STATUS:CANCELLED", "UID:B75093D9-432F-4684-8DB7-744AAB7F747B", "SEQUENCE:4", "DTSTAMP:20060227T203912Z", "DUE;VALUE=DATE:20070121", "END:VTODO", "END:VCALENDAR" ) self.failUnlessEqual(1, len(self.items)) item = self.items[0] self.failIf(pim.has_stamp(item, pim.TaskStamp)) self.failUnless(pim.has_stamp(item, pim.EventStamp)) self.failUnlessEqual(item.displayName, u"Deferred ToDo") self.failUnlessEqual(pim.EventStamp(item).startTime.date(), datetime.date(2007, 1, 21)) self.failUnlessEqual(item.triageStatus, pim.TriageEnum.later)
def outbound(peers, item, filter=None, debug=False): rv = peers[0].itsView if filter is None: filter = lambda rs: rs else: filter = filter.sync_filter # At some point, which serializer and translator to use should be # configurable serializer = eimml.EIMMLSerializer # only using class methods trans = translator.SharingTranslator(rv) rsInternal = {} items = [item] version = str(item.itsVersion) if pim.has_stamp(item, pim.EventStamp): for mod in pim.EventStamp(item).modifications or []: # modifications that have been changed purely by # auto-triage shouldn't have recordsets created for them if not (isinstance(mod, pim.Note) and pim.EventStamp(mod).isTriageOnlyModification() and pim.EventStamp(mod).simpleAutoTriage() == mod._triageStatus): items.append(mod) for item in items: alias = trans.getAliasForItem(item) rsInternal[alias] = filter(eim.RecordSet(trans.exportItem(item))) if not pim.has_stamp(item, shares.SharedItem): shares.SharedItem(item).add() shared = shares.SharedItem(item) # Abort if pending conflicts if shared.conflictingStates: raise errors.ConflictsPending(_(u"Conflicts pending.")) for peer in peers: state = shared.getPeerState(peer) # Set agreed state to what we have locally state.agreed = rsInternal[alias] # Repository identifier: if rv.repository is not None: repoId = rv.repository.getSchemaInfo()[0].str16() else: repoId = "" text = serializer.serialize(rv, rsInternal, rootName="item", repo=repoId, version=version) return text
def outbound(peers, item, filter=None, debug=False): rv = peers[0].itsView if filter is None: filter = lambda rs: rs else: filter = filter.sync_filter # At some point, which serializer and translator to use should be # configurable serializer = eimml.EIMMLSerializer # only using class methods trans = translator.SharingTranslator(rv) rsInternal = { } items = [item] version = str(item.itsVersion) if pim.has_stamp(item, pim.EventStamp): for mod in pim.EventStamp(item).modifications or []: # modifications that have been changed purely by # auto-triage shouldn't have recordsets created for them if not (isinstance(mod, pim.Note) and pim.EventStamp(mod).isTriageOnlyModification() and pim.EventStamp(mod).simpleAutoTriage() == mod._triageStatus): items.append(mod) for item in items: alias = trans.getAliasForItem(item) rsInternal[alias] = filter(eim.RecordSet(trans.exportItem(item))) if not pim.has_stamp(item, shares.SharedItem): shares.SharedItem(item).add() shared = shares.SharedItem(item) # Abort if pending conflicts if shared.conflictingStates: raise errors.ConflictsPending(_(u"Conflicts pending.")) for peer in peers: state = shared.getPeerState(peer) # Set agreed state to what we have locally state.agreed = rsInternal[alias] # Repository identifier: if rv.repository is not None: repoId = rv.repository.getSchemaInfo()[0].str16() else: repoId = "" text = serializer.serialize(rv, rsInternal, rootName="item", repo=repoId, version=version) return text
def deserialize(rv, peer, text, translator, serializer, filter=None, debug=False): items = [] trans = translator(rv) inbound, extra = serializer.deserialize(rv, text) for alias, rsExternal in inbound.items(): uuid = trans.getUUIDForAlias(alias) if uuid: item = rv.findUUID(uuid) else: item = None if rsExternal is not None: if item is not None: # Item already exists if not pim.has_stamp(item, shares.SharedItem): shares.SharedItem(item).add() shared = shares.SharedItem(item) state = shared.getPeerState(peer) rsInternal= eim.RecordSet(trans.exportItem(item)) else: # Item doesn't exist yet state = shares.State(itsView=rv, peer=peer) rsInternal = eim.RecordSet() dSend, dApply, pending = state.merge(rsInternal, rsExternal, isDiff=False, filter=filter, debug=debug) state.updateConflicts(item) if dApply: logger.debug("Applying: %s %s", uuid, dApply) trans.startImport() trans.importRecords(dApply) trans.finishImport() uuid = trans.getUUIDForAlias(alias) if uuid: item = rv.findUUID(uuid) else: item = None if item is not None and item.isLive(): if not pim.has_stamp(item, shares.SharedItem): shares.SharedItem(item).add() shares.SharedItem(item).addPeerState(state, peer) items.append(item) return items
def testStamp_THIS(self): self.event.rruleset = self.rruleset third = self.event.getFirstOccurrence().getNextOccurrence().getNextOccurrence() pim.TaskStamp(pim.CHANGE_THIS(third)).add() self.failUnless(third.modificationFor is not None) self.failUnless(pim.has_stamp(third, pim.TaskStamp)) self.failIf(pim.has_stamp(self.event, pim.TaskStamp)) self.failIf(pim.has_stamp(self.event.getFirstOccurrence(), pim.TaskStamp))
def testStamp_THISANDFUTURE(self): self.event.rruleset = self.rruleset third = self.event.getFirstOccurrence().getNextOccurrence().getNextOccurrence() pim.TaskStamp(pim.CHANGE_FUTURE(third)).add() self.failIfEqual(third.getMaster(), self.event.getMaster()) self.failUnless(pim.has_stamp(third, pim.TaskStamp)) self.failUnless(pim.has_stamp(third.getNextOccurrence(), pim.TaskStamp)) self.failIf(pim.has_stamp(self.event, pim.TaskStamp)) self.failIf(pim.has_stamp(self.event.getFirstOccurrence(), pim.TaskStamp))
def testStamp_THIS(self): self.event.rruleset = self.rruleset third = self.event.getFirstOccurrence().getNextOccurrence( ).getNextOccurrence() pim.TaskStamp(pim.CHANGE_THIS(third)).add() self.failUnless(third.modificationFor is not None) self.failUnless(pim.has_stamp(third, pim.TaskStamp)) self.failIf(pim.has_stamp(self.event, pim.TaskStamp)) self.failIf( pim.has_stamp(self.event.getFirstOccurrence(), pim.TaskStamp))
def testUpdate(self): self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060214T000000", "SUMMARY:To Do (Initial)", "UID:ED5CAC89-4BEE-4903-8DE8-1AEF6FC1D431", "DTSTAMP:20060227T233332Z", "SEQUENCE:11", "DESCRIPTION:How will I ever get this done?", "END:VTODO", "END:VCALENDAR", ) self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060214T000000", "SUMMARY:To Do (Initial)", "X-OSAF-STARRED:TRUE", "UID:ED5CAC89-4BEE-4903-8DE8-1AEF6FC1D431", "DTSTAMP:20060227T233332Z", "SEQUENCE:12", "DESCRIPTION:Phew!", "STATUS:COMPLETED", "DUE;VALUE=DATE:20060327", "END:VTODO", "END:VCALENDAR", ) self.failUnlessEqual(1, len(self.items)) item = self.items[0] task = pim.TaskStamp(item) self.failUnless(pim.has_stamp(task, pim.TaskStamp)) self.failUnless(pim.has_stamp(task, pim.EventStamp)) self.failUnlessEqual(item.body, u"Phew!") self.failUnlessEqual(pim.EventStamp(task).startTime.date(), datetime.date(2006, 3, 27)) # the update causes a (spurious, but such is life) conflict self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.now) # resolve the conflicts for c in sharing.getConflicts(task.itsItem): c.apply() self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.done)
def testUpdate(self): self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060214T000000", "SUMMARY:To Do (Initial)", "UID:ED5CAC89-4BEE-4903-8DE8-1AEF6FC1D431", "DTSTAMP:20060227T233332Z", "SEQUENCE:11", "DESCRIPTION:How will I ever get this done?", "END:VTODO", "END:VCALENDAR", ) self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060214T000000", "SUMMARY:To Do (Initial)", "X-OSAF-STARRED:TRUE", "UID:ED5CAC89-4BEE-4903-8DE8-1AEF6FC1D431", "DTSTAMP:20060227T233332Z", "SEQUENCE:12", "DESCRIPTION:Phew!", "STATUS:COMPLETED", "DUE;VALUE=DATE:20060327", "END:VTODO", "END:VCALENDAR", ) self.failUnlessEqual(1, len(self.items)) item = self.items[0] task = pim.TaskStamp(item) self.failUnless(pim.has_stamp(task, pim.TaskStamp)) self.failUnless(pim.has_stamp(task, pim.EventStamp)) self.failUnlessEqual(item.body, u"Phew!") self.failUnlessEqual( pim.EventStamp(task).startTime.date(), datetime.date(2006, 3, 27)) # the update causes a (spurious, but such is life) conflict self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.now) # resolve the conflicts for c in sharing.getConflicts(task.itsItem): c.apply() self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.done)
def testStamp_THISANDFUTURE(self): self.event.rruleset = self.rruleset third = self.event.getFirstOccurrence().getNextOccurrence( ).getNextOccurrence() pim.TaskStamp(pim.CHANGE_FUTURE(third)).add() self.failIfEqual(third.getMaster(), self.event.getMaster()) self.failUnless(pim.has_stamp(third, pim.TaskStamp)) self.failUnless(pim.has_stamp(third.getNextOccurrence(), pim.TaskStamp)) self.failIf(pim.has_stamp(self.event, pim.TaskStamp)) self.failIf( pim.has_stamp(self.event.getFirstOccurrence(), pim.TaskStamp))
def testCreateItems(self): #test that an item gets created with the correct properties paramDict = { 'choicePercentFYI': u'0', 'choicePercentTentative': u'0', 'choicePercentMonthly': u'0', 'textCtrlNoteSourceFilePath': u'itemGenNotes.txt', 'textCtrlAlarmSpec': u'b0.10:100', 'choicePercentNonRecurring': u'100', 'choicePercentNow': u'100', 'choicePercentAtTime': u'0', 'choicePercentDone': u'0', 'choicePercentAnyTime': u'0', 'choicePercentEvent': u'100', 'textCtrlCollectionFileName': u'itemGenCollections.txt', 'textCtrlTimeOfDay': u'8-8:100, 19-23:50', 'choicePercentDaily': u'0', 'textCtrlTitleSourceFile': u'itemGenTitles.txt', 'textCtrlToFile': u'', 'textCtrlRecurrenceEndDates': u'10:50, 0:50', 'choicePercentTask': u'100', 'textCtrlCCFileName': u'', 'textCtrlEndDate': u'2008,1,2', 'choicePercentConfirmed': u'100', 'textCtrlTotalItems': u'1', 'textCtrlToSpec': u'1:100', 'textCtrlDuration': u'2.0:100', 'choicePercentLater': u'0', 'textCtrlStartDate': u'2008,1,1', 'textCtrlCollectionCount': u'1', 'textCtrlCollectionMembership': u'1:100', 'choicePercentYearly': u'0', 'choicePercentAllDay': u'0', 'textCtrlBCCSpec': u'0:100', 'textCtrlCCSpec': u'0:100', 'choicePercentUnassignedStatus': u'0', 'choicePercentDuration': u'100', 'textCtrlLocationSourceFilePath': u'itemGenLocations.txt', 'choicePercentWeekly': u'0', 'textCtrlBCCFileName': u'', 'choicePercentMail': u'100', 'choicePercentBiWeekly': u'0' } #create a single item with all stamps testItem = createItems.createItems(paramDict)[0] # test it has all stamps self.failUnless(pim.has_stamp(testItem, pim.mail.MailStamp)) self.failUnless(pim.has_stamp(testItem, pim.TaskStamp)) self.failUnless(pim.has_stamp(testItem, Calendar.EventStamp))
def testStarred(self): self.runImport("BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "X-OSAF-STARRED:TRUE", "DTSTART:20060213T000000", "SUMMARY:A Starred Note", "UID:4A7707B5-6E87-49ED-8871-7A0BD37F0355", "SEQUENCE:26", "DTSTAMP:20080227T163229Z", "END:VTODO", "END:VCALENDAR") item = self.items[0] task = pim.TaskStamp(item) self.failUnless(pim.has_stamp(task, pim.TaskStamp)) self.failUnless(pim.has_stamp(task, pim.EventStamp)) self.failUnlessEqual(item.displayName, u"A Starred Note") self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.now) self.failIf(task.itsItem.needsReply)
def testInProcess(self): self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060213T000000", "SUMMARY:I'm busy!", "DTSTAMP:20060227T203912Z", "UID:48F6177A-3EEF-423B-ABBA-0B506189FD29", "SEQUENCE:1", "STATUS:IN-PROCESS", "END:VTODO", "END:VCALENDAR" ) self.failUnlessEqual(1, len(self.items)) item = self.items[0] self.failIf(pim.has_stamp(item, pim.TaskStamp)) self.failUnlessEqual(item.displayName, u"I'm busy!") self.failUnlessEqual(item.triageStatus, pim.TriageEnum.now) self.failIf(item.needsReply)
def testNeedsAction(self): self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "X-OSAF-STARRED:TRUE", "DTSTART:20060213T000000", "SUMMARY:Really\, do this right away", "DTSTAMP:20060227T203912Z", "UID:1E192668-99F7-4FA1-B1F7-70A05FC8E357", "SEQUENCE:6", "STATUS:NEEDS-ACTION", "END:VTODO", "END:VCALENDAR" ) self.failUnlessEqual(1, len(self.items)) item = self.items[0] task = pim.TaskStamp(item) self.failUnless(pim.has_stamp(task, pim.TaskStamp)) self.failUnlessEqual(task.summary, u"Really, do this right away") self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.now) self.failUnless(task.itsItem.needsReply)
def testStatus(self): self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060213T000000", "SUMMARY:ToDone", "DTSTAMP:20060227T203912Z", "UID:DD5D311A-F73F-4611-B463-A5766A1BAE5F", "SEQUENCE:6", "STATUS:COMPLETED", "END:VTODO", "END:VCALENDAR" ) self.failUnlessEqual(1, len(self.items)) item = self.items[0] task = pim.TaskStamp(item) self.failUnless(pim.has_stamp(task, pim.TaskStamp)) self.failUnlessEqual(task.summary, u"ToDone") self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.done)
def testCompleted(self): self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060213T000000", "SUMMARY:ToDoneAndWhen", "DTSTAMP:20060227T203912Z", "UID:DD5D311A-F73F-4619-B463-A5766A1BAE5F", "SEQUENCE:6", "STATUS:COMPLETED", "COMPLETED:20060301T010000Z", "END:VTODO", "END:VCALENDAR" ) self.failUnlessEqual(1, len(self.items)) item = self.items[0] task = pim.TaskStamp(item) self.failIf(pim.has_stamp(task, pim.TaskStamp)) self.failUnlessEqual(task.summary, u"ToDoneAndWhen") self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.done) expectedTSC = datetime.datetime(2006, 3, 1, 1, 0, 0, 0, self.utc) self.failUnlessEqual(task.itsItem.triageStatusChanged, Triageable.makeTriageStatusChangedTime(self.view, expectedTSC))
def testDescription(self): self.runImport( "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "UID:2C41172C-6812-4848-A9BA-73A827B06E28", "SEQUENCE:7", "STATUS:COMPLETED", "SUMMARY:To Do", "X-OSAF-STARRED:true", "COMPLETED:20060227T080000Z", "DESCRIPTION:This is a very important TODO:\\n\\n\xe2\x80\xa2 Do one thing\\n\xe2\x80\xa2 Do somet", " hing else", "END:VTODO", "END:VCALENDAR" ) self.failUnlessEqual(1, len(self.items)) item = self.items[0] task = pim.TaskStamp(item) self.failUnless(pim.has_stamp(task, pim.TaskStamp)) self.failUnlessEqual(item.body, u"This is a very important TODO:\n\n\u2022 Do one thing\n\u2022 Do something else") self.failUnlessEqual(item.triageStatus, pim.TriageEnum.done)
def takeCollectionOnline(collection): rv = collection.itsView if pim.has_stamp(collection, shares.SharedItem): collection = shares.SharedItem(collection) for share in collection.shares: share.active = True takeOnline(rv) # take sharing layer online
def findShare(self, view, collection, repoId, peerId): account = self.findAccount(view, peerId) acl = collection.getACL('p2p', None) if acl is None or not acl.verify(account.user, Permissions.READ): raise AccessDeniedError for share in SharedItem(collection).shares: if isinstance(share, self.shareClass): if share.repoId is None: if (share.ackPending and share.contents is collection and share.conduit.account is account and share.conduit.peerId == peerId): share.repoId = repoId return share elif share.repoId == repoId: return share share = self.shareClass(itsView=view, account=view[self.client.account], repoId=repoId, peerId=peerId) share.contents = collection if not has_stamp(collection, SharedItem): SharedItem(collection).add() share.localVersion = view.itsVersion + 1 view.commit() return share
def onSendShareItemEvent(self, event): """ Send or share the selected items """ selectedItems = self.__getProxiedSelectedItems(event) if len(selectedItems) == 0: return # Make sure we have an outbound account; returns False if the user # cancels out and we don't. if not sharing.ensureAccountSetUp(self.itsView, outboundMail=True): return sendableItems = [ item for item in selectedItems if self.__getSendabilityOf(item) in ('send', 'update') ] assert list(selectedItems) == sendableItems for item in sendableItems: # For now, make sure we've got a 'from' string. # @@@ BJS: this'll go away when we change 'from' to an # account picker popup. if has_stamp(item, Mail.MailStamp): mailObject = Mail.MailStamp(item) #XXX this should raise an error instead of # adding the me address since that results # in the incorrect sender getting added # which can confuse user if unicode(mailObject.fromAddress).strip() == u'': mailObject.fromAddress = mailObject.getCurrentMeEmailAddress( ) Block.Block.postEventByNameWithSender('SendMail', {'item': item})
def findShare(self, view, collection, repoId, peerId): account = self.findAccount(view, peerId) acl = collection.getACL('p2p', None) if acl is None or not acl.verify(account.user, Permissions.READ): raise AccessDeniedError for share in SharedItem(collection).shares: if isinstance(share, self.shareClass): if share.repoId is None: if (share.ackPending and share.contents is collection and share.conduit.account is account and share.conduit.peerId == peerId): share.repoId = repoId return share elif share.repoId == repoId: return share share = self.shareClass( itsView=view, account=view[self.client.account], repoId=repoId, peerId=peerId ) share.contents = collection if not has_stamp(collection, SharedItem): SharedItem(collection).add() share.localVersion = view.itsVersion + 1 view.commit() return share
def getPeers(mailStamp): peers = mailStamp.getRecipients() # First, make sure we don't have peers with duplicate email addresses peerAddresses = set() filteredPeers = list() for peer in peers: address = getattr(peer, 'emailAddress', '') if address and address not in peerAddresses: # Note: shouldn't we also filter out "me" addresses? I guess it's # harmless not to since we ignore incoming EIMML messages that are # "from me". peerAddresses.add(address) filteredPeers.append(peer) peers = filteredPeers # Next, for each peer already associated with the item, if any of them have # email addresses which match the 'peers' list, there is a chance that the # new peer is actually an EmailAddress item with same address but different # name. We want to swap that peer out for the one already associated with # the item. item = mailStamp.itsItem view = item.itsView if has_stamp(item, SharedItem): shared = SharedItem(item) updatedPeers = list() # Build a set of email addresses already associated with this item associatedAddresses = set() addressMapping = {} for state in getattr(shared, "peerStates", []): peerUUID = shared.peerStates.getAlias(state) peer = view.findUUID(peerUUID) if peer is not None and getattr(peer, 'emailAddress', ''): associatedAddresses.add(peer.emailAddress) addressMapping[peer.emailAddress] = peer # Look for matches between already associated and new: for peer in peers: if peer.emailAddress in associatedAddresses: if shared.getPeerState(peer, create=False) is not None: # We have a perfect match updatedPeers.append(peer) else: # address matches, but wrong email address item; switch # to the already associated one updatedPeers.append(addressMapping[peer.emailAddress]) else: # No matching address; it's a new peer updatedPeers.append(peer) peers = updatedPeers return peers
def onFocusStampEventUpdateUI(self, event): selectedItems = self.__getSelectedItems() stampClass = event.classParameter enable = False states = set() for item in selectedItems: # we don't want to try to stamp non-Note content items # (e.g. Collections) enable = (isinstance(item, Note) and item.isAttributeModifiable('body')) if not enable: break # Collect the states of all the items, so that we can change all # the items if they're all in the same state. states.add(has_stamp(item, stampClass)) enable = enable and (len(states) == 1) event.arguments['Enable'] = enable # next() won't raise because len(status) is 1 # event.arguments['Check'] = enable and iter(states).next() if enable: sender = event.arguments['sender'] if iter(states).next(): event.arguments['Text'] = sender.toggleTitle else: event.arguments['Text'] = sender.title
def on_debug_CreateConflictEvent(self, event): selectedItems = self.__getSelectedItems() if len(selectedItems) > 0: for item in selectedItems: if not has_stamp(item, sharing.SharedItem): sharing.SharedItem(item).add() sharing.SharedItem(item).generateConflicts()
def onSendShareItemEventUpdateUI(self, event): """ Generically enable Send-ing. """ # default to a disabled "Send" with a send-arrow enabled = False label = messages.SEND bitmap = "ApplicationBarSend.png" selectedItems = self.__getSelectedItems() if len(selectedItems) > 0: # Collect the states of all the items, so that we can change the # label to "Sent" if they're all in that state. sendStates = set([ self.__getSendabilityOf(item) for item in selectedItems ]) if len(sendStates) == 1: result = sendStates.pop() if result == 'send': enabled = True elif result == 'update': enabled = True label = messages.UPDATE # use U-shaped Update bitmap bitmap = "ApplicationBarUpdate.png" elif result == 'sent': enabled = False label = messages.SENT if has_stamp(item, Mail.MailStamp): mailObject = Mail.MailStamp(item) if mailObject.itsItem.lastModification == Modification.updated: label = messages.UPDATED bitmap = "ApplicationBarUpdate.png" event.arguments['Enable'] = enabled event.arguments['Text'] = label event.arguments['Bitmap'] = bitmap
def onSendShareItemEvent(self, event): """ Send or share the selected items """ selectedItems = self.__getProxiedSelectedItems(event) if len(selectedItems) == 0: return # Make sure we have an outbound account; returns False if the user # cancels out and we don't. if not sharing.ensureAccountSetUp(self.itsView, outboundMail=True): return sendableItems = [ item for item in selectedItems if self.__getSendabilityOf(item) in ('send', 'update') ] assert list(selectedItems) == sendableItems for item in sendableItems: # For now, make sure we've got a 'from' string. # @@@ BJS: this'll go away when we change 'from' to an # account picker popup. if has_stamp(item, Mail.MailStamp): mailObject = Mail.MailStamp(item) #XXX this should raise an error instead of # adding the me address since that results # in the incorrect sender getting added # which can confuse user if unicode(mailObject.fromAddress).strip() == u'': mailObject.fromAddress = mailObject.getCurrentMeEmailAddress() Block.Block.postEventByNameWithSender('SendMail', {'item': item})
def testStamp_ALL(self): self.event.rruleset = self.rruleset ruleEnd = self.event.startTime + datetime.timedelta(days=10) self.event.rruleset.rrules.first().until = ruleEnd occurrences = [self.event.getFirstOccurrence()] for i in xrange(10): occurrences.append(occurrences[-1].getNextOccurrence()) pim.TaskStamp(pim.CHANGE_ALL(occurrences[0])).add() for event in occurrences: self.failUnlessEqual(event.getMaster(), self.event) for item in self.event.occurrences: self.failUnless(pim.has_stamp(item, pim.TaskStamp)) self.failUnless(pim.has_stamp(self.event, pim.TaskStamp))
def isReadOnly(item): """ Return C{True} iff participating in a read-only share. """ item = getattr(item, 'inheritFrom', item) # If we're not stamped, we're not shared if not pim.has_stamp(item, shares.SharedItem): return False item = shares.SharedItem(item) sharedIn = getattr(item, 'sharedIn', []) itemShares = getattr(item, 'shares', []) # We might have been shared, see if we still are if not sharedIn and not itemShares: # not in any shares return False # For each share we're in, if *any* are writable, isReadOnly is False for share in chain(sharedIn, itemShares): if share.mode not in ('put', 'both'): return True return False
def getShare(collection): """ Return the Share item (if any) associated with an ContentCollection. @param collection: an ContentCollection @type collection: ContentCollection @return: A Share item, or None """ # First, see if there is a 'main' share for this collection. If not, # return the first "non-hidden" share for this collection -- see isShared() # method for further details. if pim.has_stamp(collection, shares.SharedItem): collection = shares.SharedItem(collection) if hasattr(collection, 'shares') and collection.shares: share = collection.shares.getByAlias('main') if share is not None: return share for share in collection.shares: if share.hidden == False: return share return None
def onSendShareItemEventUpdateUI(self, event): """ Generically enable Send-ing. """ # default to a disabled "Send" with a send-arrow enabled = False label = messages.SEND bitmap = "ApplicationBarSend.png" selectedItems = self.__getSelectedItems() if len(selectedItems) > 0: # Collect the states of all the items, so that we can change the # label to "Sent" if they're all in that state. sendStates = set( [self.__getSendabilityOf(item) for item in selectedItems]) if len(sendStates) == 1: result = sendStates.pop() if result == 'send': enabled = True elif result == 'update': enabled = True label = messages.UPDATE # use U-shaped Update bitmap bitmap = "ApplicationBarUpdate.png" elif result == 'sent': enabled = False label = messages.SENT if has_stamp(item, Mail.MailStamp): mailObject = Mail.MailStamp(item) if mailObject.itsItem.lastModification == Modification.updated: label = messages.UPDATED bitmap = "ApplicationBarUpdate.png" event.arguments['Enable'] = enabled event.arguments['Text'] = label event.arguments['Bitmap'] = bitmap
def testCreateItems(self): #test that an item gets created with the correct properties paramDict = {'choicePercentFYI': u'0', 'choicePercentTentative': u'0', 'choicePercentMonthly': u'0', 'textCtrlNoteSourceFilePath': u'itemGenNotes.txt', 'textCtrlAlarmSpec': u'b0.10:100', 'choicePercentNonRecurring': u'100', 'choicePercentNow': u'100', 'choicePercentAtTime': u'0', 'choicePercentDone': u'0', 'choicePercentAnyTime': u'0', 'choicePercentEvent': u'100', 'textCtrlCollectionFileName': u'itemGenCollections.txt', 'textCtrlTimeOfDay': u'8-8:100, 19-23:50', 'choicePercentDaily': u'0', 'textCtrlTitleSourceFile': u'itemGenTitles.txt', 'textCtrlToFile': u'', 'textCtrlRecurrenceEndDates': u'10:50, 0:50', 'choicePercentTask': u'100', 'textCtrlCCFileName': u'', 'textCtrlEndDate': u'2008,1,2', 'choicePercentConfirmed': u'100', 'textCtrlTotalItems': u'1', 'textCtrlToSpec': u'1:100', 'textCtrlDuration': u'2.0:100', 'choicePercentLater': u'0', 'textCtrlStartDate': u'2008,1,1', 'textCtrlCollectionCount': u'1', 'textCtrlCollectionMembership':u'1:100', 'choicePercentYearly': u'0', 'choicePercentAllDay': u'0', 'textCtrlBCCSpec': u'0:100', 'textCtrlCCSpec': u'0:100', 'choicePercentUnassignedStatus': u'0', 'choicePercentDuration': u'100', 'textCtrlLocationSourceFilePath': u'itemGenLocations.txt', 'choicePercentWeekly': u'0', 'textCtrlBCCFileName': u'', 'choicePercentMail': u'100', 'choicePercentBiWeekly': u'0'} #create a single item with all stamps testItem = createItems.createItems(paramDict)[0] # test it has all stamps self.failUnless(pim.has_stamp(testItem, pim.mail.MailStamp)) self.failUnless(pim.has_stamp(testItem, pim.TaskStamp)) self.failUnless(pim.has_stamp(testItem, Calendar.EventStamp))
def testSimple(self): item, vobj = self.getExportedTodoComponent(displayName=u'Important') self.failUnlessEqual(vobj.name.lower(), 'vtodo') self.failUnless(pim.has_stamp(item, pim.TaskStamp)) self.failUnlessEqual( vobj.getChildValue('x_osaf_starred').lower(), 'true') self.failUnlessEqual(u'Important', vobj.getChildValue('summary'))
def testSimple(self): item, vobj = self.getExportedTodoComponent(displayName=u'Important') self.failUnlessEqual(vobj.name.lower(), 'vtodo') self.failUnless(pim.has_stamp(item, pim.TaskStamp)) self.failUnlessEqual(vobj.getChildValue('x_osaf_starred').lower(), 'true') self.failUnlessEqual(u'Important', vobj.getChildValue('summary'))
def CanReplyOrForward(self, selectedItem): # We used to test for whether the message had ever been # received by the mail service ("in", sort of), but Mimi # thinks outgoing messages should be replyable too. # return has_stamp(selectedItem, Mail.MailStamp) and \ # Mail.MailStamp(selectedItem).viaMailService return has_stamp(selectedItem, Mail.MailStamp) and \ Mail.MailStamp(selectedItem).getSendability() != 'not'
def __getSendabilityOf(self, item): """ Return the sendable state of this item """ assert item is not None item = getattr(item, 'proxiedItem', item) if has_stamp(item, Mail.MailStamp): return Mail.MailStamp(item).getSendability() else: return 'not'
def testSimple(self): self.runImport("BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060213T000000", "SUMMARY:A ToDo", "UID:4A7707B5-6E87-49ED-8871-7A0BD37F0349", "SEQUENCE:2", "DTSTAMP:20060227T163229Z", "END:VTODO", "END:VCALENDAR") self.failUnlessEqual(1, len(self.items)) item = self.items[0] self.failIf(pim.has_stamp(item, pim.TaskStamp)) self.failUnless(pim.has_stamp(item, pim.EventStamp)) self.failUnlessEqual(item.displayName, u"A ToDo") self.failUnlessEqual(item.triageStatus, pim.TriageEnum.now) self.failIf(item.needsReply)
def testUnstampEvent_ALL(self): self.event.rruleset = self.rruleset third = self.event.getFirstOccurrence().getNextOccurrence().getNextOccurrence() pim.CHANGE_ALL(third).remove() self.failUnless(pim.isDead(third.itsItem)) self.failIf(pim.isDead(self.event.itsItem)) self.failIf(pim.has_stamp(self.event, pim.EventStamp))
def testDueDate(self): self.runImport("BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN", "METHOD:PUBLISH", "BEGIN:VTODO", "DTSTART:20060213T000000", "SUMMARY:Deferred ToDo", "STATUS:CANCELLED", "UID:B75093D9-432F-4684-8DB7-744AAB7F747B", "SEQUENCE:4", "DTSTAMP:20060227T203912Z", "DUE;VALUE=DATE:20070121", "END:VTODO", "END:VCALENDAR") self.failUnlessEqual(1, len(self.items)) item = self.items[0] self.failIf(pim.has_stamp(item, pim.TaskStamp)) self.failUnless(pim.has_stamp(item, pim.EventStamp)) self.failUnlessEqual(item.displayName, u"Deferred ToDo") self.failUnlessEqual( pim.EventStamp(item).startTime.date(), datetime.date(2007, 1, 21)) self.failUnlessEqual(item.triageStatus, pim.TriageEnum.later)
def testUnstampEvent_ALL(self): self.event.rruleset = self.rruleset third = self.event.getFirstOccurrence().getNextOccurrence( ).getNextOccurrence() pim.CHANGE_ALL(third).remove() self.failUnless(pim.isDead(third.itsItem)) self.failIf(pim.isDead(self.event.itsItem)) self.failIf(pim.has_stamp(self.event, pim.EventStamp))
def SetAttributeValue(self, item, attributeName, value): isStamped = pim.has_stamp(item, pim.TaskStamp) if isStamped != (value == self._getStateName(True)): # Stamp or unstamp the item if isinstance(item, pim.TaskStamp.targetType()): stampedObject = pim.TaskStamp(item) if isStamped: stampedObject.remove() else: stampedObject.add()
def parseTaskInfo(mailStamp): assert isinstance(mailStamp, MailStamp) if has_stamp(mailStamp.itsItem, TaskStamp): # The message has already been stamped as # a task return taskStamp = TaskStamp(mailStamp.itsItem) taskStamp.add()
def addSharedItem(self, item): """ Add an item to the share's sharedIn refcoll, stamping if necessary """ sharedItem = SharedItem(item) if not pim.has_stamp(item, SharedItem): logger.info("Stamping item %s as SharedItem", item.itsUUID) sharedItem.add() if item not in self.items: logger.info("Adding item %s to sharedIn", item.itsUUID) self.items.add(item)
def unsubscribe(collection): if has_stamp(collection, SharedItem): # Make all CosmoAccounts ignore this collection when it comes to # auto-restore: CosmoAccount.ignoreCollection(collection) collection = SharedItem(collection) for share in collection.shares: deleteShare(share)
def testHolidays(self): holidays = self.getCollection(u"U.S. Holidays") self.failUnless(pim.has_stamp(holidays, sharing.SharedItem)) self.failUnlessEqual(len(list(sharing.SharedItem(holidays).shares)), 1) share = sharing.SharedItem(holidays).shares.first() self.failUnless(share.established) self.failUnless(isinstance(share.conduit, sharing.WebDAVMonolithicRecordSetConduit))
def isCollectionOnline(collection): """ Return the active state of the first share, if any """ if not isOnline(collection.itsView): return False if pim.has_stamp(collection, shares.SharedItem): collection = shares.SharedItem(collection) for share in collection.shares: return share.active return False
def removeSharedItem(self, item): """ Remove an item from the share's sharedIn refcoll, unstamping if the last share for this item """ if not pim.has_stamp(item, SharedItem): return sharedItem = SharedItem(item) logger.info("Removing item %s from sharedIn", item.itsUUID) self.items.remove(item) if not sharedItem.sharedIn: logger.info("Unstamping item %s as SharedItem", item.itsUUID) sharedItem.remove()
def testHolidays(self): holidays = self.getCollection(u"U.S. Holidays") self.failUnless(pim.has_stamp(holidays, sharing.SharedItem)) self.failUnlessEqual(len(list(sharing.SharedItem(holidays).shares)), 1) share = sharing.SharedItem(holidays).shares.first() self.failUnless(share.established) self.failUnless( isinstance(share.conduit, sharing.WebDAVMonolithicRecordSetConduit))