Move the weechat command setup and some commands.
This commit is contained in:
parent
be48b73395
commit
27c0836eb5
7 changed files with 707 additions and 633 deletions
|
@ -2,6 +2,8 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# pylint: disable=redefined-builtin
|
||||
from builtins import str
|
||||
from collections import namedtuple
|
||||
|
||||
import webcolors
|
||||
|
|
445
matrix/commands.py
Normal file
445
matrix/commands.py
Normal file
|
@ -0,0 +1,445 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
import matrix.globals
|
||||
|
||||
from matrix.utf import utf8_decode
|
||||
from matrix.api import MatrixMessage, MessageType
|
||||
from matrix.utils import key_from_value, tags_from_line_data
|
||||
from matrix.socket import send_or_queue
|
||||
|
||||
|
||||
W = matrix.globals.W
|
||||
GLOBAL_OPTIONS = matrix.globals.OPTIONS
|
||||
SERVERS = matrix.globals.SERVERS
|
||||
|
||||
|
||||
def hook_commands():
|
||||
W.hook_completion(
|
||||
"matrix_server_commands",
|
||||
"Matrix server completion",
|
||||
"server_command_completion_cb",
|
||||
""
|
||||
)
|
||||
|
||||
W.hook_completion(
|
||||
"matrix_servers",
|
||||
"Matrix server completion",
|
||||
"matrix_server_completion_cb",
|
||||
""
|
||||
)
|
||||
|
||||
W.hook_completion(
|
||||
"matrix_commands",
|
||||
"Matrix command completion",
|
||||
"matrix_command_completion_cb",
|
||||
""
|
||||
)
|
||||
|
||||
W.hook_completion(
|
||||
"matrix_messages",
|
||||
"Matrix message completion",
|
||||
"matrix_message_completion_cb",
|
||||
""
|
||||
)
|
||||
|
||||
W.hook_completion(
|
||||
"matrix_debug_types",
|
||||
"Matrix debugging type completion",
|
||||
"matrix_debug_completion_cb",
|
||||
""
|
||||
)
|
||||
|
||||
W.hook_command(
|
||||
# Command name and short description
|
||||
'matrix', 'Matrix chat protocol command',
|
||||
# Synopsis
|
||||
(
|
||||
'server add <server-name> <hostname>[:<port>] ||'
|
||||
'server delete|list|listfull <server-name> ||'
|
||||
'connect <server-name> ||'
|
||||
'disconnect <server-name> ||'
|
||||
'reconnect <server-name> ||'
|
||||
'debug <debug-type> ||'
|
||||
'help <matrix-command>'
|
||||
),
|
||||
# Description
|
||||
(
|
||||
' server: list, add, or remove Matrix servers\n'
|
||||
' connect: connect to Matrix servers\n'
|
||||
'disconnect: disconnect from one or all Matrix servers\n'
|
||||
' reconnect: reconnect to server(s)\n\n'
|
||||
' help: show detailed command help\n\n'
|
||||
' debug: enable or disable debugging\n\n'
|
||||
'Use /matrix help [command] to find out more\n'
|
||||
),
|
||||
# Completions
|
||||
(
|
||||
'server %(matrix_server_commands)|%* ||'
|
||||
'connect %(matrix_servers) ||'
|
||||
'disconnect %(matrix_servers) ||'
|
||||
'reconnect %(matrix_servers) ||'
|
||||
'debug %(matrix_debug_types) ||'
|
||||
'help %(matrix_commands)'
|
||||
),
|
||||
# Function name
|
||||
'matrix_command_cb', '')
|
||||
|
||||
W.hook_command(
|
||||
# Command name and short description
|
||||
'redact', 'redact messages',
|
||||
# Synopsis
|
||||
(
|
||||
'<message-number>[:<"message-part">] [<reason>]'
|
||||
),
|
||||
# Description
|
||||
(
|
||||
"message-number: number of the message to redact (message numbers"
|
||||
"\n start from the last recieved as "
|
||||
"1 and count up)\n"
|
||||
" message-part: a shortened part of the message\n"
|
||||
" reason: the redaction reason\n"
|
||||
),
|
||||
# Completions
|
||||
(
|
||||
'%(matrix_messages)'
|
||||
),
|
||||
# Function name
|
||||
'matrix_redact_command_cb', '')
|
||||
|
||||
W.hook_command_run('/topic', 'matrix_command_topic_cb', '')
|
||||
W.hook_command_run('/buffer clear', 'matrix_command_buf_clear_cb', '')
|
||||
W.hook_command_run('/join', 'matrix_command_join_cb', '')
|
||||
W.hook_command_run('/part', 'matrix_command_part_cb', '')
|
||||
W.hook_command_run('/invite', 'matrix_command_invite_cb', '')
|
||||
|
||||
if GLOBAL_OPTIONS.enable_backlog:
|
||||
hook_page_up()
|
||||
|
||||
|
||||
def matrix_fetch_old_messages(server, room_id):
|
||||
room = server.rooms[room_id]
|
||||
prev_batch = room.prev_batch
|
||||
|
||||
if not prev_batch:
|
||||
return
|
||||
|
||||
message = MatrixMessage(server, GLOBAL_OPTIONS, MessageType.ROOM_MSG,
|
||||
room_id=room_id, extra_id=prev_batch)
|
||||
|
||||
send_or_queue(server, message)
|
||||
|
||||
return
|
||||
|
||||
|
||||
def hook_page_up():
|
||||
GLOBAL_OPTIONS.page_up_hook = W.hook_command_run(
|
||||
'/window page_up',
|
||||
'matrix_command_pgup_cb',
|
||||
''
|
||||
)
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_debug_completion_cb(data, completion_item, buffer, completion):
|
||||
for debug_type in ["messaging", "network", "timing"]:
|
||||
W.hook_completion_list_add(
|
||||
completion,
|
||||
debug_type,
|
||||
0,
|
||||
W.WEECHAT_LIST_POS_SORT)
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_command_buf_clear_cb(data, buffer, command):
|
||||
for server in SERVERS.values():
|
||||
if buffer in server.buffers.values():
|
||||
room_id = key_from_value(server.buffers, buffer)
|
||||
server.rooms[room_id].prev_batch = server.next_batch
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_command_pgup_cb(data, buffer, command):
|
||||
# TODO the highlight status of a line isn't allowed to be updated/changed
|
||||
# via hdata, therefore the highlight status of a messages can't be
|
||||
# reoredered this would need to be fixed in weechat
|
||||
# TODO we shouldn't fetch and print out more messages than
|
||||
# max_buffer_lines_number or older messages than max_buffer_lines_minutes
|
||||
for server in SERVERS.values():
|
||||
if buffer in server.buffers.values():
|
||||
window = W.window_search_with_buffer(buffer)
|
||||
|
||||
first_line_displayed = bool(
|
||||
W.window_get_integer(window, "first_line_displayed")
|
||||
)
|
||||
|
||||
if first_line_displayed:
|
||||
room_id = key_from_value(server.buffers, buffer)
|
||||
matrix_fetch_old_messages(server, room_id)
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_command_join_cb(data, buffer, command):
|
||||
def join(server, args):
|
||||
split_args = args.split(" ", 1)
|
||||
|
||||
# TODO handle join for non public rooms
|
||||
if len(split_args) != 2:
|
||||
message = ("{prefix}Error with command \"/join\" (help on "
|
||||
"command: /help join)").format(
|
||||
prefix=W.prefix("error"))
|
||||
W.prnt("", message)
|
||||
return
|
||||
|
||||
_, room_id = split_args
|
||||
message = MatrixMessage(
|
||||
server,
|
||||
GLOBAL_OPTIONS,
|
||||
MessageType.JOIN,
|
||||
room_id=room_id
|
||||
)
|
||||
send_or_queue(server, message)
|
||||
|
||||
for server in SERVERS.values():
|
||||
if buffer in server.buffers.values():
|
||||
join(server, command)
|
||||
return W.WEECHAT_RC_OK_EAT
|
||||
elif buffer == server.server_buffer:
|
||||
join(server, command)
|
||||
return W.WEECHAT_RC_OK_EAT
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_command_part_cb(data, buffer, command):
|
||||
def part(server, buffer, args):
|
||||
rooms = []
|
||||
|
||||
split_args = args.split(" ", 1)
|
||||
|
||||
if len(split_args) == 1:
|
||||
if buffer == server.server_buffer:
|
||||
message = ("{prefix}Error with command \"/part\" (help on "
|
||||
"command: /help part)").format(
|
||||
prefix=W.prefix("error"))
|
||||
W.prnt("", message)
|
||||
return
|
||||
|
||||
rooms = [key_from_value(server.buffers, buffer)]
|
||||
|
||||
else:
|
||||
_, rooms = split_args
|
||||
rooms = rooms.split(" ")
|
||||
|
||||
for room_id in rooms:
|
||||
message = MatrixMessage(
|
||||
server,
|
||||
GLOBAL_OPTIONS,
|
||||
MessageType.PART,
|
||||
room_id=room_id
|
||||
)
|
||||
send_or_queue(server, message)
|
||||
|
||||
for server in SERVERS.values():
|
||||
if buffer in server.buffers.values():
|
||||
part(server, buffer, command)
|
||||
return W.WEECHAT_RC_OK_EAT
|
||||
elif buffer == server.server_buffer:
|
||||
part(server, buffer, command)
|
||||
return W.WEECHAT_RC_OK_EAT
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_command_invite_cb(data, buffer, command):
|
||||
def invite(server, buf, args):
|
||||
split_args = args.split(" ", 1)
|
||||
|
||||
# TODO handle join for non public rooms
|
||||
if len(split_args) != 2:
|
||||
message = ("{prefix}Error with command \"/invite\" (help on "
|
||||
"command: /help invite)").format(
|
||||
prefix=W.prefix("error"))
|
||||
W.prnt("", message)
|
||||
return
|
||||
|
||||
_, invitee = split_args
|
||||
room_id = key_from_value(server.buffers, buf)
|
||||
|
||||
body = {"user_id": invitee}
|
||||
|
||||
message = MatrixMessage(
|
||||
server,
|
||||
GLOBAL_OPTIONS,
|
||||
MessageType.INVITE,
|
||||
room_id=room_id,
|
||||
data=body
|
||||
)
|
||||
send_or_queue(server, message)
|
||||
|
||||
for server in SERVERS.values():
|
||||
if buffer in server.buffers.values():
|
||||
invite(server, buffer, command)
|
||||
return W.WEECHAT_RC_OK_EAT
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
def event_id_from_line(buf, target_number):
|
||||
# type: (weechat.buffer, int) -> str
|
||||
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 = tags_from_line_data(line_data)
|
||||
|
||||
# Only count non redacted user messages
|
||||
if ("matrix_message" in tags
|
||||
and 'matrix_redacted' not in tags
|
||||
and "matrix_new_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):
|
||||
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:
|
||||
message = ("{prefix}matrix: Invalid command arguments (see "
|
||||
"the help for the command /help redact)").format(
|
||||
prefix=W.prefix("error"))
|
||||
W.prnt("", message)
|
||||
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:
|
||||
message = ("{prefix}matrix: No such message with number "
|
||||
"{number} found").format(
|
||||
prefix=W.prefix("error"),
|
||||
number=line)
|
||||
W.prnt("", message)
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
message = MatrixMessage(
|
||||
server,
|
||||
GLOBAL_OPTIONS,
|
||||
MessageType.REDACT,
|
||||
data=body,
|
||||
room_id=room_id,
|
||||
extra_id=event_id
|
||||
)
|
||||
send_or_queue(server, message)
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
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("", 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:
|
||||
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:
|
||||
message = W.hdata_string(W.hdata_get('line_data'), line_data,
|
||||
'message')
|
||||
|
||||
tags = tags_from_line_data(line_data)
|
||||
|
||||
# Only add non redacted user messages to the completion
|
||||
if (message
|
||||
and 'matrix_message' in tags
|
||||
and 'matrix_redacted' not in tags):
|
||||
|
||||
if len(message) > GLOBAL_OPTIONS.redaction_comp_len + 2:
|
||||
message = (
|
||||
message[:GLOBAL_OPTIONS.redaction_comp_len]
|
||||
+ '..')
|
||||
|
||||
item = ("{number}:\"{message}\"").format(
|
||||
number=line_number,
|
||||
message=message)
|
||||
|
||||
W.hook_completion_list_add(
|
||||
completion,
|
||||
item,
|
||||
0,
|
||||
W.WEECHAT_LIST_POS_END)
|
||||
line_number += 1
|
||||
|
||||
line = W.hdata_move(W.hdata_get('line'), line, -1)
|
||||
|
||||
return W.WEECHAT_RC_OK
|
96
matrix/globals.py
Normal file
96
matrix/globals.py
Normal file
|
@ -0,0 +1,96 @@
|
|||
# pylint: disable=import-error
|
||||
import sys
|
||||
|
||||
from matrix.utf import WeechatWrapper
|
||||
from matrix.config import PluginOptions, Option
|
||||
|
||||
import weechat
|
||||
|
||||
|
||||
def init_matrix_config():
|
||||
config_file = W.config_new("matrix", "matrix_config_reload_cb", "")
|
||||
|
||||
look_options = [
|
||||
Option(
|
||||
"redactions", "integer",
|
||||
"strikethrough|notice|delete", 0, 0,
|
||||
"strikethrough",
|
||||
(
|
||||
"Only notice redactions, strike through or delete "
|
||||
"redacted messages"
|
||||
)
|
||||
),
|
||||
Option(
|
||||
"server_buffer", "integer",
|
||||
"merge_with_core|merge_without_core|independent",
|
||||
0, 0, "merge_with_core", "Merge server buffers"
|
||||
)
|
||||
]
|
||||
|
||||
network_options = [
|
||||
Option(
|
||||
"max_initial_sync_events", "integer",
|
||||
"", 1, 10000,
|
||||
"30",
|
||||
(
|
||||
"How many events to fetch during the initial sync"
|
||||
)
|
||||
),
|
||||
Option(
|
||||
"max_backlog_sync_events", "integer",
|
||||
"", 1, 100,
|
||||
"10",
|
||||
(
|
||||
"How many events to fetch during backlog fetching"
|
||||
)
|
||||
),
|
||||
Option(
|
||||
"fetch_backlog_on_pgup", "boolean",
|
||||
"", 0, 0,
|
||||
"on",
|
||||
(
|
||||
"Fetch messages in the backlog on a window page up event"
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
def add_global_options(section, options):
|
||||
for option in options:
|
||||
OPTIONS.options[option.name] = W.config_new_option(
|
||||
config_file, section, option.name,
|
||||
option.type, option.description, option.string_values,
|
||||
option.min, option.max, option.value, option.value, 0, "",
|
||||
"", "matrix_config_change_cb", "", "", "")
|
||||
|
||||
section = W.config_new_section(config_file, "color", 0, 0, "", "", "", "",
|
||||
"", "", "", "", "", "")
|
||||
|
||||
# TODO color options
|
||||
|
||||
section = W.config_new_section(config_file, "look", 0, 0, "", "", "", "",
|
||||
"", "", "", "", "", "")
|
||||
|
||||
add_global_options(section, look_options)
|
||||
|
||||
section = W.config_new_section(config_file, "network", 0, 0, "", "", "",
|
||||
"", "", "", "", "", "", "")
|
||||
|
||||
add_global_options(section, network_options)
|
||||
|
||||
W.config_new_section(
|
||||
config_file, "server",
|
||||
0, 0,
|
||||
"matrix_config_server_read_cb",
|
||||
"",
|
||||
"matrix_config_server_write_cb",
|
||||
"", "", "", "", "", "", ""
|
||||
)
|
||||
|
||||
return config_file
|
||||
|
||||
|
||||
W = weechat if sys.hexversion >= 0x3000000 else WeechatWrapper(weechat)
|
||||
|
||||
OPTIONS = PluginOptions() # type: PluginOptions
|
||||
SERVERS = dict() # type: Dict[str, MatrixServer]
|
||||
CONFIG = None # type: weechat.config
|
|
@ -5,10 +5,8 @@ from __future__ import unicode_literals
|
|||
import ssl
|
||||
|
||||
from collections import deque
|
||||
|
||||
from http_parser.pyparser import HttpParser
|
||||
|
||||
|
||||
from matrix.config import Option
|
||||
|
||||
|
||||
|
|
72
matrix/socket.py
Normal file
72
matrix/socket.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
|
||||
from builtins import bytes, str
|
||||
|
||||
import matrix.globals
|
||||
from matrix.config import DebugType
|
||||
from matrix.utils import prnt_debug, server_buffer_prnt
|
||||
|
||||
|
||||
W = matrix.globals.W
|
||||
|
||||
|
||||
def disconnect(server):
|
||||
# type: (MatrixServer) -> None
|
||||
if server.fd_hook:
|
||||
W.unhook(server.fd_hook)
|
||||
|
||||
server.fd_hook = None
|
||||
server.socket = None
|
||||
server.connected = False
|
||||
|
||||
server_buffer_prnt(server, "Disconnected")
|
||||
|
||||
|
||||
def send_or_queue(server, message):
|
||||
# type: (MatrixServer, MatrixMessage) -> None
|
||||
if not send(server, message):
|
||||
prnt_debug(DebugType.MESSAGING, server,
|
||||
("{prefix} Failed sending message of type {t}. "
|
||||
"Adding to queue").format(
|
||||
prefix=W.prefix("error"),
|
||||
t=message.type))
|
||||
server.send_queue.append(message)
|
||||
|
||||
|
||||
def send(server, message):
|
||||
# type: (MatrixServer, MatrixMessage) -> bool
|
||||
|
||||
request = message.request.request
|
||||
payload = message.request.payload
|
||||
|
||||
prnt_debug(DebugType.MESSAGING, server,
|
||||
"{prefix} Sending message of type {t}.".format(
|
||||
prefix=W.prefix("error"),
|
||||
t=message.type))
|
||||
|
||||
try:
|
||||
start = time.time()
|
||||
|
||||
# TODO we probably shouldn't use sendall here.
|
||||
server.socket.sendall(bytes(request, 'utf-8'))
|
||||
if payload:
|
||||
server.socket.sendall(bytes(payload, 'utf-8'))
|
||||
|
||||
end = time.time()
|
||||
message.send_time = end
|
||||
send_time = (end - start) * 1000
|
||||
prnt_debug(DebugType.NETWORK, server,
|
||||
("Message done sending ({t}ms), putting message in the "
|
||||
"receive queue.").format(t=send_time))
|
||||
|
||||
server.receive_queue.append(message)
|
||||
return True
|
||||
|
||||
except OSError as error:
|
||||
disconnect(server)
|
||||
server_buffer_prnt(server, str(error))
|
||||
return False
|
46
matrix/utils.py
Normal file
46
matrix/utils.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
|
||||
import matrix.globals
|
||||
|
||||
|
||||
W = matrix.globals.W
|
||||
GLOBAL_OPTIONS = matrix.globals.OPTIONS
|
||||
|
||||
|
||||
def key_from_value(dictionary, value):
|
||||
# type: (Dict[str, Any], Any) -> str
|
||||
return list(dictionary.keys())[list(dictionary.values()).index(value)]
|
||||
|
||||
|
||||
def prnt_debug(debug_type, server, message):
|
||||
if debug_type in GLOBAL_OPTIONS.debug:
|
||||
W.prnt(server.server_buffer, message)
|
||||
|
||||
|
||||
def server_buffer_prnt(server, string):
|
||||
# type: (MatrixServer, str) -> None
|
||||
assert server.server_buffer
|
||||
buffer = server.server_buffer
|
||||
now = int(time.time())
|
||||
W.prnt_date_tags(buffer, now, "", string)
|
||||
|
||||
|
||||
def tags_from_line_data(line_data):
|
||||
# type: (weechat.hdata) -> List[str]
|
||||
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)]
|
||||
|
||||
return tags
|
|
@ -8,11 +8,9 @@ import ssl
|
|||
import time
|
||||
import datetime
|
||||
import pprint
|
||||
import re
|
||||
import sys
|
||||
|
||||
# pylint: disable=redefined-builtin
|
||||
from builtins import bytes, str
|
||||
from builtins import str
|
||||
|
||||
from operator import itemgetter
|
||||
|
||||
|
@ -20,20 +18,48 @@ from operator import itemgetter
|
|||
from typing import (List, Set, Dict, Tuple, Text, Optional, AnyStr, Deque, Any)
|
||||
|
||||
from matrix import colors
|
||||
from matrix.utf import WeechatWrapper, utf8_decode
|
||||
from matrix.utf import utf8_decode
|
||||
from matrix.http import HttpResponse
|
||||
from matrix.api import MatrixMessage, MessageType
|
||||
from matrix.server import MatrixServer
|
||||
from matrix.socket import disconnect, send_or_queue, send
|
||||
|
||||
|
||||
# Weechat searches for the registered callbacks in the global scope, import the
|
||||
# callbacks here so weechat can find them.
|
||||
from matrix.commands import (
|
||||
hook_commands,
|
||||
hook_page_up,
|
||||
matrix_command_join_cb,
|
||||
matrix_command_part_cb,
|
||||
matrix_command_invite_cb,
|
||||
matrix_command_pgup_cb,
|
||||
matrix_redact_command_cb,
|
||||
matrix_command_buf_clear_cb,
|
||||
matrix_debug_completion_cb,
|
||||
matrix_message_completion_cb
|
||||
)
|
||||
|
||||
from matrix.utils import (
|
||||
key_from_value,
|
||||
server_buffer_prnt,
|
||||
prnt_debug,
|
||||
tags_from_line_data
|
||||
)
|
||||
|
||||
from matrix.config import (
|
||||
PluginOptions,
|
||||
Option,
|
||||
DebugType,
|
||||
RedactType,
|
||||
ServerBufferType
|
||||
)
|
||||
|
||||
# pylint: disable=import-error
|
||||
import weechat
|
||||
import matrix.globals
|
||||
|
||||
W = matrix.globals.W
|
||||
GLOBAL_OPTIONS = matrix.globals.OPTIONS
|
||||
CONFIG = matrix.globals.CONFIG
|
||||
SERVERS = matrix.globals.SERVERS
|
||||
|
||||
|
||||
WEECHAT_SCRIPT_NAME = "matrix" # type: str
|
||||
WEECHAT_SCRIPT_DESCRIPTION = "matrix chat plugin" # type: str
|
||||
|
@ -41,15 +67,6 @@ WEECHAT_SCRIPT_AUTHOR = "Damir Jelić <poljar@termina.org.uk>" # type: str
|
|||
WEECHAT_SCRIPT_VERSION = "0.1" # type: str
|
||||
WEECHAT_SCRIPT_LICENSE = "MIT" # type: str
|
||||
|
||||
SERVERS = dict() # type: Dict[str, MatrixServer]
|
||||
CONFIG = None # type: weechat.config
|
||||
GLOBAL_OPTIONS = None # type: PluginOptions
|
||||
|
||||
|
||||
def prnt_debug(debug_type, server, message):
|
||||
if debug_type in GLOBAL_OPTIONS.debug:
|
||||
W.prnt(server.server_buffer, message)
|
||||
|
||||
|
||||
class MatrixUser:
|
||||
def __init__(self, name, display_name):
|
||||
|
@ -73,11 +90,6 @@ class MatrixRoom:
|
|||
self.encrypted = False # type: bool
|
||||
|
||||
|
||||
def key_from_value(dictionary, value):
|
||||
# type: (Dict[str, Any], Any) -> str
|
||||
return list(dictionary.keys())[list(dictionary.values()).index(value)]
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def server_config_change_cb(server_name, option):
|
||||
# type: (str, weechat.config_option) -> int
|
||||
|
@ -363,8 +375,8 @@ def date_from_age(age):
|
|||
|
||||
def color_for_tags(color):
|
||||
if color == "weechat.color.chat_nick_self":
|
||||
option = weechat.config_get(color)
|
||||
return weechat.config_string(option)
|
||||
option = W.config_get(color)
|
||||
return W.config_string(option)
|
||||
return color
|
||||
|
||||
|
||||
|
@ -964,52 +976,6 @@ def matrix_login(server):
|
|||
send_or_queue(server, message)
|
||||
|
||||
|
||||
def send_or_queue(server, message):
|
||||
# type: (MatrixServer, MatrixMessage) -> None
|
||||
if not send(server, message):
|
||||
prnt_debug(DebugType.MESSAGING, server,
|
||||
("{prefix} Failed sending message of type {t}. "
|
||||
"Adding to queue").format(
|
||||
prefix=W.prefix("error"),
|
||||
t=message.type))
|
||||
server.send_queue.append(message)
|
||||
|
||||
|
||||
def send(server, message):
|
||||
# type: (MatrixServer, MatrixMessage) -> bool
|
||||
|
||||
request = message.request.request
|
||||
payload = message.request.payload
|
||||
|
||||
prnt_debug(DebugType.MESSAGING, server,
|
||||
"{prefix} Sending message of type {t}.".format(
|
||||
prefix=W.prefix("error"),
|
||||
t=message.type))
|
||||
|
||||
try:
|
||||
start = time.time()
|
||||
|
||||
# TODO we probably shouldn't use sendall here.
|
||||
server.socket.sendall(bytes(request, 'utf-8'))
|
||||
if payload:
|
||||
server.socket.sendall(bytes(payload, 'utf-8'))
|
||||
|
||||
end = time.time()
|
||||
message.send_time = end
|
||||
send_time = (end - start) * 1000
|
||||
prnt_debug(DebugType.NETWORK, server,
|
||||
("Message done sending ({t}ms), putting message in the "
|
||||
"receive queue.").format(t=send_time))
|
||||
|
||||
server.receive_queue.append(message)
|
||||
return True
|
||||
|
||||
except socket.error as error:
|
||||
disconnect(server)
|
||||
server_buffer_prnt(server, str(error))
|
||||
return False
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def receive_cb(server_name, file_descriptor):
|
||||
server = SERVERS[server_name]
|
||||
|
@ -1081,26 +1047,6 @@ def close_socket(server):
|
|||
server.socket.close()
|
||||
|
||||
|
||||
def disconnect(server):
|
||||
# type: (MatrixServer) -> None
|
||||
if server.fd_hook:
|
||||
W.unhook(server.fd_hook)
|
||||
|
||||
server.fd_hook = None
|
||||
server.socket = None
|
||||
server.connected = False
|
||||
|
||||
server_buffer_prnt(server, "Disconnected")
|
||||
|
||||
|
||||
def server_buffer_prnt(server, string):
|
||||
# type: (MatrixServer, str) -> None
|
||||
assert server.server_buffer
|
||||
buffer = server.server_buffer
|
||||
now = int(time.time())
|
||||
W.prnt_date_tags(buffer, now, "", string)
|
||||
|
||||
|
||||
def server_buffer_set_title(server):
|
||||
# type: (MatrixServer) -> None
|
||||
if server.numeric_address:
|
||||
|
@ -1421,7 +1367,7 @@ def matrix_config_change_cb(data, option):
|
|||
|
||||
if GLOBAL_OPTIONS.enable_backlog:
|
||||
if not GLOBAL_OPTIONS.page_up_hook:
|
||||
hook_page_up()
|
||||
hook_page_up(CONFIG)
|
||||
else:
|
||||
if GLOBAL_OPTIONS.page_up_hook:
|
||||
W.unhook(GLOBAL_OPTIONS.page_up_hook)
|
||||
|
@ -1430,96 +1376,14 @@ def matrix_config_change_cb(data, option):
|
|||
return 1
|
||||
|
||||
|
||||
def init_matrix_config():
|
||||
config_file = W.config_new("matrix", "matrix_config_reload_cb", "")
|
||||
|
||||
look_options = [
|
||||
Option(
|
||||
"redactions", "integer",
|
||||
"strikethrough|notice|delete", 0, 0,
|
||||
"strikethrough",
|
||||
(
|
||||
"Only notice redactions, strike through or delete "
|
||||
"redacted messages"
|
||||
)
|
||||
),
|
||||
Option(
|
||||
"server_buffer", "integer",
|
||||
"merge_with_core|merge_without_core|independent",
|
||||
0, 0, "merge_with_core", "Merge server buffers"
|
||||
)
|
||||
]
|
||||
|
||||
network_options = [
|
||||
Option(
|
||||
"max_initial_sync_events", "integer",
|
||||
"", 1, 10000,
|
||||
"30",
|
||||
(
|
||||
"How many events to fetch during the initial sync"
|
||||
)
|
||||
),
|
||||
Option(
|
||||
"max_backlog_sync_events", "integer",
|
||||
"", 1, 100,
|
||||
"10",
|
||||
(
|
||||
"How many events to fetch during backlog fetching"
|
||||
)
|
||||
),
|
||||
Option(
|
||||
"fetch_backlog_on_pgup", "boolean",
|
||||
"", 0, 0,
|
||||
"on",
|
||||
(
|
||||
"Fetch messages in the backlog on a window page up event"
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
def add_global_options(section, options):
|
||||
for option in options:
|
||||
GLOBAL_OPTIONS.options[option.name] = W.config_new_option(
|
||||
config_file, section, option.name,
|
||||
option.type, option.description, option.string_values,
|
||||
option.min, option.max, option.value, option.value, 0, "",
|
||||
"", "matrix_config_change_cb", "", "", "")
|
||||
|
||||
section = W.config_new_section(config_file, "color", 0, 0, "", "", "", "",
|
||||
"", "", "", "", "", "")
|
||||
|
||||
# TODO color options
|
||||
|
||||
section = W.config_new_section(config_file, "look", 0, 0, "", "", "", "",
|
||||
"", "", "", "", "", "")
|
||||
|
||||
add_global_options(section, look_options)
|
||||
|
||||
section = W.config_new_section(config_file, "network", 0, 0, "", "", "",
|
||||
"", "", "", "", "", "", "")
|
||||
|
||||
add_global_options(section, network_options)
|
||||
|
||||
W.config_new_section(
|
||||
config_file, "server",
|
||||
0, 0,
|
||||
"matrix_config_server_read_cb",
|
||||
"",
|
||||
"matrix_config_server_write_cb",
|
||||
"", "", "", "", "", "", ""
|
||||
)
|
||||
|
||||
return config_file
|
||||
|
||||
|
||||
def read_matrix_config():
|
||||
# type: () -> bool
|
||||
return_code = W.config_read(CONFIG)
|
||||
if return_code == weechat.WEECHAT_CONFIG_READ_OK:
|
||||
if return_code == W.WEECHAT_CONFIG_READ_OK:
|
||||
return True
|
||||
elif return_code == weechat.WEECHAT_CONFIG_READ_MEMORY_ERROR:
|
||||
elif return_code == W.WEECHAT_CONFIG_READ_MEMORY_ERROR:
|
||||
return False
|
||||
elif return_code == weechat.WEECHAT_CONFIG_READ_FILE_NOT_FOUND:
|
||||
elif return_code == W.WEECHAT_CONFIG_READ_FILE_NOT_FOUND:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -2051,13 +1915,13 @@ def add_servers_to_completion(completion):
|
|||
completion,
|
||||
server_name,
|
||||
0,
|
||||
weechat.WEECHAT_LIST_POS_SORT
|
||||
W.WEECHAT_LIST_POS_SORT
|
||||
)
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def server_command_completion_cb(data, completion_item, buffer, completion):
|
||||
buffer_input = weechat.buffer_get_string(buffer, "input").split()
|
||||
buffer_input = W.buffer_get_string(buffer, "input").split()
|
||||
|
||||
args = buffer_input[1:]
|
||||
commands = ['add', 'delete', 'list', 'listfull']
|
||||
|
@ -2068,7 +1932,7 @@ def server_command_completion_cb(data, completion_item, buffer, completion):
|
|||
completion,
|
||||
command,
|
||||
0,
|
||||
weechat.WEECHAT_LIST_POS_SORT
|
||||
W.WEECHAT_LIST_POS_SORT
|
||||
)
|
||||
|
||||
if len(args) == 1:
|
||||
|
@ -2109,7 +1973,7 @@ def matrix_command_completion_cb(data, completion_item, buffer, completion):
|
|||
completion,
|
||||
command,
|
||||
0,
|
||||
weechat.WEECHAT_LIST_POS_SORT)
|
||||
W.WEECHAT_LIST_POS_SORT)
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
|
@ -2190,348 +2054,6 @@ def matrix_command_topic_cb(data, buffer, command):
|
|||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
def matrix_fetch_old_messages(server, room_id):
|
||||
room = server.rooms[room_id]
|
||||
prev_batch = room.prev_batch
|
||||
|
||||
if not prev_batch:
|
||||
return
|
||||
|
||||
message = MatrixMessage(server, GLOBAL_OPTIONS, MessageType.ROOM_MSG,
|
||||
room_id=room_id, extra_id=prev_batch)
|
||||
|
||||
send_or_queue(server, message)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_command_buf_clear_cb(data, buffer, command):
|
||||
for server in SERVERS.values():
|
||||
if buffer in server.buffers.values():
|
||||
room_id = key_from_value(server.buffers, buffer)
|
||||
server.rooms[room_id].prev_batch = server.next_batch
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_command_pgup_cb(data, buffer, command):
|
||||
# TODO the highlight status of a line isn't allowed to be updated/changed
|
||||
# via hdata, therefore the highlight status of a messages can't be
|
||||
# reoredered this would need to be fixed in weechat
|
||||
# TODO we shouldn't fetch and print out more messages than
|
||||
# max_buffer_lines_number or older messages than max_buffer_lines_minutes
|
||||
for server in SERVERS.values():
|
||||
if buffer in server.buffers.values():
|
||||
window = W.window_search_with_buffer(buffer)
|
||||
|
||||
first_line_displayed = bool(
|
||||
W.window_get_integer(window, "first_line_displayed")
|
||||
)
|
||||
|
||||
if first_line_displayed:
|
||||
room_id = key_from_value(server.buffers, buffer)
|
||||
matrix_fetch_old_messages(server, room_id)
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_command_join_cb(data, buffer, command):
|
||||
def join(server, args):
|
||||
split_args = args.split(" ", 1)
|
||||
|
||||
# TODO handle join for non public rooms
|
||||
if len(split_args) != 2:
|
||||
message = ("{prefix}Error with command \"/join\" (help on "
|
||||
"command: /help join)").format(
|
||||
prefix=W.prefix("error"))
|
||||
W.prnt("", message)
|
||||
return
|
||||
|
||||
_, room_id = split_args
|
||||
message = MatrixMessage(
|
||||
server,
|
||||
GLOBAL_OPTIONS,
|
||||
MessageType.JOIN,
|
||||
room_id=room_id
|
||||
)
|
||||
send_or_queue(server, message)
|
||||
|
||||
for server in SERVERS.values():
|
||||
if buffer in server.buffers.values():
|
||||
join(server, command)
|
||||
return W.WEECHAT_RC_OK_EAT
|
||||
elif buffer == server.server_buffer:
|
||||
join(server, command)
|
||||
return W.WEECHAT_RC_OK_EAT
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_command_part_cb(data, buffer, command):
|
||||
def part(server, buffer, args):
|
||||
rooms = []
|
||||
|
||||
split_args = args.split(" ", 1)
|
||||
|
||||
if len(split_args) == 1:
|
||||
if buffer == server.server_buffer:
|
||||
message = ("{prefix}Error with command \"/part\" (help on "
|
||||
"command: /help part)").format(
|
||||
prefix=W.prefix("error"))
|
||||
W.prnt("", message)
|
||||
return
|
||||
|
||||
rooms = [key_from_value(server.buffers, buffer)]
|
||||
|
||||
else:
|
||||
_, rooms = split_args
|
||||
rooms = rooms.split(" ")
|
||||
|
||||
for room_id in rooms:
|
||||
message = MatrixMessage(
|
||||
server,
|
||||
GLOBAL_OPTIONS,
|
||||
MessageType.PART,
|
||||
room_id=room_id
|
||||
)
|
||||
send_or_queue(server, message)
|
||||
|
||||
for server in SERVERS.values():
|
||||
if buffer in server.buffers.values():
|
||||
part(server, buffer, command)
|
||||
return W.WEECHAT_RC_OK_EAT
|
||||
elif buffer == server.server_buffer:
|
||||
part(server, buffer, command)
|
||||
return W.WEECHAT_RC_OK_EAT
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_command_invite_cb(data, buffer, command):
|
||||
def invite(server, buf, args):
|
||||
split_args = args.split(" ", 1)
|
||||
|
||||
# TODO handle join for non public rooms
|
||||
if len(split_args) != 2:
|
||||
message = ("{prefix}Error with command \"/invite\" (help on "
|
||||
"command: /help invite)").format(
|
||||
prefix=W.prefix("error"))
|
||||
W.prnt("", message)
|
||||
return
|
||||
|
||||
_, invitee = split_args
|
||||
room_id = key_from_value(server.buffers, buf)
|
||||
|
||||
body = {"user_id": invitee}
|
||||
|
||||
message = MatrixMessage(
|
||||
server,
|
||||
GLOBAL_OPTIONS,
|
||||
MessageType.INVITE,
|
||||
room_id=room_id,
|
||||
data=body
|
||||
)
|
||||
send_or_queue(server, message)
|
||||
|
||||
for server in SERVERS.values():
|
||||
if buffer in server.buffers.values():
|
||||
invite(server, buffer, command)
|
||||
return W.WEECHAT_RC_OK_EAT
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
def tags_from_line_data(line_data):
|
||||
# type: (weechat.hdata) -> List[str]
|
||||
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)]
|
||||
|
||||
return tags
|
||||
|
||||
|
||||
def event_id_from_line(buf, target_number):
|
||||
# type: (weechat.buffer, int) -> str
|
||||
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 = tags_from_line_data(line_data)
|
||||
|
||||
# Only count non redacted user messages
|
||||
if ("matrix_message" in tags
|
||||
and 'matrix_redacted' not in tags
|
||||
and "matrix_new_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):
|
||||
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:
|
||||
message = ("{prefix}matrix: Invalid command arguments (see "
|
||||
"the help for the command /help redact)").format(
|
||||
prefix=W.prefix("error"))
|
||||
W.prnt("", message)
|
||||
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:
|
||||
message = ("{prefix}matrix: No such message with number "
|
||||
"{number} found").format(
|
||||
prefix=W.prefix("error"),
|
||||
number=line)
|
||||
W.prnt("", message)
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
message = MatrixMessage(
|
||||
server,
|
||||
GLOBAL_OPTIONS,
|
||||
MessageType.REDACT,
|
||||
data=body,
|
||||
room_id=room_id,
|
||||
extra_id=event_id
|
||||
)
|
||||
send_or_queue(server, message)
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
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("", message)
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_debug_completion_cb(data, completion_item, buffer, completion):
|
||||
for debug_type in ["messaging", "network", "timing"]:
|
||||
W.hook_completion_list_add(
|
||||
completion,
|
||||
debug_type,
|
||||
0,
|
||||
weechat.WEECHAT_LIST_POS_SORT)
|
||||
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:
|
||||
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:
|
||||
message = W.hdata_string(W.hdata_get('line_data'), line_data,
|
||||
'message')
|
||||
|
||||
tags = tags_from_line_data(line_data)
|
||||
|
||||
# Only add non redacted user messages to the completion
|
||||
if (message
|
||||
and 'matrix_message' in tags
|
||||
and 'matrix_redacted' not in tags):
|
||||
|
||||
if len(message) > GLOBAL_OPTIONS.redaction_comp_len + 2:
|
||||
message = (
|
||||
message[:GLOBAL_OPTIONS.redaction_comp_len]
|
||||
+ '..')
|
||||
|
||||
item = ("{number}:\"{message}\"").format(
|
||||
number=line_number,
|
||||
message=message)
|
||||
|
||||
W.hook_completion_list_add(
|
||||
completion,
|
||||
item,
|
||||
0,
|
||||
weechat.WEECHAT_LIST_POS_END)
|
||||
line_number += 1
|
||||
|
||||
line = W.hdata_move(W.hdata_get('line'), line, -1)
|
||||
|
||||
return W.WEECHAT_RC_OK
|
||||
|
||||
|
||||
def hook_page_up():
|
||||
GLOBAL_OPTIONS.page_up_hook = W.hook_command_run(
|
||||
'/window page_up',
|
||||
'matrix_command_pgup_cb',
|
||||
''
|
||||
)
|
||||
|
||||
|
||||
@utf8_decode
|
||||
def matrix_bar_item_plugin(data, item, window, buffer, extra_info):
|
||||
# pylint: disable=unused-argument
|
||||
|
@ -2576,109 +2098,6 @@ def matrix_bar_item_name(data, item, window, buffer, extra_info):
|
|||
return ""
|
||||
|
||||
|
||||
def init_hooks():
|
||||
W.hook_completion(
|
||||
"matrix_server_commands",
|
||||
"Matrix server completion",
|
||||
"server_command_completion_cb",
|
||||
""
|
||||
)
|
||||
|
||||
W.hook_completion(
|
||||
"matrix_servers",
|
||||
"Matrix server completion",
|
||||
"matrix_server_completion_cb",
|
||||
""
|
||||
)
|
||||
|
||||
W.hook_completion(
|
||||
"matrix_commands",
|
||||
"Matrix command completion",
|
||||
"matrix_command_completion_cb",
|
||||
""
|
||||
)
|
||||
|
||||
W.hook_completion(
|
||||
"matrix_messages",
|
||||
"Matrix message completion",
|
||||
"matrix_message_completion_cb",
|
||||
""
|
||||
)
|
||||
|
||||
W.hook_completion(
|
||||
"matrix_debug_types",
|
||||
"Matrix debugging type completion",
|
||||
"matrix_debug_completion_cb",
|
||||
""
|
||||
)
|
||||
|
||||
W.hook_command(
|
||||
# Command name and short description
|
||||
'matrix', 'Matrix chat protocol command',
|
||||
# Synopsis
|
||||
(
|
||||
'server add <server-name> <hostname>[:<port>] ||'
|
||||
'server delete|list|listfull <server-name> ||'
|
||||
'connect <server-name> ||'
|
||||
'disconnect <server-name> ||'
|
||||
'reconnect <server-name> ||'
|
||||
'debug <debug-type> ||'
|
||||
'help <matrix-command>'
|
||||
),
|
||||
# Description
|
||||
(
|
||||
' server: list, add, or remove Matrix servers\n'
|
||||
' connect: connect to Matrix servers\n'
|
||||
'disconnect: disconnect from one or all Matrix servers\n'
|
||||
' reconnect: reconnect to server(s)\n\n'
|
||||
' help: show detailed command help\n\n'
|
||||
' debug: enable or disable debugging\n\n'
|
||||
'Use /matrix help [command] to find out more\n'
|
||||
),
|
||||
# Completions
|
||||
(
|
||||
'server %(matrix_server_commands)|%* ||'
|
||||
'connect %(matrix_servers) ||'
|
||||
'disconnect %(matrix_servers) ||'
|
||||
'reconnect %(matrix_servers) ||'
|
||||
'debug %(matrix_debug_types) ||'
|
||||
'help %(matrix_commands)'
|
||||
),
|
||||
# Function name
|
||||
'matrix_command_cb', '')
|
||||
|
||||
W.hook_command(
|
||||
# Command name and short description
|
||||
'redact', 'redact messages',
|
||||
# Synopsis
|
||||
(
|
||||
'<message-number>[:<"message-part">] [<reason>]'
|
||||
),
|
||||
# Description
|
||||
(
|
||||
"message-number: number of the message to redact (message numbers"
|
||||
"\n start from the last recieved as "
|
||||
"1 and count up)\n"
|
||||
" message-part: a shortened part of the message\n"
|
||||
" reason: the redaction reason\n"
|
||||
),
|
||||
# Completions
|
||||
(
|
||||
'%(matrix_messages)'
|
||||
),
|
||||
# Function name
|
||||
'matrix_redact_command_cb', '')
|
||||
|
||||
W.hook_command_run('/topic', 'matrix_command_topic_cb', '')
|
||||
W.hook_command_run('/buffer clear', 'matrix_command_buf_clear_cb', '')
|
||||
W.hook_command_run('/join', 'matrix_command_join_cb', '')
|
||||
W.hook_command_run('/part', 'matrix_command_part_cb', '')
|
||||
W.hook_command_run('/invite', 'matrix_command_invite_cb', '')
|
||||
|
||||
if GLOBAL_OPTIONS.enable_backlog:
|
||||
hook_page_up()
|
||||
|
||||
|
||||
def autoconnect(servers):
|
||||
for server in servers.values():
|
||||
if server.autoconnect:
|
||||
|
@ -2686,8 +2105,6 @@ def autoconnect(servers):
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
W = weechat if sys.hexversion >= 0x3000000 else WeechatWrapper(weechat)
|
||||
|
||||
if W.register(WEECHAT_SCRIPT_NAME,
|
||||
WEECHAT_SCRIPT_AUTHOR,
|
||||
WEECHAT_SCRIPT_VERSION,
|
||||
|
@ -2696,13 +2113,11 @@ if __name__ == "__main__":
|
|||
'matrix_unload_cb',
|
||||
''):
|
||||
|
||||
GLOBAL_OPTIONS = PluginOptions()
|
||||
|
||||
# TODO if this fails we should abort and unload the script.
|
||||
CONFIG = init_matrix_config()
|
||||
CONFIG = matrix.globals.init_matrix_config()
|
||||
read_matrix_config()
|
||||
|
||||
init_hooks()
|
||||
hook_commands()
|
||||
|
||||
W.bar_item_new("(extra)buffer_plugin", "matrix_bar_item_plugin", "")
|
||||
W.bar_item_new("(extra)buffer_name", "matrix_bar_item_name", "")
|
||||
|
|
Loading…
Reference in a new issue