diff --git a/python/examples/echo_and_quit.py b/python/examples/echo_and_quit.py index 2795923f1..2ad9450e4 100644 --- a/python/examples/echo_and_quit.py +++ b/python/examples/echo_and_quit.py @@ -11,10 +11,11 @@ class EchoPlugin: if message.text.strip() == "/quit": message.account.shutdown() else: - ch = message.get_sender_chat() + # unconditionally accept the chat + message.accept_sender_contact() addr = message.get_sender_contact().addr text = message.text - ch.send_text("echoing from {}:\n{}".format(addr, text)) + message.chat.send_text("echoing from {}:\n{}".format(addr, text)) @deltachat.hookspec.account_hookimpl def process_message_delivered(self, message): diff --git a/python/examples/test_examples.py b/python/examples/test_examples.py index 66d28e828..dc074db82 100644 --- a/python/examples/test_examples.py +++ b/python/examples/test_examples.py @@ -22,7 +22,6 @@ def test_echo_quit_plugin(acfactory): def run_bot(): print("*"*20 + " starting bot") - print("*"*20 + " bot_ac.dbpath", bot_ac.db_path) echo_and_quit.main([ "echo", "--show-ffi", @@ -40,6 +39,7 @@ def test_echo_quit_plugin(acfactory): ch1.send_text("hello") reply = ac1._evtracker.wait_next_incoming_message() assert "hello" in reply.text + assert reply.chat == ch1 ch1.send_text("/quit") t.join() diff --git a/python/src/deltachat/account.py b/python/src/deltachat/account.py index 5c23cbc28..c70c54deb 100644 --- a/python/src/deltachat/account.py +++ b/python/src/deltachat/account.py @@ -283,6 +283,9 @@ class Account(object): """ create or get an existing chat object for the the specified message. + If this message is in the deaddrop chat then + the sender will become an accepted contact. + :param message: messsage id or message instance. :returns: a :class:`deltachat.chat.Chat` object. """ diff --git a/python/src/deltachat/eventlogger.py b/python/src/deltachat/eventlogger.py index 3ac47e290..4be38c63f 100644 --- a/python/src/deltachat/eventlogger.py +++ b/python/src/deltachat/eventlogger.py @@ -128,3 +128,10 @@ class FFIEventTracker: """ wait for and return next incoming message. """ ev = self.get_matching("DC_EVENT_INCOMING_MSG") return self.account.get_message_by_id(ev.data2) + + def wait_next_messages_changed(self): + """ wait for and return next message-changed message or None + if the event contains no msgid""" + ev = self.get_matching("DC_EVENT_MSGS_CHANGED") + if ev.data2 > 0: + return self.account.get_message_by_id(ev.data2) diff --git a/python/src/deltachat/message.py b/python/src/deltachat/message.py index e94ba0e1c..fc63636de 100644 --- a/python/src/deltachat/message.py +++ b/python/src/deltachat/message.py @@ -50,6 +50,16 @@ class Message(object): lib.dc_msg_unref )) + def accept_sender_contact(self): + """ ensure that the sender is an accepted contact + and that the message has a non-deaddrop chat object. + """ + self.account.create_chat_by_message(self) + self._dc_msg = ffi.gc( + lib.dc_get_msg(self._dc_context, self.id), + lib.dc_msg_unref + ) + @props.with_doc def text(self): """unicode text of this messages (might be empty if not a text message). """ diff --git a/python/tests/test_account.py b/python/tests/test_account.py index a51cb38b1..b653159cd 100644 --- a/python/tests/test_account.py +++ b/python/tests/test_account.py @@ -276,7 +276,7 @@ class TestOfflineChat: def test_delete_and_send_fails(self, ac1, chat1): chat1.delete() - ac1._evtracker.get_matching("DC_EVENT_MSGS_CHANGED") + ac1._evtracker.wait_next_messages_changed() with pytest.raises(ValueError): chat1.send_text("msg1") @@ -625,8 +625,8 @@ class TestOnlineAccount: ev = ac1._evtracker.get_matching("DC_EVENT_DELETED_BLOB_FILE") # Second client receives only second message, but not the first - ev = ac1_clone._evtracker.get_matching("DC_EVENT_MSGS_CHANGED") - assert ac1_clone.get_message_by_id(ev.data2).text == msg_out.text + ev_msg = ac1_clone._evtracker.wait_next_messages_changed() + assert ev_msg.text == msg_out.text def test_send_file_twice_unicode_filename_mangling(self, tmpdir, acfactory, lp): ac1, ac2 = acfactory.get_two_online_accounts() @@ -1377,6 +1377,15 @@ class TestOnlineAccount: assert chat1b.get_profile_image() is None assert chat.get_profile_image() is None + def test_accept_sender_contact(self, acfactory, lp): + ac1, ac2 = acfactory.get_two_online_accounts() + ch = ac1.create_chat_by_contact(ac1.create_contact(ac2.get_config("addr"))) + ch.send_text("hello") + msg = ac2._evtracker.wait_next_messages_changed() + assert msg.chat.is_deaddrop() + msg.accept_sender_contact() + assert not msg.chat.is_deaddrop() + def test_send_receive_locations(self, acfactory, lp): now = datetime.utcnow() ac1, ac2 = acfactory.get_two_online_accounts()