Exemple #1
0
class BaseConduit(Conduit):

    sharePath = schema.One(
        schema.Text,
        initialValue=u"",
        doc="The parent 'directory' of the share",
    )

    shareName = schema.One(
        schema.Text,
        initialValue=u"",
        doc="The 'directory' name of the share, relative to 'sharePath'",
    )

    schema.initialValues(shareName=lambda self: unicode(UUID()), )

    # TODO: see if this is used anymore:

    def isAttributeModifiable(self, item, attribute):
        share = self.share

        if utility.isSharedByMe(share) or share.mode in ('put', 'both'):
            return True

        # In old style shares, an attribute isn't modifiable if it's one
        # of the attributes shared for this item in this share
        for attr in item.getBasedAttributes(attribute):
            if attr in share.getSharedAttributes(item.itsKind):
                return False

        return True
    def getTypeName(self, attribute, attrs, default):

        name = None

        if attrs.has_key('typeid'):
            try:
                name = self.view[UUID(attrs['typeid'])].handlerName()
            except KeyError:
                raise TypeError, "Type %s not found" % (attrs['typeid'])

        elif attrs.has_key('typepath'):
            typeItem = self.view.find(Path(attrs['typepath']))
            if typeItem is None:
                raise TypeError, "Type %s not found" % (attrs['typepath'])
            name = typeItem.handlerName()

        elif attrs.has_key('type'):
            name = attrs['type']

        elif attribute is not None:
            attrType = attribute.getAspect('type', None)
            if attrType is not None:
                name = attrType.handlerName()

        return name or default
    def purgeDocuments(self,
                       txn,
                       counter,
                       indexSearcher,
                       indexReader,
                       uItem,
                       toVersion=None):

        term = Term("item", uItem.str64())

        if toVersion is None:
            counter.documentCount += indexReader.deleteDocuments(term)

        else:
            x, keep = self.store._items.findValues(None, toVersion, uItem,
                                                   None, True)
            keep = set(keep)

            for hit in indexSearcher.search(TermQuery(term)):
                hit = Hit.cast_(hit)

                doc = hit.getDocument()
                ver = long(doc['version'])
                if ver <= toVersion and UUID(doc['value']) not in keep:
                    indexReader.deleteDocument(hit.getId())
                    counter.documentCount += 1
 def __init__(self, title):
     self.id = UUID()
     self.title = title
     self.status = STATUS_INACTIVE
     self.totalWork = None
     self.workDone = 0
     self.exception = None
     self.abortRequested = False
    def kindEnd(self, itemHandler, attrs):

        if attrs['type'] == 'uuid':
            self.kindRef = UUID(self.data)
        else:
            self.kindRef = Path(self.data)

        self.kind = self.view._findSchema(self.kindRef, self.withSchema)
Exemple #6
0
    def __init__(self, view, item, name, otherName, dictKey,
                 readOnly, new, uuid):

        self.uuid = uuid or UUID()

        PersistentRefs.__init__(self, view)
        RefList.__init__(self, view, item, name, otherName, dictKey, readOnly,
                         (CLinkedMap.NEW if new else 0) | CLinkedMap.LOAD)
