mirror of
https://github.com/deltachat/deltachat-core.git
synced 2025-10-04 10:19:16 +02:00
introduce message.get_state() API which provides is_in_delivered()|is_out_delivered|... methods.
This commit is contained in:
parent
959ac73122
commit
da2bcd0c5a
4 changed files with 96 additions and 16 deletions
|
@ -2,7 +2,7 @@ from deltachat import capi
|
|||
from deltachat.capi import ffi
|
||||
from deltachat.account import Account # noqa
|
||||
|
||||
__version__ = "0.5.dev0"
|
||||
__version__ = "0.5.dev1"
|
||||
|
||||
|
||||
_DC_CALLBACK_MAP = {}
|
||||
|
|
|
@ -12,7 +12,7 @@ deltah = joinpath(dirname(dirname(dirname(here))), "src", "deltachat.h")
|
|||
|
||||
|
||||
def read_event_defines():
|
||||
rex = re.compile(r'#define\s+(?:DC_EVENT_|DC_CONTACT_ID_|DC_GCL|DC_CHAT)\S+\s+([x\d]+).*')
|
||||
rex = re.compile(r'#define\s+(?:DC_EVENT_|DC_STATE_|DC_CONTACT_ID_|DC_GCL|DC_CHAT)\S+\s+([x\d]+).*')
|
||||
return filter(rex.match, open(deltah))
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
""" Chatting related objects: Contact, Chat, Message. """
|
||||
""" chatting related objects: Contact, Chat, Message. """
|
||||
|
||||
from . import capi
|
||||
from .cutil import convert_to_bytes_utf8, ffi_unicode, iter_array_and_unref
|
||||
|
@ -114,10 +114,22 @@ class Message(object):
|
|||
def dc_msg_t(self):
|
||||
return capi.lib.dc_get_msg(self.dc_context, self.id)
|
||||
|
||||
def _refresh(self):
|
||||
if hasattr(self, "_property_cache"):
|
||||
lib.dc_msg_unref(self.dc_msg_t)
|
||||
self._property_cache.clear()
|
||||
|
||||
def __del__(self):
|
||||
if lib is not None and hasattr(self, "_property_cache"):
|
||||
lib.dc_msg_unref(self.dc_msg_t)
|
||||
|
||||
def get_state(self):
|
||||
""" get the message in/out state.
|
||||
|
||||
:returns: :class:`MessageState`
|
||||
"""
|
||||
return MessageState(self)
|
||||
|
||||
@property_with_doc
|
||||
def text(self):
|
||||
"""unicode representation. """
|
||||
|
@ -131,3 +143,63 @@ class Message(object):
|
|||
"""
|
||||
chat_id = capi.lib.dc_msg_get_chat_id(self.dc_msg_t)
|
||||
return Chat(self.dc_context, chat_id)
|
||||
|
||||
|
||||
@attr.s
|
||||
class MessageState(object):
|
||||
""" Current Message In/Out state, updated on each call of is_* methods.
|
||||
"""
|
||||
message = attr.ib(validator=v.instance_of(Message))
|
||||
|
||||
@property
|
||||
def _msgstate(self):
|
||||
self.message._refresh()
|
||||
return lib.dc_msg_get_state(self.message.dc_msg_t)
|
||||
|
||||
def is_in_fresh(self):
|
||||
""" return True if Message is incoming fresh message (un-noticed).
|
||||
|
||||
Fresh messages are not noticed nor seen and are typically
|
||||
shown in notifications.
|
||||
"""
|
||||
return self._msgstate == lib.DC_STATE_IN_FRESH
|
||||
|
||||
def is_in_noticed(self):
|
||||
"""Return True if Message is incoming and noticed.
|
||||
|
||||
Eg. chat opened but message not yet read - noticed messages
|
||||
are not counted as unread but were not marked as read nor resulted in MDNs.
|
||||
"""
|
||||
return self._msgstate == lib.DC_STATE_IN_NOTICED
|
||||
|
||||
def is_in_seen(self):
|
||||
"""Return True if Message is incoming, noticed and has been seen.
|
||||
|
||||
Eg. chat opened but message not yet read - noticed messages
|
||||
are not counted as unread but were not marked as read nor resulted in MDNs.
|
||||
"""
|
||||
return self._msgstate == lib.DC_STATE_IN_SEEN
|
||||
|
||||
def is_out_pending(self):
|
||||
"""Return True if Message is outgoing, but is pending (no single checkmark).
|
||||
"""
|
||||
return self._msgstate == lib.DC_STATE_OUT_PENDING
|
||||
|
||||
def is_out_failed(self):
|
||||
"""Return True if Message is unrecoverably failed.
|
||||
"""
|
||||
return self._msgstate == lib.DC_STATE_OUT_FAILED
|
||||
|
||||
def is_out_delivered(self):
|
||||
"""Return True if Message was successfully delivered to the server (one checkmark).
|
||||
|
||||
Note, that already delivered messages may get into the state is_out_failed().
|
||||
"""
|
||||
return self._msgstate == lib.DC_STATE_OUT_DELIVERED
|
||||
|
||||
def is_out_mdn_received(self):
|
||||
"""Return True if message was marked as read by the recipient(s) (two checkmarks;
|
||||
this requires goodwill on the receiver's side). If a sent message changes to this
|
||||
state, you'll receive the event DC_EVENT_MSG_READ.
|
||||
"""
|
||||
return self._msgstate == lib.DC_STATE_OUT_MDN_RCVD
|
||||
|
|
|
@ -56,6 +56,15 @@ class TestOfflineAccount:
|
|||
chat = ac1.create_chat_by_contact(contact1)
|
||||
msg = chat.send_text_message("msg1")
|
||||
assert msg
|
||||
msg_state = msg.get_state()
|
||||
assert not msg_state.is_in_fresh()
|
||||
assert not msg_state.is_in_noticed()
|
||||
assert not msg_state.is_in_seen()
|
||||
# XXX the following line should work but doesn't:
|
||||
# assert msg_state.is_out_pending()
|
||||
assert not msg_state.is_out_failed()
|
||||
assert not msg_state.is_out_delivered()
|
||||
assert not msg_state.is_out_mdn_received()
|
||||
|
||||
|
||||
class TestOnlineAccount:
|
||||
|
@ -103,26 +112,27 @@ class TestOnlineAccount:
|
|||
self.wait_successful_IMAP_SMTP_connection(ac2)
|
||||
self.wait_configuration_progress(ac1, 1000)
|
||||
self.wait_configuration_progress(ac2, 1000)
|
||||
msg = chat.send_text_message("msg1")
|
||||
msg_out = chat.send_text_message("message1")
|
||||
ev = ac1._evlogger.get_matching("DC_EVENT_MSG_DELIVERED")
|
||||
evt_name, data1, data2 = ev
|
||||
assert data1 == chat.id
|
||||
assert data2 == msg.id
|
||||
assert data2 == msg_out.id
|
||||
assert msg_out.get_state().is_out_delivered()
|
||||
|
||||
# wait for other account to receive
|
||||
ev = ac2._evlogger.get_matching("DC_EVENT_MSGS_CHANGED")
|
||||
assert ev[2] == msg.id
|
||||
msg2 = ac2.get_message_by_id(msg.id)
|
||||
assert msg2.text == "msg1"
|
||||
assert ev[2] == msg_out.id
|
||||
msg_in = ac2.get_message_by_id(msg_out.id)
|
||||
assert msg_in.text == "message1"
|
||||
|
||||
# check the message arrived in contact-requets/deaddrop
|
||||
chat2 = msg2.chat
|
||||
assert msg2 in chat2.get_messages()
|
||||
chat2 = msg_in.chat
|
||||
assert msg_in in chat2.get_messages()
|
||||
assert chat2.is_deaddrop()
|
||||
assert chat2.count_fresh_messages() == 0
|
||||
|
||||
# create new chat with contact and verify it's proper
|
||||
chat2b = ac2.create_chat_by_message(msg2)
|
||||
chat2b = ac2.create_chat_by_message(msg_in)
|
||||
assert not chat2b.is_deaddrop()
|
||||
assert chat2b.count_fresh_messages() == 1
|
||||
|
||||
|
@ -131,8 +141,6 @@ class TestOnlineAccount:
|
|||
assert chat2b.count_fresh_messages() == 0
|
||||
|
||||
# mark messages as seen and check ac1 sees the MDN
|
||||
ac2.mark_seen_messages([msg2])
|
||||
while 1:
|
||||
ev = ac1._evlogger.get_matching("DC_EVENT_INFO")
|
||||
if "Marking message" in ev[2]:
|
||||
break
|
||||
ac2.mark_seen_messages([msg_in])
|
||||
ac1._evlogger.get_matching("DC_EVENT_MSGS_CHANGED")
|
||||
assert msg_out.get_state().is_out_mdn_received()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue