Fully implemented /redact command.
This commit is contained in:
parent
5aba3052fd
commit
fdc44ba1f9
1 changed files with 138 additions and 10 deletions
|
@ -7,6 +7,7 @@ import socket
|
||||||
import ssl
|
import ssl
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
|
import re
|
||||||
|
|
||||||
# pylint: disable=redefined-builtin
|
# pylint: disable=redefined-builtin
|
||||||
from builtins import bytes
|
from builtins import bytes
|
||||||
|
@ -115,6 +116,7 @@ class MessageType(Enum):
|
||||||
SYNC = 1
|
SYNC = 1
|
||||||
SEND = 2
|
SEND = 2
|
||||||
STATE = 3
|
STATE = 3
|
||||||
|
REDACT = 4
|
||||||
|
|
||||||
|
|
||||||
@unique
|
@unique
|
||||||
|
@ -174,7 +176,7 @@ class HttpRequest:
|
||||||
host, # type: unicode
|
host, # type: unicode
|
||||||
port, # type: int
|
port, # type: int
|
||||||
location, # type: unicode
|
location, # type: unicode
|
||||||
data=None, # type: Dict[unicode, any]
|
data=None, # type: Dict[unicode, Any]
|
||||||
user_agent='weechat-matrix/{version}'.format(
|
user_agent='weechat-matrix/{version}'.format(
|
||||||
version=WEECHAT_SCRIPT_VERSION) # type: unicode
|
version=WEECHAT_SCRIPT_VERSION) # type: unicode
|
||||||
):
|
):
|
||||||
|
@ -224,13 +226,20 @@ class HttpRequest:
|
||||||
self.payload = payload
|
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:
|
class MatrixMessage:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
server, # type: MatrixServer
|
server, # type: MatrixServer
|
||||||
message_type, # type: MessageType
|
message_type, # type: MessageType
|
||||||
room_id=None, # type: unicode
|
room_id=None, # type: unicode
|
||||||
event_type=None, # type: unicode
|
extra_id=None, # type: unicode
|
||||||
data=None, # type: Dict[unicode, Any]
|
data=None, # type: Dict[unicode, Any]
|
||||||
extra_data=None # type: Dict[unicode, Any]
|
extra_data=None # type: Dict[unicode, Any]
|
||||||
):
|
):
|
||||||
|
@ -296,7 +305,24 @@ class MatrixMessage:
|
||||||
"access_token={access_token}").format(
|
"access_token={access_token}").format(
|
||||||
api=MATRIX_API_PATH,
|
api=MATRIX_API_PATH,
|
||||||
room=room_id,
|
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)
|
access_token=server.access_token)
|
||||||
|
|
||||||
self.request = HttpRequest(
|
self.request = HttpRequest(
|
||||||
|
@ -325,7 +351,7 @@ def key_from_value(dictionary, value):
|
||||||
|
|
||||||
@utf8_decode
|
@utf8_decode
|
||||||
def server_config_change_cb(server_name, option):
|
def server_config_change_cb(server_name, option):
|
||||||
# type: (unicode, weechat.config_option) -> bool
|
# type: (unicode, weechat.config_option) -> int
|
||||||
server = SERVERS[server_name]
|
server = SERVERS[server_name]
|
||||||
option_name = None
|
option_name = None
|
||||||
|
|
||||||
|
@ -383,6 +409,7 @@ class MatrixServer:
|
||||||
|
|
||||||
self.access_token = None # type: unicode
|
self.access_token = None # type: unicode
|
||||||
self.next_batch = None # type: unicode
|
self.next_batch = None # type: unicode
|
||||||
|
self.transaction_id = 0 # type: int
|
||||||
|
|
||||||
self.http_parser = HttpParser() # type: HttpParser
|
self.http_parser = HttpParser() # type: HttpParser
|
||||||
self.http_buffer = [] # type: List[bytes]
|
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):
|
def matrix_handle_redacted_message(server, room_id, event):
|
||||||
# type: (MatrixServer, unicode, Dict[Any, Any]) -> None
|
# type: (MatrixServer, unicode, Dict[Any, Any]) -> None
|
||||||
|
reason = ">"
|
||||||
censor = strip_matrix_server(
|
censor = strip_matrix_server(
|
||||||
event['unsigned']['redacted_because']['sender']
|
event['unsigned']['redacted_because']['sender']
|
||||||
)[1:]
|
)[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 = ("<Message redacted by: {censor}{reason}").format(
|
||||||
censor=censor,
|
censor=censor,
|
||||||
reason=")")
|
reason=reason)
|
||||||
|
|
||||||
msg_author = strip_matrix_server(event['sender'])[1:]
|
msg_author = strip_matrix_server(event['sender'])[1:]
|
||||||
|
|
||||||
|
@ -700,6 +733,9 @@ def matrix_handle_room_events(server, room_id, room_events):
|
||||||
|
|
||||||
W.prnt_date_tags(buf, date, tags, message)
|
W.prnt_date_tags(buf, date, tags, message)
|
||||||
|
|
||||||
|
elif event['type'] == "m.room.redaction":
|
||||||
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
message = ("{prefix}Handling of message type "
|
message = ("{prefix}Handling of message type "
|
||||||
"{type} not implemented").format(
|
"{type} not implemented").format(
|
||||||
|
@ -765,8 +801,9 @@ def matrix_handle_message(
|
||||||
buf = server.buffers[room_id]
|
buf = server.buffers[room_id]
|
||||||
W.prnt_date_tags(buf, date, tag, data)
|
W.prnt_date_tags(buf, date, tag, data)
|
||||||
|
|
||||||
# Nothing to do here, we'll handle state changes in the sync
|
# Nothing to do here, we'll handle state changes and redactions in the sync
|
||||||
elif message_type == MessageType.STATE:
|
elif (message_type == MessageType.STATE or
|
||||||
|
message_type == MessageType.REDACT):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -1827,7 +1864,7 @@ def matrix_command_topic_cb(data, buffer, command):
|
||||||
MessageType.STATE,
|
MessageType.STATE,
|
||||||
data=body,
|
data=body,
|
||||||
room_id=room_id,
|
room_id=room_id,
|
||||||
event_type="m.room.topic"
|
extra_id="m.room.topic"
|
||||||
)
|
)
|
||||||
send_or_queue(server, message)
|
send_or_queue(server, message)
|
||||||
|
|
||||||
|
@ -1843,11 +1880,102 @@ def matrix_command_topic_cb(data, buffer, command):
|
||||||
return W.WEECHAT_RC_OK
|
return W.WEECHAT_RC_OK
|
||||||
|
|
||||||
|
|
||||||
|
def event_id_from_line(buf, target_number):
|
||||||
|
# type: (weechat.buffer, int) -> 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):
|
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
|
return W.WEECHAT_RC_OK
|
||||||
|
|
||||||
|
|
||||||
|
@utf8_decode
|
||||||
def matrix_message_completion_cb(data, completion_item, buffer, completion):
|
def matrix_message_completion_cb(data, completion_item, buffer, completion):
|
||||||
own_lines = W.hdata_pointer(W.hdata_get('buffer'), buffer, 'own_lines')
|
own_lines = W.hdata_pointer(W.hdata_get('buffer'), buffer, 'own_lines')
|
||||||
if own_lines:
|
if own_lines:
|
||||||
|
|
Loading…
Reference in a new issue