mirror of
https://github.com/chatmail/core.git
synced 2026-04-05 23:22:11 +03:00
New APIs for message processing loops
This patch adds new C APIs dc_get_next_msgs() and dc_wait_next_msgs(), and their JSON-RPC counterparts get_next_msgs() and wait_next_msgs(). New configuration "last_msg_id" tracks the last message ID processed by the bot. get_next_msgs() returns message IDs above the "last_msg_id". wait_next_msgs() waits for new message notification and calls get_next_msgs(). wait_next_msgs() can be used to build a separate message processing loop independent of the event loop. Async Python API get_fresh_messages_in_arrival_order() is deprecated in favor of get_next_messages(). Introduced Python APIs: - Account.wait_next_incoming_message() - Message.is_from_self() - Message.is_from_device() Introduced Rust APIs: - Context.set_config_u32() - Context.get_config_u32()
This commit is contained in:
@@ -376,6 +376,22 @@ class Account:
|
||||
dc_array = ffi.gc(lib.dc_get_fresh_msgs(self._dc_context), lib.dc_array_unref)
|
||||
return (x for x in iter_array(dc_array, lambda x: Message.from_db(self, x)) if x is not None)
|
||||
|
||||
def _wait_next_message_ids(self) -> List[int]:
|
||||
"""Return IDs of all next messages from all chats."""
|
||||
dc_array = ffi.gc(lib.dc_wait_next_msgs(self._dc_context), lib.dc_array_unref)
|
||||
return [lib.dc_array_get_id(dc_array, i) for i in range(lib.dc_array_get_cnt(dc_array))]
|
||||
|
||||
def wait_next_incoming_message(self) -> Message:
|
||||
"""Waits until the next incoming message
|
||||
with ID higher than given is received and returns it."""
|
||||
while True:
|
||||
message_ids = self._wait_next_message_ids()
|
||||
for msg_id in message_ids:
|
||||
message = Message.from_db(self, msg_id)
|
||||
if message and not message.is_from_self() and not message.is_from_device():
|
||||
self.set_config("last_msg_id", str(msg_id))
|
||||
return message
|
||||
|
||||
def create_chat(self, obj) -> Chat:
|
||||
"""Create a 1:1 chat with Account, Contact or e-mail address."""
|
||||
return self.create_contact(obj).create_chat()
|
||||
|
||||
@@ -344,6 +344,16 @@ class Message:
|
||||
contact_id = lib.dc_msg_get_from_id(self._dc_msg)
|
||||
return Contact(self.account, contact_id)
|
||||
|
||||
def is_from_self(self):
|
||||
"""Return true if the message is sent by self."""
|
||||
contact_id = lib.dc_msg_get_from_id(self._dc_msg)
|
||||
return contact_id == const.DC_CONTACT_ID_SELF
|
||||
|
||||
def is_from_device(self):
|
||||
"""Return true if the message is sent by the device."""
|
||||
contact_id = lib.dc_msg_get_from_id(self._dc_msg)
|
||||
return contact_id == const.DC_CONTACT_ID_DEVICE
|
||||
|
||||
#
|
||||
# Message State query methods
|
||||
#
|
||||
|
||||
@@ -44,21 +44,21 @@ def test_configure_generate_key(acfactory, lp):
|
||||
lp.sec("ac1: send unencrypted message to ac2")
|
||||
chat.send_text("message1")
|
||||
lp.sec("ac2: waiting for message from ac1")
|
||||
msg_in = ac2._evtracker.wait_next_incoming_message()
|
||||
msg_in = ac2.wait_next_incoming_message()
|
||||
assert msg_in.text == "message1"
|
||||
assert not msg_in.is_encrypted()
|
||||
|
||||
lp.sec("ac2: send encrypted message to ac1")
|
||||
msg_in.chat.send_text("message2")
|
||||
lp.sec("ac1: waiting for message from ac2")
|
||||
msg2_in = ac1._evtracker.wait_next_incoming_message()
|
||||
msg2_in = ac1.wait_next_incoming_message()
|
||||
assert msg2_in.text == "message2"
|
||||
assert msg2_in.is_encrypted()
|
||||
|
||||
lp.sec("ac1: send encrypted message to ac2")
|
||||
msg2_in.chat.send_text("message3")
|
||||
lp.sec("ac2: waiting for message from ac1")
|
||||
msg3_in = ac2._evtracker.wait_next_incoming_message()
|
||||
msg3_in = ac2.wait_next_incoming_message()
|
||||
assert msg3_in.text == "message3"
|
||||
assert msg3_in.is_encrypted()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user