Exemple #7
0
    def _value(self, item, name, value, version, flags, withSchema, attribute):

        self.lobs = []
        self.indexes = []
        view = item.itsView

        uValue = UUID()
        self.values.append((name, uValue))

        if isinstance(value, Indexable):
            indexed = value.isIndexed()
            indexable = True
        else:
            indexed = None
            indexable = False

        if attribute is None:
            attrCard = 'single'
            attrType = None
            if indexed is None:
                indexed = False
        else:
            c = attribute.c
            attrCard = c.cardinality
            attrType = attribute.type
            if indexed is None:
                indexed = c.indexed

        if indexed and self.toindex:
            flags |= CValues.TOINDEX
            item._status |= CItem.TOINDEX
            indexed = False

        record = Record(Record.UUID, attribute.itsUUID, Record.BYTE, flags)

        valueRecord = Record()
        if withSchema:
            valueRecord += (Record.SYMBOL, name)

        try:
            if attrCard == 'single':
                self.writeValue(valueRecord, item, version, value, withSchema,
                                attrType)
            elif attrCard == 'list':
                self.writeList(valueRecord, item, version, value, withSchema,
                               attrType)
            elif attrCard == 'set':
                self.writeSet(valueRecord, item, version, value, withSchema,
                              attrType)
            elif attrCard == 'dict':
                self.writeDict(valueRecord, item, version, value, withSchema,
                               attrType)
        except DBLockDeadlockError:
            raise
        except Exception, e:
            raise SaveValueError, (item, name, e)
    def exists(self):

        value = self._container.get(self._key)
        if value is None:
            return False

        zero, self.length, self.timeModified, uuid = unpack('>IIQ16s', value)
        self._uuid = UUID(uuid)

        return True
            def __iter__(_self):

                _self.txnStatus = store.startTransaction(view)
                _self.searcher = searcher = self.getIndexSearcher()
                _self.collector = _collector()

                searcher.search(query, _self.collector)
                hits = _self.collector.hits

                if hits:
                    heapify(hits)
                    while hits:
                        score, id = heappop(hits)
                        doc = searcher.doc(id)
                        uItem = UUID(doc['item'])

                        if long(doc['version']) <= version:
                            if store._items.isValue(view, version, uItem,
                                                    UUID(doc['value'])):
                                yield uItem, UUID(doc['attribute'])
    def parentEnd(self, itemHandler, attrs):

        if attrs['type'] == 'uuid':
            self.parentRef = UUID(self.data)
        else:
            self.parentRef = Path(self.data)

        self.isContainer = attrs.get('container', 'False') == 'True'
        self.parent = self.view.find(self.parentRef)

        if self.parent is None:
            self.afterLoadHooks.append(self._move)
Exemple #11
0
    def itemStart(self, attrs):

        parent = None

        if attrs.get('afterLoadHooks', 'False') == 'True':
            self.hooks.append([])

        if attrs.has_key('path'):
            parent = self.view.find(Path(attrs['path']))
        elif attrs.has_key('uuid'):
            parent = self.view.find(UUID(attrs['uuid']))
        elif attrs.has_key('file'):
            file = attrs['file']
            if isinstance(file, unicode):
                file = file.encode(self.fsenc)

            parent = self.loadItem(os.path.join(self.cwd[-1], file),
                                   self.parent[-1])

        elif attrs.has_key('files'):
            files = attrs['files']
            if isinstance(files, unicode):
                files = files.encode(self.fsenc)

            pattern = '^' + files + '$'
            pattern = pattern.replace('.', '\\.').replace('*', '.*')
            exp = re.compile(pattern)

            if self.package is not None:
                if os.path.sep != '/':
                    path = self.cwd[-1].replace(os.path.sep, '/')
                else:
                    path = self.cwd[-1]
                files = resource_listdir(self.package, path)
            else:
                files = os.listdir(self.cwd[-1])

            for file in files:
                if exp.match(file):
                    parent = self.loadItem(os.path.join(self.cwd[-1], file),
                                           self.parent[-1])
                    if self.errorOccurred():
                        return

        self.parent.append(parent)

        if attrs.has_key('cwd'):
            cwd = attrs['cwd']
            if isinstance(cwd, unicode):
                cwd = cwd.encode(self.fsenc)

            self.cwd.append(os.path.join(self.cwd[-1], cwd))
    def __init__(self, container, name, create=False, value=None):

        super(File, self).__init__()

        self._container = container
        self.setName(name)

        if not self.exists():
            self._uuid = UUID()
            self.length = 0

        elif create:
            self.length = 0
    def _result_receipt(self, view, iq, elem, args):

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

            repoId = UUID(args['fromRepoId'])
            uuid = UUID(args['uuid'])
            version = int(args['version'])
            collection = view.find(uuid)

            if collection is None:
                raise NameError, ('no such collection', uuid)

            share = self.findShare(view, collection, repoId, iq['from'])
            share.remoteVersion = version
            share.ackPending = False
        except:
            view.cancel()
            raise

        view.commit()
        self.client.output(None)
    def refEnd(self, itemHandler, attrs):

        if self.tags[-1] == 'item':
            attribute = self.attributes.pop()
            cardinality = self.getCardinality(attribute, attrs)
            otherCard = attrs.get('otherCard', None)

        else:
            cardinality = 'single'
            otherCard = self.tagAttrs[-1].get('otherCard', None)

        if cardinality == 'single':  # cardinality of tag
            typeName = attrs.get('type', 'path')

            if typeName == 'path':
                ref = Path(self.data)
            elif typeName == 'none':
                self.references[attrs['name']] = None
                return
            else:
                ref = UUID(self.data)

            if self.collections:
                refList = self.collections[-1]
                self.refs.append(
                    RefArgs(refList._name,
                            None,
                            refList._otherName,
                            ref,
                            otherCard=otherCard,
                            otherAlias=attrs.get('otherAlias'),
                            previous=self.refName(attrs, 'previous'),
                            next=self.refName(attrs, 'next'),
                            alias=attrs.get('alias')))
            else:
                name = attrs['name']
                otherName = self.getOtherName(name, self.getAttribute(name),
                                              attrs)
                self.refs.append(
                    RefArgs(name,
                            None,
                            otherName,
                            ref,
                            otherCard=otherCard,
                            otherAlias=attrs.get('otherAlias')))
        else:
            value = self.collections.pop()
            self.references[attrs['name']] = value
            if value._indexes:
                self.afterLoadHooks.append(value._restoreIndexes)
