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 functools import partial
from typing import Dict, List, NamedTuple, Optional, Set
from uuid import UUID
from nio import (
Api,
@ -810,6 +811,9 @@ class RoomBuffer(object):
self.unhandled_users = [] # type: List[str]
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)
# This dict remembers the connection from a user_id to the name we
@ -1081,6 +1085,36 @@ class RoomBuffer(object):
elif isinstance(event, RoomEncryptionEvent):
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):
# TODO this should be done for every messagetype that gets printed in
# the buffer
@ -1095,6 +1129,10 @@ class RoomBuffer(object):
self.add_user(event.sender, 0, True, True)
if event.transaction_id:
self.handle_own_message_in_timeline(event)
return
if isinstance(event, RoomMemberEvent):
self.handle_membership_events(event, False)

View file

@ -247,8 +247,6 @@ class MatrixServer(object):
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) \
# type: DefaultDict[str, Deque[EncrytpionQueueItem]]
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.own_message_queue[uuid] = own_message
room_buffer.sent_messages_queue[uuid] = own_message
self.send_or_queue(request)
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 = W.string_remove_color(plain_message, "")
attributes = DEFAULT_ATRIBUTES.copy()
@ -781,22 +779,24 @@ class MatrixServer(object):
server_buffer_prnt(self, pprint.pformat(message.response.body))
def handle_own_messages_error(self, response):
message = self.own_message_queue.pop(response.uuid)
if response.uuid not in self.print_before_ack_queue:
room_buffer = self.room_buffers[response.room_id]
if response.uuid not in room_buffer.printed_before_ack_queue:
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.printed_before_ack_queue.remove(response.uuid)
def handle_own_messages(self, response):
message = self.own_message_queue.pop(response.uuid)
room_buffer = self.room_buffers[message.room_id]
room_buffer = self.room_buffers[response.room_id]
message = room_buffer.sent_messages_queue.pop(response.uuid)
message = message._replace(event_id=response.event_id)
# We already printed the message, just modify it to contain the proper
# 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.printed_before_ack_queue.remove(response.uuid)
return
if isinstance(message, OwnAction):