From 35f47547d23fc55c80f8347ec60f4ad67d6ba79d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Sun, 14 Oct 2018 11:47:11 +0200 Subject: [PATCH] commands: Add initial device manipulation command. --- main.py | 5 +++-- matrix/commands.py | 51 ++++++++++++++++++++++++++++++++++++++++++++ matrix/completion.py | 30 ++++++++++++++++++++++++++ matrix/server.py | 49 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 9727c9e..b3ad24a 100644 --- a/main.py +++ b/main.py @@ -45,7 +45,7 @@ from matrix.commands import (hook_commands, hook_page_up, matrix_join_command_cb, matrix_kick_command_cb, matrix_me_command_cb, matrix_part_command_cb, matrix_redact_command_cb, matrix_topic_command_cb, - matrix_olm_command_cb) + matrix_olm_command_cb, matrix_devices_command_cb) from matrix.completion import (init_completion, matrix_command_completion_cb, matrix_debug_completion_cb, matrix_message_completion_cb, @@ -53,7 +53,8 @@ from matrix.completion import (init_completion, matrix_command_completion_cb, matrix_olm_user_completion_cb, matrix_server_command_completion_cb, matrix_server_completion_cb, - matrix_user_completion_cb) + matrix_user_completion_cb, + matrix_own_devices_completion_cb) from matrix.config import (MatrixConfig, config_log_category_cb, config_log_level_cb, config_server_buffer_cb, matrix_config_reload_cb, config_pgup_cb) diff --git a/matrix/commands.py b/matrix/commands.py index ca0ac3f..8aefad9 100644 --- a/matrix/commands.py +++ b/matrix/commands.py @@ -90,6 +90,17 @@ class WeechatCommandParser(object): parser.add_argument("room_id", nargs="?") return WeechatCommandParser._run_parser(parser, args) + @staticmethod + def devices(args): + parser = WeechatArgParse(prog="devices") + subparsers = parser.add_subparsers(dest="subcommand") + subparsers.add_parser("list") + + delete_parser = subparsers.add_parser("delete") + delete_parser.add_argument("device_id") + + return WeechatCommandParser._run_parser(parser, args) + @staticmethod def olm(args): parser = WeechatArgParse(prog="olm") @@ -293,6 +304,23 @@ def hook_commands(): "", ) + W.hook_command( + # Command name and short description + "devices", + "list or delete matrix devices", + # Synopsis + ("list ||" + "delete "), + # Description + ("device-id: device id of the device to delete"), + # Completions + ("list ||" + "delete %(matrix_own_devices)"), + # Callback + "matrix_devices_command_cb", + "", + ) + W.hook_command( # Command name and short description "olm", @@ -596,6 +624,29 @@ def matrix_olm_command_cb(data, buffer, args): return W.WEECHAT_RC_OK +@utf8_decode +def matrix_devices_command_cb(data, buffer, args): + for server in SERVERS.values(): + if buffer in server.buffers.values() or buffer == server.server_buffer: + parsed_args = WeechatCommandParser.devices(args) + if not parsed_args: + return W.WEECHAT_RC_OK + + if not parsed_args.subcommand or parsed_args.subcommand == "list": + server.devices() + elif parsed_args.subcommand == "delete": + server.delete_device(parsed_args.delete_device) + + return W.WEECHAT_RC_OK + + W.prnt("", "{prefix}matrix: command \"devices\" must be executed on a " + "matrix buffer (server or channel)".format( + prefix=W.prefix("error") + )) + + return W.WEECHAT_RC_OK + + @utf8_decode def matrix_me_command_cb(data, buffer, args): for server in SERVERS.values(): diff --git a/matrix/completion.py b/matrix/completion.py index fe943dd..0df1362 100644 --- a/matrix/completion.py +++ b/matrix/completion.py @@ -199,6 +199,29 @@ def matrix_olm_device_completion_cb(data, completion_item, buffer, completion): return W.WEECHAT_RC_OK +@utf8_decode +def matrix_own_devices_completion_cb( + data, + completion_item, + buffer, + completion +): + server = server_from_buffer(buffer) + + if not server: + return W.WEECHAT_RC_OK + + olm = server.client.olm + + if not olm: + return W.WEECHAT_RC_OK + + W.hook_completion_list_add( + completion, olm.device_id, 0, W.WEECHAT_LIST_POS_SORT + ) + + user = olm.user_id + if user not in olm.device_store.users: return W.WEECHAT_RC_OK @@ -292,3 +315,10 @@ def init_completion(): "matrix_user_completion_cb", "", ) + + W.hook_completion( + "matrix_own_devices", + "Matrix own devices completion", + "matrix_own_devices_completion_cb", + "", + ) diff --git a/matrix/server.py b/matrix/server.py index a4e4690..f2d75ed 100644 --- a/matrix/server.py +++ b/matrix/server.py @@ -36,6 +36,7 @@ from nio import ( ShareGroupSessionResponse, KeysQueryResponse, KeysClaimResponse, + DevicesResponse, TransportResponse, TransportType, RoomMessagesResponse, @@ -582,6 +583,14 @@ class MatrixServer(object): W.prnt(self.server_buffer, msg) + def devices(self): + _, request = self.client.devices() + self.send_or_queue(request) + + def delete_device(self, device_id): + # TODO implement this + return + def room_send_state(self, room_buffer, body, event_type): if room_buffer.room.encrypted: return @@ -731,6 +740,43 @@ class MatrixServer(object): room_buffer.handle_backlog(response) + def handle_devices_response(self, response): + if not response.devices: + m = "{}{}: No devices found for this account".format( + W.prefix("error"), + SCRIPT_NAME) + W.prnt(self.server_buffer, m) + + header = (W.prefix("network") + SCRIPT_NAME + ": devices for " + "server {}{}{}:\n" + " Device ID Device Name " + "Last Seen").format( + W.color("chat_server"), + self.name, + W.color("reset") + ) + W.prnt(self.server_buffer, header) + + lines = [] + for device in response.devices: + last_seen = "{ip} @ {date}".format( + ip=device.last_seen_ip, + date=device.last_seen_date.strftime("%Y/%m/%d %H:%M") + ) + device_color = ("chat_self" if device.id == self.device_id else + W.info_get("nick_color_name", device.id)) + bold = W.color("bold") if device.id == self.device_id else "" + line = " {}{}{:<18}{}{:<29}{:<}".format( + bold, + W.color(device_color), + device.id, + W.color("resetcolor"), + device.display_name, + last_seen + ) + lines.append(line) + W.prnt(self.server_buffer, "\n".join(lines)) + def _handle_login(self, response): self.access_token = response.access_token self.user_id = response.user_id @@ -899,6 +945,9 @@ class MatrixServer(object): elif isinstance(response, RoomMessagesResponse): self.handle_backlog_response(response) + elif isinstance(response, DevicesResponse): + self.handle_devices_response(response) + elif isinstance(response, KeysQueryResponse): self.keys_queried = False