diff --git a/.travis.yml b/.travis.yml index 7b5a66e..ee468f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,26 @@ -language: python -dist: xenial -sudo: false +--- +## Machine config +os: "linux" +arch: "amd64" +dist: "bionic" +version: "~> 1.0" + +## Language config +language: "python" python: - - "3.6" - - "3.7" - - "3.8" + - "3.6" + - "3.7" + - "3.8" before_install: - - wget https://gitlab.matrix.org/matrix-org/olm/-/archive/master/olm-master.tar.bz2 - - tar -xvf olm-master.tar.bz2 - - pushd olm-master && make && sudo make PREFIX="/usr" install && popd - - rm -r olm-master + - wget https://gitlab.matrix.org/matrix-org/olm/-/archive/master/olm-master.tar.bz2 + - tar -xvf olm-master.tar.bz2 + - pushd olm-master && make && sudo make PREFIX="/usr" install && popd + - rm -r olm-master install: - - pip install -r requirements.txt - - pip install pytest - - pip install hypothesis + - pip install -r requirements.txt + - pip install pytest + - pip install hypothesis -script: - python -m pytest +script: python -m pytest diff --git a/main.py b/main.py index 73d9524..a3993ad 100644 --- a/main.py +++ b/main.py @@ -73,7 +73,8 @@ from matrix.commands import (hook_commands, hook_page_up, matrix_redact_command_cb, matrix_topic_command_cb, matrix_olm_command_cb, matrix_devices_command_cb, matrix_room_command_cb, matrix_uploads_command_cb, - matrix_upload_command_cb, matrix_send_anyways_cb) + matrix_upload_command_cb, matrix_send_anyways_cb, + matrix_reply_command_cb) from matrix.completion import (init_completion, matrix_command_completion_cb, matrix_debug_completion_cb, matrix_message_completion_cb, diff --git a/matrix/commands.py b/matrix/commands.py index 52a0754..a2ec1a8 100644 --- a/matrix/commands.py +++ b/matrix/commands.py @@ -285,6 +285,27 @@ def hook_commands(): "", ) + W.hook_command( + # Command name and short description + "reply-matrix", + "reply to a message", + # Synopsis + ('[:""] []'), + # Description + ( + " event-id: event id of the message that will be replied to\n" + "message-part: an initial part of the message (ignored, only " + "used\n" + " as visual feedback when using completion)\n" + " reply: the reply\n" + ), + # Completions + ("%(matrix_messages)"), + # Function name + "matrix_reply_command_cb", + "", + ) + W.hook_command( # Command name and short description "topic", @@ -1321,6 +1342,64 @@ def matrix_redact_command_cb(data, buffer, args): return W.WEECHAT_RC_OK +@utf8_decode +def matrix_reply_command_cb(data, buffer, args): + def predicate(event_id, line): + event_tag = SCRIPT_NAME + "_id_{}".format(event_id) + tags = line.tags + + if event_tag in tags: + return True + return False + + for server in SERVERS.values(): + if buffer in server.buffers.values(): + room_buffer = server.find_room_from_ptr(buffer) + + # Intentional use of `parse_redact_args` which serves the + # necessary purpose + event_id, reply = parse_redact_args(args) + + if not event_id: + message = ( + "{prefix}matrix: Invalid command " + "arguments (see /help reply)" + ).format(prefix=W.prefix("error")) + W.prnt("", message) + return W.WEECHAT_RC_ERROR + + lines = room_buffer.weechat_buffer.find_lines( + partial(predicate, event_id), max_lines=1 + ) + + if not lines: + room_buffer.error( + "No such message with event id " + "{event_id} found.".format(event_id=event_id)) + return W.WEECHAT_RC_OK + + formatted_data = Formatted.from_input_line(reply) + server.room_send_message( + room_buffer, + formatted_data, + "m.text", + in_reply_to_event_id=event_id, + ) + room_buffer.last_message = None + + return W.WEECHAT_RC_OK + + if buffer == server.server_buffer: + message = ( + '{prefix}matrix: command "reply" must be ' + "executed on a Matrix channel buffer" + ).format(prefix=W.prefix("error")) + W.prnt("", message) + return W.WEECHAT_RC_OK + + return W.WEECHAT_RC_OK + + def matrix_command_help(args): if not args: message = ( diff --git a/matrix/server.py b/matrix/server.py index 1ef69c4..7d9ee0f 100644 --- a/matrix/server.py +++ b/matrix/server.py @@ -1118,6 +1118,7 @@ class MatrixServer(object): formatted, # type: Formatted msgtype="m.text", # type: str ignore_unverified_devices=False, # type: bool + in_reply_to_event_id="", # type: str ): # type: (...) -> bool room = room_buffer.room @@ -1126,9 +1127,13 @@ class MatrixServer(object): content = {"msgtype": msgtype, "body": formatted.to_plain()} - if formatted.is_formatted(): + if formatted.is_formatted() or in_reply_to_event_id: content["format"] = "org.matrix.custom.html" content["formatted_body"] = formatted.to_html() + if in_reply_to_event_id: + content["m.relates_to"] = { + "m.in_reply_to": {"event_id": in_reply_to_event_id} + } try: uuid = self.room_send_event(