Example #1
0
    def _result_sync(self, view, uid, message, fromAddress):

        try:
            view.refresh(None, None, False)

            repoId = UUID(message['X-chandler-p2p-from'])
            uuid, version = message['X-chandler-p2p-item'].split('-')
            uuid = UUID(uuid)
            version = int(version)
            name = message['X-chandler-p2p-name']
            self.client.output("processing '%s'" %(name))

            collection = view.find(uuid)
            if collection is None:
                collection = pim.SmartCollection(itsView=view, _uuid=uuid,
                                                 displayName=name)
                schema.ns("osaf.app", view).sidebarCollection.add(collection)

                # for now, grant READ to everyone
                acl = ACL()
                acl.append(ACE(schema.ns('p2p', view).all.itsUUID,
                               Permissions.READ))
                collection.setACL(acl, 'p2p')
                isNew = True
            else:
                isNew = False

            share = self.findShare(view, collection, repoId, fromAddress)
            format = share.format

            if isNew:
                share.localVersion = view.itsVersion + 1
            else:
                changes = self.computeChanges(view, share.localVersion,
                                              collection, share)
                if not changes:
                    share.localVersion = view.itsVersion + 1

            payload = message.get_payload(1).get_payload()
            dom = ElementTreeDOM()
            input = StringIO(decompress(b64decode(payload)))
            data = ElementTree(file=input).getroot()
            input.close()

            share.remoteVersion = version
            view.deferDelete()

            for itemElement in dom.iterElements(data):
                attributes = dom.getAttributes(itemElement)
                status = attributes.get('status')
                if status == 'deleted':
                    item = view.findUUID(attributes['uuid'])
                    if item is not None:
                        item.delete()
                else:
                    child = dom.getFirstChildElement(itemElement)
                    if child is not None:
                        item = format.importProcess(dom, child)
                    else:
                        item = view.findUUID(attributes['uuid'])

                    if status == 'member':
                        collection.inclusions.add(item)

            # Kludge until masterEvents filter patch on bug 6970 is checked in
            for item in collection.inclusions:
                if pim.has_stamp(item, pim.EventStamp):
                    event = pim.EventStamp(item)
                    if event.rruleset is not None:
                        event.getMaster().getFirstOccurrence()

        except:
            view.cancel()
            raise

        share.established = True
        view.commit()
        self.client.output("'%s' synchronized" %(collection.displayName))

        replyTo = view[self.client.account].imap.replyToAddress.emailAddress

        receipt = MIMEText('Chandler sent a receipt for "%s"' %(name))
        receipt['From'] = replyTo
        receipt['Reply-To'] = replyTo
        receipt['To'] = message.get('replyTo') or fromAddress
        receipt['Subject'] = "Chandler sent a receipt"
        receipt['X-chandler'] = 'p2p'
        receipt['X-chandler-p2p-name'] = name
        receipt['X-chandler-p2p-from'] = self._repoId.str64()
        receipt['X-chandler-p2p-to'] = repoId.str64()
        receipt['X-chandler-p2p-item'] = "%s-%d" %(uuid.str64(),
                                                   share.localVersion)
        receipt['X-chandler-p2p-op'] = 'receipt'

        return receipt
