From dc8df67f556694eb788e4c5946ee0f381dc85277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 3 Sep 2018 20:39:16 +0200 Subject: [PATCH] commands: Add backlog fetching back. --- main.py | 2 +- matrix/buffer.py | 24 ++++++++++++++++-------- matrix/commands.py | 6 +++--- matrix/config.py | 17 +++++++++++++++++ matrix/server.py | 36 +++++++++++++++++++++++++++++++++--- 5 files changed, 70 insertions(+), 15 deletions(-) diff --git a/main.py b/main.py index 7230229..071fe23 100644 --- a/main.py +++ b/main.py @@ -55,7 +55,7 @@ from matrix.completion import (init_completion, matrix_command_completion_cb, matrix_user_completion_cb) from matrix.config import (MatrixConfig, config_log_category_cb, config_log_level_cb, config_server_buffer_cb, - matrix_config_reload_cb) + matrix_config_reload_cb, config_pgup_cb) from matrix.globals import SCRIPT_NAME, SERVERS, W from matrix.server import (MatrixServer, create_default_server, matrix_config_server_change_cb, diff --git a/matrix/buffer.py b/matrix/buffer.py index a07f4ea..630bcce 100644 --- a/matrix/buffer.py +++ b/matrix/buffer.py @@ -755,9 +755,10 @@ class WeechatChannelBuffer(object): class RoomBuffer(object): - def __init__(self, room, server_name): + def __init__(self, room, server_name, prev_batch): self.room = room self.backlog_pending = False + self.prev_batch = prev_batch self.joined = True self.leave_event_id = None # type: Optional[str] @@ -1142,11 +1143,13 @@ class RoomBuffer(object): ] tags += self.get_event_tags(event) nick = self.find_nick(event.sender) - data = ( - event.formatted_message.to_weechat() - if event.formatted_message - else event.message - ) + + formatted = None + + if event.formatted_body: + formatted = Formatted.from_html(event.formatted_body) + + data = formatted.to_weechat() if formatted else event.body user = self.weechat_buffer._get_user(nick) date = server_ts_to_weechat(event.server_timestamp) self.weechat_buffer._print_message(user, data, date, tags) @@ -1185,8 +1188,10 @@ class RoomBuffer(object): new.date, new.date_printed, new.tags, new.prefix, new.message ) - def handle_backlog(self, events): - for event in events: + def handle_backlog(self, response): + self.prev_batch = response.end + + for event in response.chunk: if isinstance(event, RoomMessageText): self.old_message(event) elif isinstance(event, RedactedEvent): @@ -1194,6 +1199,9 @@ class RoomBuffer(object): self.sort_messages() + self.backlog_pending = False + W.bar_item_update("buffer_modes") + def handle_joined_room(self, info): for event in info.state: self.handle_state_event(event) diff --git a/matrix/commands.py b/matrix/commands.py index 10d16d2..880f163 100644 --- a/matrix/commands.py +++ b/matrix/commands.py @@ -246,8 +246,8 @@ def hook_commands(): W.hook_command_run("/buffer clear", "matrix_command_buf_clear_cb", "") - # if OPTIONS.enable_backlog: - # hook_page_up() + if G.CONFIG.network.fetch_backlog_on_pgup: + hook_page_up() @utf8_decode @@ -375,7 +375,7 @@ def matrix_command_pgup_cb(data, buffer, command): if first_line_displayed: room_id = key_from_value(server.buffers, buffer) - matrix_fetch_old_messages(server, room_id) + server.room_get_messages(room_id) return W.WEECHAT_RC_OK diff --git a/matrix/config.py b/matrix/config.py index 5a94fad..8daa890 100644 --- a/matrix/config.py +++ b/matrix/config.py @@ -136,6 +136,21 @@ def config_log_category_cb(data, option): return 1 +@utf8_decode +def config_pgup_cb(data, option): + if G.CONFIG.network.fetch_backlog_on_pgup: + if not G.CONFIG.page_up_hook: + G.CONFIG.page_up_hook = W.hook_command_run( + "/window page_up", "matrix_command_pgup_cb", "" + ) + else: + if G.CONFIG.page_up_hook: + W.unhook(G.CONFIG.page_up_hook) + G.CONFIG.page_up_hook = None + + return 1 + + def level_to_logbook(value): if value == 0: return logbook.ERROR @@ -337,6 +352,8 @@ class MatrixConfig(WeechatConfig): 0, "on", ("Fetch messages in the backlog on a window page up event"), + None, + config_pgup_cb, ), Option( "debug_level", diff --git a/matrix/server.py b/matrix/server.py index c53d623..cfbdc94 100644 --- a/matrix/server.py +++ b/matrix/server.py @@ -34,6 +34,7 @@ from nio import ( SyncRepsponse, TransportResponse, TransportType, + RoomMessagesResponse, ) from . import globals as G @@ -218,6 +219,7 @@ class MatrixServer(object): self.device_check_timestamp = None # type: Optional[int] self.own_message_queue = dict() # type: Dict[str, OwnMessage] + self.backlog_queue = dict() # type: Dict[str, str] self.config = ServerConfig(self.name, config_ptr) self._create_session_dir() @@ -581,6 +583,26 @@ class MatrixServer(object): _, request = self.client.room_leave(room_id) self.send_or_queue(request) + def room_get_messages(self, room_id): + room_buffer = self.find_room_from_id(room_id) + + # We're already fetching old messages + if room_buffer.backlog_pending: + return + + if not room_buffer.prev_batch: + return + + uuid, request = self.client.room_messages( + room_id, + room_buffer.prev_batch, + limit=10) + + room_buffer.backlog_pending = True + W.bar_item_update("buffer_modes") + self.backlog_queue[uuid] = room_id + self.send_or_queue(request) + def room_send_message(self, room_buffer, formatted, msgtype="m.text"): # type: (RoomBuffer, Formatted, str) -> None if room_buffer.room.encrypted: @@ -642,6 +664,12 @@ class MatrixServer(object): "Unsupported message of type {}".format(type(message)) ) + def handle_backlog_response(self, response): + room_id = self.backlog_queue.pop(response.uuid) + room_buffer = self.find_room_from_id(room_id) + + room_buffer.handle_backlog(response) + def _handle_login(self, response): self.access_token = response.access_token self.user_id = response.user_id @@ -703,7 +731,7 @@ class MatrixServer(object): for room_id, info in response.rooms.join.items(): if room_id not in self.buffers: - self.create_room_buffer(room_id) + self.create_room_buffer(room_id, info.timeline.prev_batch) room_buffer = self.find_room_from_id(room_id) room_buffer.handle_joined_room(info) @@ -756,10 +784,12 @@ class MatrixServer(object): elif isinstance(response, RoomSendResponse): self.handle_own_messages(response) + elif isinstance(response, RoomMessagesResponse): + self.handle_backlog_response(response) - def create_room_buffer(self, room_id): + def create_room_buffer(self, room_id, prev_batch): room = self.client.rooms[room_id] - buf = RoomBuffer(room, self.name) + buf = RoomBuffer(room, self.name, prev_batch) # TODO this should turned into a propper class self.room_buffers[room_id] = buf self.buffers[room_id] = buf.weechat_buffer._ptr