def UUIDFromICalUID(view, uid_to_uuid_map, uid):
    """
    When importing iCalendar, match up events by their uid if an item with that
    icalUID or UUID exists.  Otherwise, randomize UUID, bug 9965.
    """
    uuid = uid_to_uuid_map.get(uid)
    if uuid is None:
        item = utility.findUID(view, uid)
        if item is None:
            try:
                # See if uid is a valid repository UUID, if it is, and that UUID
                # already exists, we'll use it
                item = view.findUUID(UUID(uid))
            except ValueError:
                pass

        if item is None:
            uuid = UUID()
        else:
            uuid = item.itsUUID
        uid_to_uuid_map[uid] = uuid

    return str(uuid)
    def _result_receipt(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)
            collection = view.find(uuid)

            if collection is None:
                raise NameError, ('no such collection', uuid)

            share = self.findShare(view, collection, repoId, fromAddress)
            share.remoteVersion = version
            share.ackPending = False
        except:
            view.cancel()
            raise

        view.commit()
        self.client.output(None)
Exemple #17
0
    def append(self, name):
        """
        Add a name to this path.

        C{name} should be a string without C{/} characters.

        @param name: the name to add
        @type name: a string
        """

        if not isinstance(name, UUID) and name.startswith('{'):
            name = UUID(name[1:-1])

        self._names.append(name)
        def _find(spec):

            typeAttr = attrs.get('type', 'path')
            if typeAttr == 'path':
                item = self.parent.find(Path(spec))
            elif typeAttr == 'uuid':
                item = self.parent.find(UUID(spec))
            else:
                raise TypeError, typeAttr

            if item is None:
                raise NoSuchItemError, (spec, self.version)

            return item
    def itemStart(self, itemHandler, attrs):

        super(ItemHandler, self).itemStart(itemHandler, attrs)

        if self.values is None:
            self.values = Values(None)
        if self.references is None:
            self.references = References(None)

        self.refs = []
        self.name = None
        self.cls = None
        self.parentRef = None
        self.isContainer = False
        self.uuid = UUID(attrs.get('uuid'))
        self.version = int(attrs.get('version', '0'))
        self.update = update = attrs.get('update')
        self.delete = delete = attrs.get('delete')

        def _find(spec):

            typeAttr = attrs.get('type', 'path')
            if typeAttr == 'path':
                item = self.parent.find(Path(spec))
            elif typeAttr == 'uuid':
                item = self.parent.find(UUID(spec))
            else:
                raise TypeError, typeAttr

            if item is None:
                raise NoSuchItemError, (spec, self.version)

            return item

        if update is not None:
            item = _find(update)
        elif delete is not None:
            item = _find(delete)
        else:
            item = None

        if item is not None:
            self.item = item
            self.cls = type(item)
            self.version = item._version
            self.name = item.itsName
            self.kind = item.itsKind
            self.uuid = item.itsUUID
            self.parent = item.itsParent
Exemple #20
0
    def _writeValue(self, itemWriter, record, version, withSchema):

        if self._uuid is None or not self._append:
            self._uuid = UUID()
            self._dirty = True

        store = self._view.repository.store
        size = self._writeData(version, store._lobs)

        itemWriter.lobs.append(self._uuid)
        record += (Record.UUID, self._uuid, Record.BOOLEAN, self._indexed,
                   Record.SYMBOL, self.mimetype, Record.SYMBOL, self.encoding,
                   Record.SYMBOL, self._compression, Record.SYMBOL,
                   self._encryption, Record.SYMBOL, self._iv)

        return size
            def _gotMail(_self, result):
                self.output("imap: got mail")
                messages = MessageSet()
                for data in result.itervalues():
                    message = message_from_string(data['RFC822'])
                    toRepoId = message.get('X-chandler-p2p-to')
                    if toRepoId is None or UUID(toRepoId) == self._repoId:
                        args = (data['UID'], message, peerId)
                        self.worker.queueRequest(('receive', args))
                        messages.add(data['UID'])


#                d = _self.logout()
#                d = d.addCallback(_self._done)
                d = _self.addFlags(messages, ('\\Deleted', ), uid=True)
                d = d.addCallback(_self._flagsAdded)
                return d.addErrback(_self.catchErrors)
Exemple #22
0
def installParcel(parcel, oldVersion = None):
    # Hard code the UUID so that after a new repository is created we can still
    # find the dummy for dump and reload
    dummyPassword = Password.update(parcel,
                                    'dummyPassword',
                                    _uuid = UUID('dd555441-9ddc-416c-b55a-77b073c7bd15'),
                                    )
    
    password = ''.join([string.printable[ord(c) % len(string.printable)] \
                        for c in os.urandom(16)])
    waitForDeferred(dummyPassword.encryptPassword(password, masterPassword=''))
    
    PasswordPrefs.update(parcel, 'passwordPrefs', dummyPassword=dummyPassword)
    
    # This ensures that MasterPassword.installParcel gets called now;
    # not doing this can lead to weird stale parcel items later on.
    schema.ns('osaf.framework.MasterPassword', parcel).masterPasswordPrefs
    def _setupRefList(self, name, attribute, readOnly, attrs):

        refList = None
        otherName = self.getOtherName(name, attribute, attrs)

        if attrs.has_key('uuid'):  # some xml parsers don't like 'in' here
            uuid = UUID(attrs['uuid'])
        else:
            uuid = None

        if self.update and attrs.get('operation') == 'append':
            refList = self.item._references.get(name)

        if refList is None:
            refList = self.view._createRefList(None, name, otherName, None,
                                               readOnly, self.new, uuid)

        self.collections.append(refList)
Exemple #24
0
    def set(self, *args):
        """
        Any number of arguments are combined to form a list of names, a path.
        Individual Arguments are split along C{/} characters allowing for paths
        to be constructed from path strings.
        Ending C{/} characters are stripped.
        """

        self._names = []
        first = True

        for arg in args:

            if isinstance(arg, Path):
                self._names.extend(arg._names)

            elif isinstance(arg, UUID):
                self._names.append(arg)

            elif arg:

                if arg.startswith('//'):
                    if first:
                        self._names.append('//')
                    arg = arg[2:]

                elif arg.startswith('/'):
                    if first:
                        self._names.append('/')
                    arg = arg[1:]

                if arg.endswith('/'):
                    arg = arg[:-1]

                if arg:
                    for arg in arg.split('/'):
                        if arg.startswith('{'):
                            arg = UUID(arg[1:-1])
                        self._names.append(arg)

                first = False
    def _setupTypeDelegate(self, attrs):

        if attrs.has_key('typeid'):
            try:
                attrType = self.view[UUID(attrs['typeid'])]
            except KeyError:
                raise TypeError, "Type %s not found" % (attrs['typeid'])

            self.delegates.append(attrType)
            attrType.startValue(self)

            return True

        elif self.attributes[-1]:
            attrType = self.attributes[-1].getAspect('type')
            if attrType is not None and not attrType.isAlias():
                self.delegates.append(attrType)
                attrType.startValue(self)

                return True

        return False
    def _processError(self, view, iq, inResponseTo):

        self.client.output("processing error")

        error = iq.query.error
        className = error['class']

        if className == 'p2p.errors.RepositoryMismatchError':
            args = error['args'].split(',')
            view.refresh(None, None, False)
            repoId = UUID(args[0])
            for share in JabberShare.getKind(view).iterItems():
                if share.repoId == repoId:
                    share.delete()
            view.commit()

        else:
            errorName = className.rsplit('.', 1)[-1]
            if inResponseTo:
                op, arg = inResponseTo
                self.client.output("%s '%s' failed: %s" % (op, arg, errorName))
            else:
                self.client.output("received error: %s" % (errorName))