Example #2
0
    def _result_sync(self, view, uid, message, fromAddress):

        try:
            view.refresh(None, None, False)

            repoId = UUID(message['X-chandler-p2p-from'])
            uuid, version = message['X-chandler-p2p-item'].split('-')
            uuid = UUID(uuid)
            version = int(version)
            name = message['X-chandler-p2p-name']
            self.client.output("processing '%s'" % (name))

            collection = view.find(uuid)
            if collection is None:
                collection = pim.SmartCollection(itsView=view,
                                                 _uuid=uuid,
                                                 displayName=name)
                schema.ns("osaf.app", view).sidebarCollection.add(collection)

                # for now, grant READ to everyone
                acl = ACL()
                acl.append(
                    ACE(schema.ns('p2p', view).all.itsUUID, Permissions.READ))
                collection.setACL(acl, 'p2p')
                isNew = True
            else:
                isNew = False

            share = self.findShare(view, collection, repoId, fromAddress)
            format = share.format

            if isNew:
                share.localVersion = view.itsVersion + 1
            else:
                changes = self.computeChanges(view, share.localVersion,
                                              collection, share)
                if not changes:
                    share.localVersion = view.itsVersion + 1

            payload = message.get_payload(1).get_payload()
            dom = ElementTreeDOM()
            input = StringIO(decompress(b64decode(payload)))
            data = ElementTree(file=input).getroot()
            input.close()

            share.remoteVersion = version
            view.deferDelete()

            for itemElement in dom.iterElements(data):
                attributes = dom.getAttributes(itemElement)
                status = attributes.get('status')
                if status == 'deleted':
                    item = view.findUUID(attributes['uuid'])
                    if item is not None:
                        item.delete()
                else:
                    child = dom.getFirstChildElement(itemElement)
                    if child is not None:
                        item = format.importProcess(dom, child)
                    else:
                        item = view.findUUID(attributes['uuid'])

                    if status == 'member':
                        collection.inclusions.add(item)

            # Kludge until masterEvents filter patch on bug 6970 is checked in
            for item in collection.inclusions:
                if pim.has_stamp(item, pim.EventStamp):
                    event = pim.EventStamp(item)
                    if event.rruleset is not None:
                        event.getMaster().getFirstOccurrence()

        except:
            view.cancel()
            raise

        share.established = True
        view.commit()
        self.client.output("'%s' synchronized" % (collection.displayName))

        replyTo = view[self.client.account].imap.replyToAddress.emailAddress

        receipt = MIMEText('Chandler sent a receipt for "%s"' % (name))
        receipt['From'] = replyTo
        receipt['Reply-To'] = replyTo
        receipt['To'] = message.get('replyTo') or fromAddress
        receipt['Subject'] = "Chandler sent a receipt"
        receipt['X-chandler'] = 'p2p'
        receipt['X-chandler-p2p-name'] = name
        receipt['X-chandler-p2p-from'] = self._repoId.str64()
        receipt['X-chandler-p2p-to'] = repoId.str64()
        receipt['X-chandler-p2p-item'] = "%s-%d" % (uuid.str64(),
                                                    share.localVersion)
        receipt['X-chandler-p2p-op'] = 'receipt'

        return receipt
Example #3
0
    def _get_sync(self, view, shareId, peerId, name, op):

        try:
            view.refresh(None, None, False)

            if shareId is not None:
                share = view[shareId]
                peerId = share.conduit.peerId
                toRepoId = share.repoId
                collection = share.contents
                name = collection.displayName
                uuid = collection.itsUUID
                version = share.localVersion
            else:
                collection, name, uuid = self.findCollection(view, name, None)
                toRepoId = None
                version = 0

            replyTo = view[self.client.account].imap.replyToAddress.emailAddress
            share = self.findShare(view, collection, toRepoId, peerId)

            changes = self.computeChanges(view, version, collection, share)
            if op == 'sync' and not changes:
                share.localVersion = view.itsVersion + 1
                view.commit()
                return None

            message = MIMEMultipart()
            message['From'] = replyTo
            message['Reply-To'] = replyTo
            message['To'] = peerId
            message['Subject'] = 'Chandler sent "%s" collection' %(name)
            message['X-chandler'] = 'p2p'
            textPart = MIMEBase('text', 'plain')
            textPart.set_payload('Chandler sent "%s"' %(name))
            message.attach(textPart)
            attachment = MIMEBase('application', 'octet-stream')

            builder = TreeBuilder()
            dom = ElementTreeDOM()
            data = dom.openElement(builder, 'data')

            keys = set()
            for key, (_changes, status) in changes.iteritems():
                if key not in keys:
                    attrs = { 'uuid': key.str64() }
                    if status & CItem.DELETED:
                        attrs['status'] = 'deleted'
                        item = dom.openElement(data, 'item', **attrs)
                    else:
                        if key in collection:
                            attrs['status'] = 'member'
                        item = dom.openElement(data, 'item', **attrs)
                        share.format.exportProcess(dom, key, item,
                                                   changes, keys)
                    dom.closeElement(data, 'item')
                elif key in collection:
                    item = dom.openElement(data, 'item', uuid=key.str64(),
                                           status='member')
                    dom.closeElement(data, 'item')

            dom.closeElement(builder, 'data')
            out = StringIO()
            ElementTree(builder.close()).write(out, 'utf-8')
            data = compress(out.getvalue())
            out.close()

            message['X-chandler-p2p-name'] = name
            message['X-chandler-p2p-from'] = self._repoId.str64()
            if toRepoId is not None:
                message['X-chandler-p2p-to'] = toRepoId.str64()
            message['X-chandler-p2p-item'] = "%s-%d" %(uuid.str64(),
                                                       view.itsVersion)
            message['X-chandler-p2p-op'] = 'sync'

            attachment.set_payload(data)
            encode_base64(attachment)
            attachment.add_header('Content-Disposition', 'attachment',
                                  name=name)
            message.attach(attachment)
        except:
            view.cancel()
            raise

        share.localVersion = view.itsVersion + 1
        share.established = True
        share.ackPending = True
        view.commit()

        return message
