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