Exemple #27
0
    def __init__(self, view, **kwds):

        super(DBNumericIndex, self).__init__(**kwds)

        self.view = view
        self._changedKeys = {}

        if not kwds.get('loading', False):

            if 'uuid' in kwds:
                self._uuid = UUID(kwds['uuid'])
                self._headKey = UUID(kwds['head'])
                self._tailKey = UUID(kwds['tail'])
            else:
                self._uuid = UUID()
                self._headKey = UUID()
                self._tailKey = UUID()

            self.__init()
Exemple #28
0
    def _get_sync(self, view, iq, args):

        try:
            if 'toRepoId' in args and UUID(args['toRepoId']) != self._repoId:
                raise RepositoryMismatchError, args['toRepoId']

            view.refresh(None, None, False)

            repoId = UUID(args['fromRepoId'])
            name = args['name']
            version = int(args.get('version', '0'))
            uuid = args.get('uuid')
            if uuid is not None:
                uuid = UUID(uuid)

            collection, name, uuid = self.findCollection(view, name, uuid)
            share = self.findShare(view, collection, repoId, iq['from'])

            iq = client.IQ(self.client.xmlstream, "result")
            query = iq.addElement(("jabber:x:chandler", "query"))
            sync = query.addElement('sync')
            sync['name'] = name

            changes = self.computeChanges(view, version, collection, share)
            keys = set()
            compressed = len(changes) > 16

            if compressed:
                builder = TreeBuilder()
                dom = formats.ElementTreeDOM()
                data = dom.openElement(builder, 'data')
            else:
                dom = DomishDOM()
                data = dom.openElement(sync, 'data')

            for key, (_changes, status) in changes.iteritems():
                if key not in keys:
                    if status & CItem.DELETED:
                        dom.openElement(data, 'item', uuid=key.str64(),
                                        status='deleted')
                    else:
                        attrs = { 'uuid': key.str64() }
                        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:
                    dom.openElement(data, 'item', uuid=key.str64(),
                                    status='member')
                    dom.closeElement(data, 'item')

            dom.closeElement(data, 'data')

            sync['fromRepoId'] = self._repoId.str64()
            sync['toRepoId'] = repoId.str64()
            sync['version'] = str(view.itsVersion)
            sync['uuid'] = collection.itsUUID.str64()

            if compressed:
                sync['compressed'] = 'true'
                out = StringIO()
                ElementTree(builder.close()).write(out, 'utf-8')
                sync.children.append(b64encode(compress(out.getvalue())))
                out.close()

        except:
            view.cancel()
            raise

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

        return iq
Exemple #29
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
Exemple #30
0
    def _result_sync(self, view, iq, sync, args):

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

            if 'toRepoId' in args and UUID(args['toRepoId']) != self._repoId:
                raise RepositoryMismatchError, args['toRepoId']

            repoId = UUID(args['fromRepoId'])
            uuid = UUID(args['uuid'])
            version = int(args['version'])
            collection = view.find(uuid)

            if collection is None:
                collection = pim.SmartCollection(itsView=view, _uuid=uuid,
                                                 displayName=args['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, iq['from'])
            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

            if sync.attributes.get('compressed') == 'true':
                dom = formats.ElementTreeDOM()
                input = StringIO(decompress(b64decode(sync.children[0])))
                data = ElementTree(file=input).getroot()
                input.close()
            else:
                dom = DomishDOM()
                data = sync.firstChildElement()

            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))

        to = iq['from']
        iq = client.IQ(self.client.xmlstream, 'result')
        iq.addElement(('jabber:x:chandler', 'query'))
        receipt = iq.query.addElement('receipt')
        receipt['fromRepoId'] = self._repoId.str64()
        receipt['toRepoId'] = repoId.str64()
        receipt['uuid'] = collection.itsUUID.str64()
        receipt['version'] = str(share.localVersion)
        reactor.callFromThread(iq.send, to)
    def getRecords(self, debug=False, activity=None):
        # Get and return records, extra
        debug = True
        doLog = logger.info if debug else logger.debug

        # 'alias' for a state will be the pseudoId

        inbound = {}
        extra = {}

        query = gdata.calendar.service.CalendarEventQuery()
        query.feed = self.url
        query.max_results = '10000'
        feed = self.gService.CalendarQuery(query)
        # feed = self.gService.GetCalendarEventFeed(self.url)
        extra['name'] = feed.title.text
        doLog("Fetched Google calendar: %s (%d entries)" %
              (feed.title.text, len(feed.entry)))

        # gdata id --> state mapping
        states = {}
        for state in self.share.states:
            states[state.id] = state

        # alias --> entry mapping
        entries = {}
        unchanged = set()
        for entry in feed.entry:
            # doLog("Received entry: %s", entry)
            records = []
            id = entry.id.text

            editLink = entry.GetEditLink()
            if editLink is not None:
                editLink = editLink.href
                self.share.mode = 'both'
            else:
                # This is a read-only calendar
                self.share.mode = 'get'

            if id in states:
                # update to existing item
                state = states[id]
                alias = self.share.states.getAlias(state)
                if editLink:
                    if state.editLink == editLink:
                        unchanged.add(alias)
                    else:
                        state.editLink = editLink
                        doLog("Received update to: %s" % entry.title.text)
                else:
                    doLog("Received possible update to read-only item: %s" %
                          entry.title.text)
            else:
                # new inbound item
                alias = UUID(md5.new(entry.id.text).digest()).str16()
                state = self.newState(alias)
                state.id = id
                if editLink:
                    state.editLink = editLink
                doLog("Received new item: %s" % entry.title.text)

            state.gdataEntry = entry  # non-persisted, used by putRecords next
            state.removed = False
            entries[alias] = entry

        for id, state in states.iteritems():
            alias = self.share.states.getAlias(state)
            if alias not in entries and not state.removed:
                # indicator of remote deletion
                inbound[alias] = None
                state.removed = True
                doLog("Received deletion of: %s" % alias)

        for alias, entry in entries.iteritems():
            if alias in unchanged:
                continue

            records = []
            title = entry.title.text
            body = entry.content.text
            rec = sharing.ItemRecord(alias, title, NC, NC, NC, NC, NC)
            records.append(rec)
            rec = sharing.NoteRecord(alias, body, NC, NC, NC, NC)
            records.append(rec)

            if entry.recurrence:
                # print "Skipping (recurrence)", title, entry.recurrence
                self.removeState(alias)
                continue

            else:
                where = entry.where[0]
                location = where.value_string if where and where.value_string \
                    else None

                startTime = whenToDatetime(self.itsView,
                                           entry.when[0].start_time)
                endTime = whenToDatetime(self.itsView, entry.when[0].end_time)
                duration = endTime - startTime
                startTime = sharing.toICalendarDateTime(self.itsView,
                                                        startTime,
                                                        False,
                                                        anyTime=False)
                duration = sharing.toICalendarDuration(duration, allDay=False)
                rec = sharing.EventRecord(alias, startTime, duration, location,
                                          None, None, None, None, NC)
                records.append(rec)

            inbound[alias] = sharing.RecordSet(records)

        return inbound, extra, False
    def testZlibEncrypted(self):

        self.compressed('zlib', 'rijndael', UUID()._uuid)
    def testEncrypted(self):

        self.compressed(None, 'rijndael', UUID()._uuid)