Example #4
0
    def _get_sync(self, view, shareId, peerId, name, op):

        try:
            view.refresh(None, None, False)

            if shareId is not None:
                share = view[shareId]
                peerId = share.conduit.peerId
                toRepoId = share.repoId
                collection = share.contents
                name = collection.displayName
                uuid = collection.itsUUID
                version = share.localVersion
            else:
                collection, name, uuid = self.findCollection(view, name, None)
                toRepoId = None
                version = 0

            replyTo = view[
                self.client.account].imap.replyToAddress.emailAddress
            share = self.findShare(view, collection, toRepoId, peerId)

            changes = self.computeChanges(view, version, collection, share)
            if op == 'sync' and not changes:
                share.localVersion = view.itsVersion + 1
                view.commit()
                return None

            message = MIMEMultipart()
            message['From'] = replyTo
            message['Reply-To'] = replyTo
            message['To'] = peerId
            message['Subject'] = 'Chandler sent "%s" collection' % (name)
            message['X-chandler'] = 'p2p'
            textPart = MIMEBase('text', 'plain')
            textPart.set_payload('Chandler sent "%s"' % (name))
            message.attach(textPart)
            attachment = MIMEBase('application', 'octet-stream')

            builder = TreeBuilder()
            dom = ElementTreeDOM()
            data = dom.openElement(builder, 'data')

            keys = set()
            for key, (_changes, status) in changes.iteritems():
                if key not in keys:
                    attrs = {'uuid': key.str64()}
                    if status & CItem.DELETED:
                        attrs['status'] = 'deleted'
                        item = dom.openElement(data, 'item', **attrs)
                    else:
                        if key in collection:
                            attrs['status'] = 'member'
                        item = dom.openElement(data, 'item', **attrs)
                        share.format.exportProcess(dom, key, item, changes,
                                                   keys)
                    dom.closeElement(data, 'item')
                elif key in collection:
                    item = dom.openElement(data,
                                           'item',
                                           uuid=key.str64(),
                                           status='member')
                    dom.closeElement(data, 'item')

            dom.closeElement(builder, 'data')
            out = StringIO()
            ElementTree(builder.close()).write(out, 'utf-8')
            data = compress(out.getvalue())
            out.close()

            message['X-chandler-p2p-name'] = name
            message['X-chandler-p2p-from'] = self._repoId.str64()
            if toRepoId is not None:
                message['X-chandler-p2p-to'] = toRepoId.str64()
            message['X-chandler-p2p-item'] = "%s-%d" % (uuid.str64(),
                                                        view.itsVersion)
            message['X-chandler-p2p-op'] = 'sync'

            attachment.set_payload(data)
            encode_base64(attachment)
            attachment.add_header('Content-Disposition',
                                  'attachment',
                                  name=name)
            message.attach(attachment)
        except:
            view.cancel()
            raise

        share.localVersion = view.itsVersion + 1
        share.established = True
        share.ackPending = True
        view.commit()

        return message