buffer: Handle messages containing a transaction id.

This commit is contained in:
Damir Jelić 2018-11-05 21:59:25 +01:00
parent fd9053eacd
commit 59b318bdce
2 changed files with 49 additions and 11 deletions

View file

@ -21,6 +21,7 @@ import time
from builtins import super from builtins import super
from functools import partial from functools import partial
from typing import Dict, List, NamedTuple, Optional, Set from typing import Dict, List, NamedTuple, Optional, Set
from uuid import UUID
from nio import ( from nio import (
Api, Api,
@ -810,6 +811,9 @@ class RoomBuffer(object):
self.unhandled_users = [] # type: List[str] self.unhandled_users = [] # type: List[str]
self.inactive_users = [] self.inactive_users = []
self.sent_messages_queue = dict() # type: Dict[UUID, OwnMessage]
self.printed_before_ack_queue = list() # type: List[UUID]
buffer_name = "{}.{}".format(server_name, room.room_id) buffer_name = "{}.{}".format(server_name, room.room_id)
# This dict remembers the connection from a user_id to the name we # This dict remembers the connection from a user_id to the name we
@ -1081,6 +1085,36 @@ class RoomBuffer(object):
elif isinstance(event, RoomEncryptionEvent): elif isinstance(event, RoomEncryptionEvent):
pass pass
def handle_own_message_in_timeline(self, event):
"""Check if our own message is already printed if not print it.
This function is called for messages that contain a transaction id
indicating that they were sent out using our own client. If we sent out
a message but never got a valid server response (e.g. due to
disconnects) this function prints them out using data from the next
sync response"""
uuid = UUID(event.transaction_id)
message = self.sent_messages_queue.pop(uuid, None)
# We already got a response to the room_send_message() API call and
# handled the message, no need to print it out again
if not message:
return
message = message._replace(event_id=event.event_id)
if uuid in self.printed_before_ack_queue:
self.replace_printed_line_by_uuid(
event.transaction_id,
message
)
self.printed_before_ack_queue.remove(uuid)
return
if isinstance(message, OwnAction):
self.self_action(message)
elif isinstance(message, OwnMessage):
self.self_message(message)
return
def handle_timeline_event(self, event): def handle_timeline_event(self, event):
# TODO this should be done for every messagetype that gets printed in # TODO this should be done for every messagetype that gets printed in
# the buffer # the buffer
@ -1095,6 +1129,10 @@ class RoomBuffer(object):
self.add_user(event.sender, 0, True, True) self.add_user(event.sender, 0, True, True)
if event.transaction_id:
self.handle_own_message_in_timeline(event)
return
if isinstance(event, RoomMemberEvent): if isinstance(event, RoomMemberEvent):
self.handle_membership_events(event, False) self.handle_membership_events(event, False)

View file

@ -247,8 +247,6 @@ class MatrixServer(object):
self.device_deletion_queue = dict() self.device_deletion_queue = dict()
self.own_message_queue = dict() # type: Dict[str, OwnMessage]
self.print_before_ack_queue = [] # type: List[UUID]
self.encryption_queue = defaultdict(deque) \ self.encryption_queue = defaultdict(deque) \
# type: DefaultDict[str, Deque[EncrytpionQueueItem]] # type: DefaultDict[str, Deque[EncrytpionQueueItem]]
self.backlog_queue = dict() # type: Dict[str, str] self.backlog_queue = dict() # type: Dict[str, str]
@ -723,11 +721,11 @@ class MatrixServer(object):
self.user_id, 0, "", uuid, room.room_id, formatted self.user_id, 0, "", uuid, room.room_id, formatted
) )
self.own_message_queue[uuid] = own_message room_buffer.sent_messages_queue[uuid] = own_message
self.send_or_queue(request) self.send_or_queue(request)
if G.CONFIG.network.print_unconfirmed_messages: if G.CONFIG.network.print_unconfirmed_messages:
self.print_before_ack_queue.append(uuid) room_buffer.printed_before_ack_queue.append(uuid)
plain_message = formatted.to_weechat() plain_message = formatted.to_weechat()
plain_message = W.string_remove_color(plain_message, "") plain_message = W.string_remove_color(plain_message, "")
attributes = DEFAULT_ATRIBUTES.copy() attributes = DEFAULT_ATRIBUTES.copy()
@ -781,22 +779,24 @@ class MatrixServer(object):
server_buffer_prnt(self, pprint.pformat(message.response.body)) server_buffer_prnt(self, pprint.pformat(message.response.body))
def handle_own_messages_error(self, response): def handle_own_messages_error(self, response):
message = self.own_message_queue.pop(response.uuid) room_buffer = self.room_buffers[response.room_id]
if response.uuid not in self.print_before_ack_queue:
if response.uuid not in room_buffer.printed_before_ack_queue:
return return
room_buffer = self.room_buffers[message.room_id] message = room_buffer.sent_messages_queue.pop(response.uuid)
room_buffer.mark_message_as_unsent(response.uuid, message) room_buffer.mark_message_as_unsent(response.uuid, message)
room_buffer.printed_before_ack_queue.remove(response.uuid)
def handle_own_messages(self, response): def handle_own_messages(self, response):
message = self.own_message_queue.pop(response.uuid) room_buffer = self.room_buffers[response.room_id]
room_buffer = self.room_buffers[message.room_id] message = room_buffer.sent_messages_queue.pop(response.uuid)
message = message._replace(event_id=response.event_id) message = message._replace(event_id=response.event_id)
# We already printed the message, just modify it to contain the proper # We already printed the message, just modify it to contain the proper
# colors and formatting. # colors and formatting.
if response.uuid in self.print_before_ack_queue: if response.uuid in room_buffer.printed_before_ack_queue:
room_buffer.replace_printed_line_by_uuid(response.uuid, message) room_buffer.replace_printed_line_by_uuid(response.uuid, message)
room_buffer.printed_before_ack_queue.remove(response.uuid)
return return
if isinstance(message, OwnAction): if isinstance(message, OwnAction):