diff --git a/matrix/buffer.py b/matrix/buffer.py index a170623..de5c71a 100644 --- a/matrix/buffer.py +++ b/matrix/buffer.py @@ -228,7 +228,7 @@ class WeechatChannelBuffer(object): @date.setter def date(self, new_date): # type: (int) -> None - new_data = {"date": new_date} + new_data = {"date": str(new_date)} W.hdata_update(self._hdata, self._ptr, new_data) @property @@ -239,7 +239,7 @@ class WeechatChannelBuffer(object): @date_printed.setter def date_printed(self, new_date): # type: (int) -> None - new_data = {"date_printed": new_date} + new_data = {"date_printed": str(new_date)} W.hdata_update(self._hdata, self._ptr, new_data) @property @@ -247,16 +247,32 @@ class WeechatChannelBuffer(object): # type: () -> bool return bool(W.hdata_char(self._hdata, self._ptr, "highlight")) - def update(self, date, date_printed, tags, prefix, message): - new_data = { - "date": date, - "date_printed": date_printed, - "tags_array": ','.join(tags), - "prefix": prefix, - "message": message, - # "highlight": highlight - } - W.hdata_update(self._hdata, self._ptr, new_data) + def update( + self, + date=None, + date_printed=None, + tags=None, + prefix=None, + message=None, + highlight=None + ): + new_data = {} + + if date: + new_data["date"] = str(date) + if date_printed: + new_data["date_printed"] = str(date_printed) + if tags: + new_data["tags_array"] = ','.join(tags) + if prefix: + new_data["prefix"] = prefix + if message: + new_data["message"] = message + if highlight: + new_data["highlight"] = highlight + + if new_data: + W.hdata_update(self._hdata, self._ptr, new_data) def __init__(self, name, server_name, user): # type: (str, str, str) @@ -953,3 +969,86 @@ class RoomBuffer(object): nick = self.find_nick(self.room.own_user_id) date = server_ts_to_weechat(message.timestamp) self.weechat_buffer.self_action(nick, message.message, date) + + def old_redacted(self, event): + tags = [ + SCRIPT_NAME + "_message", + "notify_message", + "no_log", + "no_highlight" + ] + reason = (", reason: \"{reason}\"".format(reason=event.reason) + if event.reason else "") + + censor = self.find_nick(event.censor) + + data = ("{del_color}<{log_color}Message redacted by: " + "{censor}{log_color}{reason}{del_color}>{ncolor}").format( + del_color=W.color("chat_delimiters"), + ncolor=W.color("reset"), + log_color=W.color("logger.color.backlog_line"), + censor=censor, + reason=reason) + + tags += self.get_event_tags(event) + nick = self.find_nick(event.sender) + user = self.weechat_buffer._get_user(nick) + date = server_ts_to_weechat(event.timestamp) + self.weechat_buffer._print_message(user, data, date, tags) + + def old_message(self, event): + tags = [ + SCRIPT_NAME + "_message", + "notify_message", + "no_log", + "no_highlight" + ] + 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) + user = self.weechat_buffer._get_user(nick) + date = server_ts_to_weechat(event.timestamp) + self.weechat_buffer._print_message(user, data, date, tags) + + def sort_messages(self): + class LineCopy(object): + def __init__( + self, + date, + date_printed, + tags, + prefix, + message, + highlight + ): + self.date = date + self.date_printed = date_printed + self.tags = tags + self.prefix = prefix + self.message = message + self.highlight = highlight + + @classmethod + def from_line(cls, line): + return cls(line.date, line.date_printed, line.tags, + line.prefix, line.message, line.highlight) + + lines = [ + LineCopy.from_line(line) for line in self.weechat_buffer.lines + ] + sorted_lines = sorted(lines, key=lambda line: line.date, reverse=True) + + for n, line in enumerate(self.weechat_buffer.lines): + new = sorted_lines[n] + line.update(new.date, new.date_printed, new.tags, new.prefix, + new.message) + + def handle_backlog(self, events): + for event in events: + if isinstance(event, RoomMessageText): + self.old_message(event) + elif isinstance(event, RoomRedactedMessageEvent): + self.old_redacted(event) + + self.sort_messages() diff --git a/matrix/events.py b/matrix/events.py index fb24c0c..0a38034 100644 --- a/matrix/events.py +++ b/matrix/events.py @@ -427,72 +427,6 @@ class MatrixBacklogEvent(MatrixEvent): return RoomMessageEvent.from_dict(event_dict) - @staticmethod - def buffer_sort_messages(buff): - lines = [] - - own_lines = W.hdata_pointer(W.hdata_get('buffer'), buff, 'own_lines') - - if own_lines: - hdata_line = W.hdata_get('line') - hdata_line_data = W.hdata_get('line_data') - line = W.hdata_pointer( - W.hdata_get('lines'), own_lines, 'first_line') - - while line: - data = W.hdata_pointer(hdata_line, line, 'data') - - line_data = {} - - if data: - date = W.hdata_time(hdata_line_data, data, 'date') - print_date = W.hdata_time(hdata_line_data, data, - 'date_printed') - tags = tags_from_line_data(data) - prefix = W.hdata_string(hdata_line_data, data, 'prefix') - message = W.hdata_string(hdata_line_data, data, 'message') - highlight = W.hdata_char(hdata_line_data, data, "highlight") - - line_data = { - 'date': date, - 'date_printed': print_date, - 'tags_array': ','.join(tags), - 'prefix': prefix, - 'message': message, - 'highlight': highlight - } - - lines.append(line_data) - - line = W.hdata_move(hdata_line, line, 1) - - sorted_lines = sorted(lines, key=itemgetter('date')) - lines = [] - - # We need to convert the dates to a string for hdata_update(), this - # will reverse the list at the same time - while sorted_lines: - line = sorted_lines.pop() - new_line = {k: str(v) for k, v in line.items()} - lines.append(new_line) - - MatrixBacklogEvent.update_buffer_lines(lines, own_lines) - - @staticmethod - def update_buffer_lines(new_lines, own_lines): - hdata_line = W.hdata_get('line') - hdata_line_data = W.hdata_get('line_data') - - line = W.hdata_pointer(W.hdata_get('lines'), own_lines, 'first_line') - - while line: - data = W.hdata_pointer(hdata_line, line, 'data') - - if data: - W.hdata_update(hdata_line_data, data, new_lines.pop()) - - line = W.hdata_move(hdata_line, line, 1) - @classmethod def from_dict(cls, server, room_id, parsed_dict): try: @@ -515,19 +449,6 @@ class MatrixBacklogEvent(MatrixEvent): return MatrixErrorEvent.from_dict(server, "Error fetching backlog", False, parsed_dict) - def execute(self): - room = self.server.rooms[self.room_id] - buff = self.server.buffers[self.room_id] - tags = tags_for_message("backlog") - - for event in self.events: - event.execute(self.server, room, buff, list(tags)) - - room.prev_batch = self.end_token - MatrixBacklogEvent.buffer_sort_messages(buff) - room.backlog_pending = False - W.bar_item_update("buffer_modes") - class MatrixSyncEvent(MatrixEvent): diff --git a/matrix/server.py b/matrix/server.py index e540915..ca51595 100644 --- a/matrix/server.py +++ b/matrix/server.py @@ -52,7 +52,10 @@ from matrix.api import ( MatrixKeyClaimMessage ) -from .events import MatrixSendEvent +from .events import ( + MatrixSendEvent, + MatrixBacklogEvent +) from matrix.encryption import ( Olm, @@ -697,6 +700,14 @@ class MatrixServer: if isinstance(response, MatrixSendEvent): _, room_buffer = self.find_room_from_id(response.room_id) self.handle_own_messages(room_buffer, response.message) + + elif isinstance(response, MatrixBacklogEvent): + room, room_buffer = self.find_room_from_id(response.room_id) + room_buffer.handle_backlog(response.events) + room.prev_batch = response.end_token + room.backlog_pending = False + W.bar_item_update("buffer_modes") + else: response.execute()