def ImportMessageChange(self, props, flags): if self.skip: raise MAPIError(SYNC_E_IGNORE) try: entryid = PpropFindProp(props, PR_ENTRYID) if self.importer.store: mapistore = self.importer.store.mapiobj else: store_entryid = PpropFindProp(props, PR_STORE_ENTRYID).Value store_entryid = WrapStoreEntryID(0, b'zarafa6client.dll', store_entryid[:-4]) + self.server.pseudo_url + b'\x00' mapistore = self.server._store2(store_entryid) item = _item.Item() item.server = self.server item.store = _store.Store(mapiobj=mapistore, server=self.server) try: item.mapiobj = _utils.openentry_raw(mapistore, entryid.Value, 0) props = item.mapiobj.GetProps([PR_EC_HIERARCHYID, PR_EC_PARENT_HIERARCHYID, PR_STORE_RECORD_KEY], 0) # XXX properties don't exist? item.docid = props[0].Value item.storeid = _benc(props[2].Value) if hasattr(self.importer, 'update'): self.importer.update(item, flags) except (MAPIErrorNotFound, MAPIErrorNoAccess): # XXX, mail already deleted, can we do this in a cleaner way? self.log.debug('received change for entryid %s, but it could not be opened', _benc(entryid.Value)) except Exception: self.log.error('could not process change for entryid %s (%r):', _benc(entryid.Value), props) self.log.error(traceback.format_exc()) if self.stats: self.stats['errors'] += 1 raise MAPIError(SYNC_E_IGNORE)
def create_store(self): try: storeid_rootid = self.server.sa.CreateStore( ECSTORE_TYPE_PRIVATE, self._ecuser.UserID) except MAPIErrorCollision: raise DuplicateError("user '%s' already has store" % self.name) store_entryid = WrapStoreEntryID( 0, b'zarafa6client.dll', storeid_rootid[0][:-4]) + self.server.pseudo_url + b'\x00' return Store(entryid=_benc(store_entryid), server=self.server)
def create_public_store(self): """Create company public :class:`store <Store>`.""" if self._name == u'Default': try: storeid_rootid = self.server.sa.CreateStore(ECSTORE_TYPE_PUBLIC, EID_EVERYONE) except MAPIErrorCollision: raise DuplicateError("public store already exists") else: try: storeid_rootid = self.server.sa.CreateStore(ECSTORE_TYPE_PUBLIC, self._eccompany.CompanyID) except MAPIErrorCollision: raise DuplicateError("public store already exists for company '%s'" % self.name) store_entryid = WrapStoreEntryID(0, b'zarafa6client.dll', storeid_rootid[0][:-4]) + self.server.pseudo_url + b'\x00' self._public_store = _store.Store(entryid=_hex(store_entryid), server=self.server) return self._public_store
def create_store(self, user, _msr=False): # TODO detect homeserver override storetype = ECSTORE_TYPE_PRIVATE # TODO configurable storetype if _msr: try: storeid, rootid = self.sa.CreateEmptyStore( storetype, _bdec(user.userid), EC_OVERRIDE_HOMESERVER, None, None) except MAPIErrorCollision: raise DuplicateError( "user '%s' already has an associated store (unhook first?)" % user.name) store_entryid = WrapStoreEntryID( 0, b'zarafa6client.dll', storeid[:-4]) + b'https://' + codecs.encode( self.name, 'utf-8') + b':237\x00' store_entryid = store_entryid[:66] + b'\x10' + store_entryid[ 67:] # multi-server flag store = self.store(entryid=_benc(store_entryid)) # TODO add EC_OVERRIDE_HOMESERVER flag to CreateStore instead? or how does the old MSR do this? # TODO language # system folders root = store.root store.findroot = root.create_folder('FINDER_ROOT') store.findroot.permission(self.group('Everyone'), create=True).rights = [ 'read_items', 'create_subfolders', 'edit_own', 'delete_own', 'folder_visible' ] store.views = root.create_folder('IPM_VIEWS') store.common_views = root.create_folder('IPM_COMMON_VIEWS') root.create_folder('Freebusy Data') root.create_folder('Schedule') root.create_folder('Shortcut') # special folders subtree = store.subtree = root.folder('IPM_SUBTREE', create=True) store.calendar = subtree.create_folder('Calendar') store.contacts = subtree.create_folder('Contacts') # TODO Conversation Action Settings? store.wastebasket = subtree.create_folder('Deleted Items') store.drafts = subtree.create_folder('Drafts') store.inbox = subtree.create_folder('Inbox') store.journal = subtree.create_folder('Journal') store.junk = subtree.create_folder('Junk E-mail') store.notes = subtree.create_folder('Notes') store.outbox = subtree.create_folder('Outbox') # TODO Quick Step Settings? # TODO RSS Feeds? store.sentmail = subtree.create_folder('Sent Items') # TODO Suggested Contacts? store.tasks = subtree.create_folder('Tasks') # freebusy message TODO create dynamically instead? fbmsg = root.create_item( subject='LocalFreebusy', message_class='IPM.Microsoft.ScheduleData.FreeBusy') root[PR_FREEBUSY_ENTRYIDS] = [b'', _bdec(fbmsg.entryid), b'', b''] else: store = user.create_store() return store
def create_store(self, user, _msr=False): """Create store for :class:`User`. :param user: User """ # TODO detect homeserver override storetype = ECSTORE_TYPE_PRIVATE # TODO configurable storetype if _msr: try: storeid, rootid = self.sa.CreateEmptyStore(storetype, _bdec(user.userid), EC_OVERRIDE_HOMESERVER, None, None) except MAPIErrorCollision: raise DuplicateError("user '%s' already has an associated \ store (unhook first?)" % user.name) # Parse the server, fallback to 237 for now server_port = self._get_server_port() if not server_port: # TODO: raise exception? server_port = 237 store_entryid = \ WrapStoreEntryID(0, b'zarafa6client.dll',storeid[:-4]) + \ b'https://' + \ codecs.encode(self.name, 'utf-8') + \ b':' + str(server_port).encode('utf-8') + b'\x00' # multi-server flag store_entryid = \ store_entryid[:66] + \ b'\x10' + \ store_entryid[67:] store = self.store(entryid=_benc(store_entryid)) # TODO add EC_OVERRIDE_HOMESERVER flag to CreateStore instead? # or how does the old MSR do this? # TODO language # system folders root = store.root store.findroot = root.create_folder('FINDER_ROOT') store.findroot.permission( self.group('Everyone'), create=True).rights = \ ['read_items', 'create_subfolders', 'edit_own', 'delete_own', 'folder_visible'] store.views = root.create_folder('IPM_VIEWS') store.common_views = root.create_folder('IPM_COMMON_VIEWS') freebusydata = root.create_folder('Freebusy Data') root.create_folder('Schedule') root.create_folder('Shortcut') # special folders subtree = store.subtree = root.folder('IPM_SUBTREE', create=True) calendar = subtree.create_folder('Calendar') store.calendar = calendar store.contacts = subtree.create_folder('Contacts') # TODO Conversation Action Settings? store.wastebasket = subtree.create_folder('Deleted Items') store.drafts = subtree.create_folder('Drafts') store.inbox = subtree.create_folder('Inbox') store.journal = subtree.create_folder('Journal') store.junk = subtree.create_folder('Junk E-mail') store.notes = subtree.create_folder('Notes') store.outbox = subtree.create_folder('Outbox') # TODO Quick Step Settings? # TODO RSS Feeds? store.sentmail = subtree.create_folder('Sent Items') # TODO Suggested Contacts? store.tasks = subtree.create_folder('Tasks') # freebusy message TODO create dynamically instead? fbmsg = root.create_item( subject='LocalFreebusy', message_class='IPM.Microsoft.ScheduleData.FreeBusy' ) calendar_fbmsg = calendar.create_item( subject='LocalFreebusy', message_class='IPM.Microsoft.ScheduleData.FreeBusy', associated=True ) # PR_FREEBUSY_ENTRYIDS[0] gives associated freebusy iten in calendar # PR_FREEBUSY_ENTRYIDS[1] Localfreebusy (used for delegate properties) message # PR_FREEBUSY_ENTRYIDS[2] global Freebusydata in public store (empty in Kopano) # PR_FREEBUSY_ENTRYIDS[3] Freebusydata in IPM_SUBTREE root[PR_FREEBUSY_ENTRYIDS] = [_bdec(calendar_fbmsg.entryid), _bdec(fbmsg.entryid), b'', _bdec(freebusydata.entryid)] else: store = user.create_store() return store