diff --git a/weechat-matrix.py b/weechat-matrix.py index 57fa33d..e8dceae 100644 --- a/weechat-matrix.py +++ b/weechat-matrix.py @@ -7,6 +7,7 @@ import socket import ssl import time import datetime +import re # pylint: disable=redefined-builtin from builtins import bytes @@ -115,6 +116,7 @@ class MessageType(Enum): SYNC = 1 SEND = 2 STATE = 3 + REDACT = 4 @unique @@ -174,7 +176,7 @@ class HttpRequest: host, # type: unicode port, # type: int location, # type: unicode - data=None, # type: Dict[unicode, any] + data=None, # type: Dict[unicode, Any] user_agent='weechat-matrix/{version}'.format( version=WEECHAT_SCRIPT_VERSION) # type: unicode ): @@ -224,13 +226,20 @@ class HttpRequest: self.payload = payload +def get_transaction_id(server): + # type: (MatrixServer) -> int + transaction_id = server.transaction_id + server.transaction_id += 1 + return transaction_id + + class MatrixMessage: def __init__( self, server, # type: MatrixServer message_type, # type: MessageType room_id=None, # type: unicode - event_type=None, # type: unicode + extra_id=None, # type: unicode data=None, # type: Dict[unicode, Any] extra_data=None # type: Dict[unicode, Any] ): @@ -296,7 +305,24 @@ class MatrixMessage: "access_token={access_token}").format( api=MATRIX_API_PATH, room=room_id, - event_type=event_type, + event_type=extra_id, + access_token=server.access_token) + + self.request = HttpRequest( + RequestType.PUT, + server.address, + server.port, + path, + data + ) + + elif message_type == MessageType.REDACT: + path = ("{api}/rooms/{room}/redact/{event_id}/{tx_id}?" + "access_token={access_token}").format( + api=MATRIX_API_PATH, + room=room_id, + event_id=extra_id, + tx_id=get_transaction_id(server), access_token=server.access_token) self.request = HttpRequest( @@ -325,7 +351,7 @@ def key_from_value(dictionary, value): @utf8_decode def server_config_change_cb(server_name, option): - # type: (unicode, weechat.config_option) -> bool + # type: (unicode, weechat.config_option) -> int server = SERVERS[server_name] option_name = None @@ -383,6 +409,7 @@ class MatrixServer: self.access_token = None # type: unicode self.next_batch = None # type: unicode + self.transaction_id = 0 # type: int self.http_parser = HttpParser() # type: HttpParser self.http_buffer = [] # type: List[bytes] @@ -613,12 +640,18 @@ def matrix_handle_room_text_message(server, room_id, event): def matrix_handle_redacted_message(server, room_id, event): # type: (MatrixServer, unicode, Dict[Any, Any]) -> None + reason = ">" censor = strip_matrix_server( event['unsigned']['redacted_because']['sender'] )[1:] - msg = ("(Message redacted by: {censor}{reason}").format( + + if 'reason' in event['unsigned']['redacted_because']['content']: + reason = ", reason: \"{reason}\">".format( + reason=event['unsigned']['redacted_because']['content']['reason']) + + msg = (" unicode + own_lines = W.hdata_pointer(W.hdata_get('buffer'), buf, 'own_lines') + if own_lines: + line = W.hdata_pointer( + W.hdata_get('lines'), + own_lines, + 'last_line' + ) + + line_number = 1 + + while line: + line_data = W.hdata_pointer( + W.hdata_get('line'), + line, + 'data' + ) + + if line_data: + tags_count = W.hdata_get_var_array_size( + W.hdata_get('line_data'), + line_data, + 'tags_array' + ) + + tags = [ + W.hdata_string( + W.hdata_get('line_data'), + line_data, + '%d|tags_array' % i + ) for i in range(tags_count)] + + # Only count non redacted user messages + if ('matrix_message' in tags + and 'matrix_redacted' not in tags): + + if line_number == target_number: + for tag in tags: + if tag.startswith("matrix_id"): + event_id = tag[10:] + return event_id + + line_number += 1 + + line = W.hdata_move(W.hdata_get('line'), line, -1) + + return "" + + +@utf8_decode def matrix_redact_command_cb(data, buffer, args): - W.prnt("", args) + for server in SERVERS.values(): + if buffer in server.buffers.values(): + body = {} + + room_id = key_from_value(server.buffers, buffer) + + matches = re.match(r"(\d+)(:\".*\")? ?(.*)?", args) + + if not matches: + return W.WEECHAT_RC_ERROR + + line_string, _, reason = matches.groups() + line = int(line_string) + + if reason: + body = {"reason": reason} + + event_id = event_id_from_line(buffer, line) + + if not event_id: + print("EERRRRRORRRR") + + message = MatrixMessage( + server, + MessageType.REDACT, + data=body, + room_id=room_id, + extra_id=event_id + ) + send_or_queue(server, message) + + return W.WEECHAT_RC_OK_EAT + + elif buffer == server.server_buffer: + message = ("{prefix}matrix: command \"redact\" must be " + "executed on a Matrix channel buffer").format( + prefix=W.prefix("error")) + W.prnt(buffer, message) + return W.WEECHAT_RC_OK + return W.WEECHAT_RC_OK +@utf8_decode def matrix_message_completion_cb(data, completion_item, buffer, completion): own_lines = W.hdata_pointer(W.hdata_get('buffer'), buffer, 'own_lines') if own_lines: