示例#1
0
 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)
示例#2
0
 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)
示例#3
0
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
示例#4
0
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
示例#6
0
    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))
示例#7
0
    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))
示例#9
0
 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)
示例#10
0
    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))
示例#12
0
 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))
示例#13
0
    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)
示例#14
0
 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)
示例#15
0
 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)
示例#16
0
 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)
示例#17
0
 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))
示例#18
0
 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)
示例#19
0
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
示例#20
0
    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})
示例#22
0
    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
示例#23
0
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
示例#25
0
 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()
示例#26
0
    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
示例#27
0
    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
示例#28
0
    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})
示例#29
0
    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 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))
示例#31
0
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
示例#32
0
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
示例#33
0
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 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()
示例#36
0
 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))
示例#37
0
    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'))
示例#38
0
 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'))
示例#39
0
 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'
示例#40
0
 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 __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 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'
示例#43
0
    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)
示例#44
0
    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))
示例#45
0
    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()
示例#48
0
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()
示例#49
0
 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)
示例#50
0
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)
示例#51
0
    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))
示例#52
0
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()
示例#53
0
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
示例#54
0
 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()
示例#55
0
    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))