buffer: Store undecrytped events so we can try to decrypt them later.
This commit is contained in:
parent
bdb7f4509e
commit
a0199109be
2 changed files with 67 additions and 0 deletions
|
@ -20,6 +20,7 @@ from __future__ import unicode_literals
|
|||
import time
|
||||
from builtins import super
|
||||
from functools import partial
|
||||
from collections import deque
|
||||
from typing import Dict, List, NamedTuple, Optional, Set
|
||||
from uuid import UUID
|
||||
|
||||
|
@ -816,6 +817,7 @@ class RoomBuffer(object):
|
|||
|
||||
self.sent_messages_queue = dict() # type: Dict[UUID, OwnMessage]
|
||||
self.printed_before_ack_queue = list() # type: List[UUID]
|
||||
self.undecrypted_events = deque(maxlen=5000)
|
||||
|
||||
buffer_name = "{}.{}".format(server_name, room.room_id)
|
||||
|
||||
|
@ -1300,6 +1302,8 @@ class RoomBuffer(object):
|
|||
self.get_event_tags(event) + [session_id_tag]
|
||||
)
|
||||
|
||||
self.undecrypted_events.append(event)
|
||||
|
||||
else:
|
||||
W.prnt(
|
||||
"", "Unhandled event of type {}.".format(type(event).__name__)
|
||||
|
@ -1384,6 +1388,43 @@ class RoomBuffer(object):
|
|||
new_tags.append(SCRIPT_NAME + "_id_" + new_message.event_id)
|
||||
line.tags = new_tags
|
||||
|
||||
def replace_undecrypted_line(self, event):
|
||||
"""Find a undecrypted message in the buffer and replace it with the now
|
||||
decrypted event."""
|
||||
# TODO different messages need different formatting
|
||||
# To implement this, refactor out the different formatting code
|
||||
# snippets to a Formatter class and reuse them here.
|
||||
if not isinstance(event, RoomMessageText):
|
||||
return
|
||||
|
||||
def predicate(event_id, line):
|
||||
event_tag = SCRIPT_NAME + "_id_{}".format(event_id)
|
||||
if event_tag in line.tags:
|
||||
return True
|
||||
return False
|
||||
|
||||
lines = self.weechat_buffer.find_lines(
|
||||
partial(predicate, event.event_id)
|
||||
)
|
||||
|
||||
if not lines:
|
||||
return
|
||||
|
||||
formatted = None
|
||||
if event.formatted_body:
|
||||
formatted = Formatted.from_html(event.formatted_body)
|
||||
|
||||
data = formatted.to_weechat() if formatted else event.body
|
||||
# TODO this isn't right if the data has multiple lines, that is
|
||||
# everything is printed on a signle line and newlines are shown as a
|
||||
# space.
|
||||
# Weechat should support deleting lines and printing new ones at an
|
||||
# arbitrary position.
|
||||
# To implement this without weechat support either only handle single
|
||||
# line messages or edit the first line in place, print new ones at the
|
||||
# bottom and sort the buffer lines.
|
||||
lines[0].message = data
|
||||
|
||||
def old_redacted(self, event):
|
||||
tags = [
|
||||
SCRIPT_NAME + "_message",
|
||||
|
|
|
@ -957,6 +957,28 @@ class MatrixServer(object):
|
|||
"matrix_load_users_cb", self.name)
|
||||
self.lazy_load_hook = hook
|
||||
|
||||
def decrypt_printed_messages(self, key_event):
|
||||
"""Decrypt already printed messages and send them to the buffer"""
|
||||
try:
|
||||
room_buffer = self.find_room_from_id(key_event.room_id)
|
||||
except KeyError:
|
||||
return
|
||||
|
||||
decrypted_events = []
|
||||
|
||||
for undecrypted_event in room_buffer.undecrypted_events:
|
||||
if undecrypted_event.session_id != key_event.session_id:
|
||||
continue
|
||||
|
||||
event = self.client.decrypt_event(undecrypted_event)
|
||||
if event:
|
||||
decrypted_events.append((undecrypted_event, event))
|
||||
|
||||
for event_pair in decrypted_events:
|
||||
undecrypted_event, event = event_pair
|
||||
room_buffer.undecrypted_events.remove(undecrypted_event)
|
||||
room_buffer.replace_undecrypted_line(event)
|
||||
|
||||
def _handle_sync(self, response):
|
||||
# we got the same batch again, nothing to do
|
||||
if self.next_batch == response.next_batch:
|
||||
|
@ -979,6 +1001,10 @@ class MatrixServer(object):
|
|||
}
|
||||
W.hook_hsignal_send("matrix_room_key_received", message)
|
||||
|
||||
# TODO try to decrypt some cached undecrypted messages with the
|
||||
# new key
|
||||
# self.decrypt_printed_messages(event)
|
||||
|
||||
# Full sync response handle everything.
|
||||
if isinstance(response, SyncResponse):
|
||||
if self.client.should_upload_keys:
|
||||
|
|
Loading…
Add table
Reference in a new issue