def test_random(self): mailbox_id = ObjectId.random_mailbox_id() self.assertEqual(b'F', mailbox_id.value[0:1]) self.assertTrue(len(mailbox_id.value)) email_id = ObjectId.random_email_id() self.assertEqual(b'M', email_id.value[0:1]) self.assertTrue(len(email_id.value)) thread_id = ObjectId.random_thread_id() self.assertEqual(b'T', thread_id.value[0:1]) self.assertTrue(len(thread_id.value))
def add(self, content: MessageContent) -> ObjectId: self._ref[content] = thread_keys = ThreadKey.get_all(content.header) for thread_key in thread_keys: thread_id = self._thread_ids.get(thread_key) if thread_id is not None: break else: thread_id = ObjectId.random_thread_id() for thread_key in thread_keys: self._thread_ids.setdefault(thread_key, thread_id) return thread_id
async def reset(self) -> MailboxData: keys = await self._get_keys() async with UidList.with_write(self._path) as uidl: for rec in uidl.records: keys.pop(rec.key, None) if not keys: raise NoChanges() for key, info in keys.items(): filename = key + ':' + info fields = {'E': str(ObjectId.random_email_id()), 'T': str(ObjectId.random_thread_id())} new_rec = Record(uidl.next_uid, fields, filename) uidl.next_uid += 1 uidl.set(new_rec) self._uid_validity = uidl.uid_validity self._next_uid = uidl.next_uid return self
async def save(self, message: bytes) -> SavedMessage: redis = self._redis ns_keys = self._ns_keys content = MessageContent.parse(message) new_email_id = ObjectId.random_email_id() msg_hash = HashStream(hashlib.sha1()).digest(content) thread_keys = ThreadKey.get_all(content.header) thread_key_keys = [ b'\0'.join(thread_key) for thread_key in thread_keys ] await redis.unwatch() multi = redis.multi_exec() multi.hsetnx(ns_keys.email_ids, msg_hash, new_email_id.value) multi.hget(ns_keys.email_ids, msg_hash) if thread_key_keys: multi.hmget(ns_keys.thread_ids, *thread_key_keys) else: multi.hmget(ns_keys.thread_ids, b'') _, email_id, thread_ids = await multi.execute() thread_id_b = next( (thread_id for thread_id in thread_ids if thread_id is not None), None) if thread_id_b is None: thread_id = ObjectId.random_thread_id() else: thread_id = ObjectId(thread_id_b) ct_keys = ContentKeys(ns_keys, email_id) multi = redis.multi_exec() multi.hset(ct_keys.data, b'full', message) multi.hset(ct_keys.data, b'full-json', json.dumps(content.json)) multi.hset(ct_keys.data, b'header', bytes(content.header)) multi.hset(ct_keys.data, b'header-json', json.dumps(content.header.json)) multi.expire(ct_keys.data, self._cleanup.content_expire) for thread_key_key in thread_key_keys: multi.hsetnx(ns_keys.thread_ids, thread_key_key, thread_id.value) await multi.execute() return SavedMessage(ObjectId(email_id), thread_id, None)
async def save(self, message: bytes) -> SavedMessage: email_id = ObjectId.random_email_id() thread_id = ObjectId.random_thread_id() return SavedMessage(email_id, thread_id, message)