Reformat the source tree using yapf.

This commit is contained in:
poljar (Damir Jelić) 2018-02-21 17:00:11 +01:00
parent 81e078173a
commit 2f4137933f
5 changed files with 219 additions and 404 deletions

158
main.py
View file

@ -31,26 +31,16 @@ from typing import (List, Set, Dict, Tuple, Text, Optional, AnyStr, Deque, Any)
from matrix.colors import Formatted from matrix.colors import Formatted
from matrix.utf import utf8_decode from matrix.utf import utf8_decode
from matrix.http import HttpResponse from matrix.http import HttpResponse
from matrix.api import ( from matrix.api import (MessageType, MatrixSendMessage)
MessageType,
MatrixSendMessage
)
from matrix.messages import handle_http_response from matrix.messages import handle_http_response
# Weechat searches for the registered callbacks in the scope of the main script # Weechat searches for the registered callbacks in the scope of the main script
# file, import the callbacks here so weechat can find them. # file, import the callbacks here so weechat can find them.
from matrix.commands import ( from matrix.commands import (hook_commands, hook_page_up, matrix_command_cb,
hook_commands, matrix_command_join_cb, matrix_command_part_cb,
hook_page_up, matrix_command_invite_cb, matrix_command_topic_cb,
matrix_command_cb, matrix_command_pgup_cb, matrix_redact_command_cb,
matrix_command_join_cb, matrix_command_buf_clear_cb)
matrix_command_part_cb,
matrix_command_invite_cb,
matrix_command_topic_cb,
matrix_command_pgup_cb,
matrix_redact_command_cb,
matrix_command_buf_clear_cb
)
from matrix.server import ( from matrix.server import (
MatrixServer, MatrixServer,
@ -62,29 +52,16 @@ from matrix.server import (
matrix_config_server_change_cb, matrix_config_server_change_cb,
) )
from matrix.bar_items import ( from matrix.bar_items import (init_bar_items, matrix_bar_item_name,
init_bar_items, matrix_bar_item_plugin, matrix_bar_item_lag)
matrix_bar_item_name,
matrix_bar_item_plugin,
matrix_bar_item_lag
)
from matrix.completion import ( from matrix.completion import (
init_completion, init_completion, matrix_command_completion_cb,
matrix_command_completion_cb, matrix_server_command_completion_cb, matrix_debug_completion_cb,
matrix_server_command_completion_cb, matrix_message_completion_cb, matrix_server_completion_cb)
matrix_debug_completion_cb,
matrix_message_completion_cb,
matrix_server_completion_cb
)
from matrix.utils import ( from matrix.utils import (key_from_value, server_buffer_prnt, prnt_debug,
key_from_value, tags_from_line_data, server_buffer_set_title)
server_buffer_prnt,
prnt_debug,
tags_from_line_data,
server_buffer_set_title
)
from matrix.plugin_options import ( from matrix.plugin_options import (
DebugType, DebugType,
@ -92,35 +69,29 @@ from matrix.plugin_options import (
ServerBufferType, ServerBufferType,
) )
from matrix.config import ( from matrix.config import (matrix_config_init, matrix_config_read,
matrix_config_init, matrix_config_free, matrix_config_change_cb,
matrix_config_read, matrix_config_reload_cb)
matrix_config_free,
matrix_config_change_cb,
matrix_config_reload_cb
)
import matrix.globals import matrix.globals
from matrix.globals import W, OPTIONS, SERVERS from matrix.globals import W, OPTIONS, SERVERS
# yapf: disable
WEECHAT_SCRIPT_NAME = "matrix" # type: str WEECHAT_SCRIPT_NAME = "matrix" # type: str
WEECHAT_SCRIPT_DESCRIPTION = "matrix chat plugin" # type: str WEECHAT_SCRIPT_DESCRIPTION = "matrix chat plugin" # type: str
WEECHAT_SCRIPT_AUTHOR = "Damir Jelić <poljar@termina.org.uk>" # type: str WEECHAT_SCRIPT_AUTHOR = "Damir Jelić <poljar@termina.org.uk>" # type: str
WEECHAT_SCRIPT_VERSION = "0.1" # type: str WEECHAT_SCRIPT_VERSION = "0.1" # type: str
WEECHAT_SCRIPT_LICENSE = "ISC" # type: str WEECHAT_SCRIPT_LICENSE = "ISC" # type: str
# yapf: enable
def wrap_socket(server, file_descriptor): def wrap_socket(server, file_descriptor):
# type: (MatrixServer, int) -> None # type: (MatrixServer, int) -> None
sock = None # type: socket.socket sock = None # type: socket.socket
temp_socket = socket.fromfd( temp_socket = socket.fromfd(file_descriptor, socket.AF_INET,
file_descriptor, socket.SOCK_STREAM)
socket.AF_INET,
socket.SOCK_STREAM
)
# For python 2.7 wrap_socket() doesn't work with sockets created from an # For python 2.7 wrap_socket() doesn't work with sockets created from an
# file descriptor because fromfd() doesn't return a wrapped socket, the bug # file descriptor because fromfd() doesn't return a wrapped socket, the bug
@ -142,8 +113,7 @@ def wrap_socket(server, file_descriptor):
W.prnt(server.server_buffer, message) W.prnt(server.server_buffer, message)
ssl_socket = server.ssl_context.wrap_socket( ssl_socket = server.ssl_context.wrap_socket(
sock, sock, do_handshake_on_connect=False,
do_handshake_on_connect=False,
server_hostname=server.address) # type: ssl.SSLSocket server_hostname=server.address) # type: ssl.SSLSocket
server.socket = ssl_socket server.socket = ssl_socket
@ -189,23 +159,15 @@ def try_ssl_handshake(server):
return True return True
except ssl.SSLWantReadError: except ssl.SSLWantReadError:
hook = W.hook_fd( hook = W.hook_fd(server.socket.fileno(), 1, 0, 0, "ssl_fd_cb",
server.socket.fileno(), server.name)
1, 0, 0,
"ssl_fd_cb",
server.name
)
server.ssl_hook = hook server.ssl_hook = hook
return False return False
except ssl.SSLWantWriteError: except ssl.SSLWantWriteError:
hook = W.hook_fd( hook = W.hook_fd(server.socket.fileno(), 0, 1, 0, "ssl_fd_cb",
server.socket.fileno(), server.name)
0, 1, 0,
"ssl_fd_cb",
server.name
)
server.ssl_hook = hook server.ssl_hook = hook
return False return False
@ -215,15 +177,13 @@ def try_ssl_handshake(server):
message = ("{prefix}Error while doing SSL handshake" message = ("{prefix}Error while doing SSL handshake"
": {error}").format( ": {error}").format(
prefix=W.prefix("network"), prefix=W.prefix("network"), error=str_error)
error=str_error)
server_buffer_prnt(server, message) server_buffer_prnt(server, message)
server_buffer_prnt( server_buffer_prnt(
server, server, ("{prefix}matrix: disconnecting from server..."
("{prefix}matrix: disconnecting from server...").format( ).format(prefix=W.prefix("network")))
prefix=W.prefix("network")))
server.disconnect() server.disconnect()
return False return False
@ -245,15 +205,13 @@ def receive_cb(server_name, file_descriptor):
message = ("{prefix}Error while reading from " message = ("{prefix}Error while reading from "
"socket: {error}").format( "socket: {error}").format(
prefix=W.prefix("network"), prefix=W.prefix("network"), error=str_error)
error=str_error)
server_buffer_prnt(server, message) server_buffer_prnt(server, message)
server_buffer_prnt( server_buffer_prnt(
server, server, ("{prefix}matrix: disconnecting from server..."
("{prefix}matrix: disconnecting from server...").format( ).format(prefix=W.prefix("network")))
prefix=W.prefix("network")))
server.disconnect() server.disconnect()
@ -265,9 +223,8 @@ def receive_cb(server_name, file_descriptor):
"{prefix}matrix: Error while reading from socket".format( "{prefix}matrix: Error while reading from socket".format(
prefix=W.prefix("network"))) prefix=W.prefix("network")))
server_buffer_prnt( server_buffer_prnt(
server, server, ("{prefix}matrix: disconnecting from server..."
("{prefix}matrix: disconnecting from server...").format( ).format(prefix=W.prefix("network")))
prefix=W.prefix("network")))
server.disconnect() server.disconnect()
break break
@ -296,9 +253,7 @@ def receive_cb(server_name, file_descriptor):
prnt_debug(DebugType.MESSAGING, server, prnt_debug(DebugType.MESSAGING, server,
("{prefix}Received message of type {t} and " ("{prefix}Received message of type {t} and "
"status {s}").format( "status {s}").format(
prefix=W.prefix("error"), prefix=W.prefix("error"), t=message.type, s=status))
t=message.type,
s=status))
# Message done, reset the parser state. # Message done, reset the parser state.
server.reset_parser() server.reset_parser()
@ -310,12 +265,7 @@ def receive_cb(server_name, file_descriptor):
def finalize_connection(server): def finalize_connection(server):
hook = W.hook_fd( hook = W.hook_fd(server.socket.fileno(), 1, 0, 0, "receive_cb", server.name)
server.socket.fileno(),
1, 0, 0,
"receive_cb",
server.name
)
server.fd_hook = hook server.fd_hook = hook
server.connected = True server.connected = True
@ -342,8 +292,7 @@ def connect_cb(data, status, gnutls_rc, sock, error, ip_address):
elif status_value == W.WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND: elif status_value == W.WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND:
W.prnt( W.prnt(
server.server_buffer, server.server_buffer,
'{address} not found'.format(address=ip_address) '{address} not found'.format(address=ip_address))
)
elif status_value == W.WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND: elif status_value == W.WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND:
W.prnt(server.server_buffer, 'IP address not found') W.prnt(server.server_buffer, 'IP address not found')
@ -352,10 +301,8 @@ def connect_cb(data, status, gnutls_rc, sock, error, ip_address):
W.prnt(server.server_buffer, 'Connection refused') W.prnt(server.server_buffer, 'Connection refused')
elif status_value == W.WEECHAT_HOOK_CONNECT_PROXY_ERROR: elif status_value == W.WEECHAT_HOOK_CONNECT_PROXY_ERROR:
W.prnt( W.prnt(server.server_buffer,
server.server_buffer, 'Proxy fails to establish connection to server')
'Proxy fails to establish connection to server'
)
elif status_value == W.WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR: elif status_value == W.WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR:
W.prnt(server.server_buffer, 'Unable to set local hostname') W.prnt(server.server_buffer, 'Unable to set local hostname')
@ -377,8 +324,7 @@ def connect_cb(data, status, gnutls_rc, sock, error, ip_address):
else: else:
W.prnt( W.prnt(
server.server_buffer, server.server_buffer,
'Unexpected error: {status}'.format(status=status_value) 'Unexpected error: {status}'.format(status=status_value))
)
server.disconnect(reconnect=True) server.disconnect(reconnect=True)
return W.WEECHAT_RC_OK return W.WEECHAT_RC_OK
@ -403,10 +349,7 @@ def room_input_cb(server_name, buffer, input_data):
formatted_data = Formatted.from_input_line(input_data) formatted_data = Formatted.from_input_line(input_data)
message = MatrixSendMessage( message = MatrixSendMessage(
server.client, server.client, room_id=room_id, formatted_message=formatted_data)
room_id=room_id,
formatted_message=formatted_data
)
server.send_or_queue(message) server.send_or_queue(message)
return W.WEECHAT_RC_OK return W.WEECHAT_RC_OK
@ -414,8 +357,8 @@ def room_input_cb(server_name, buffer, input_data):
@utf8_decode @utf8_decode
def room_close_cb(data, buffer): def room_close_cb(data, buffer):
W.prnt("", "Buffer '%s' will be closed!" % W.prnt("",
W.buffer_get_string(buffer, "name")) "Buffer '%s' will be closed!" % W.buffer_get_string(buffer, "name"))
return W.WEECHAT_RC_OK return W.WEECHAT_RC_OK
@ -432,21 +375,14 @@ def autoconnect(servers):
if __name__ == "__main__": if __name__ == "__main__":
if W.register(WEECHAT_SCRIPT_NAME, if W.register(WEECHAT_SCRIPT_NAME, WEECHAT_SCRIPT_AUTHOR,
WEECHAT_SCRIPT_AUTHOR, WEECHAT_SCRIPT_VERSION, WEECHAT_SCRIPT_LICENSE,
WEECHAT_SCRIPT_VERSION, WEECHAT_SCRIPT_DESCRIPTION, 'matrix_unload_cb', ''):
WEECHAT_SCRIPT_LICENSE,
WEECHAT_SCRIPT_DESCRIPTION,
'matrix_unload_cb',
''):
# TODO if this fails we should abort and unload the script. # TODO if this fails we should abort and unload the script.
matrix.globals.CONFIG = W.config_new( matrix.globals.CONFIG = W.config_new("matrix",
"matrix", "matrix_config_reload_cb", "")
"matrix_config_reload_cb",
""
)
matrix_config_init(matrix.globals.CONFIG) matrix_config_init(matrix.globals.CONFIG)
matrix_config_read(matrix.globals.CONFIG) matrix_config_read(matrix.globals.CONFIG)

View file

@ -52,6 +52,7 @@ class MessageType(Enum):
class MatrixClient: class MatrixClient:
def __init__( def __init__(
self, self,
host, # type: str host, # type: str
@ -92,17 +93,13 @@ class MatrixClient:
if sync_filter: if sync_filter:
query_parameters["filter"] = json.dumps( query_parameters["filter"] = json.dumps(
sync_filter, sync_filter, separators=(",", ":"))
separators=(",", ":")
)
if next_batch: if next_batch:
query_parameters["since"] = next_batch query_parameters["since"] = next_batch
path = ("{api}/sync?{query_params}").format( path = ("{api}/sync?{query_params}").format(
api=MATRIX_API_PATH, api=MATRIX_API_PATH, query_params=urlencode(query_parameters))
query_params=urlencode(query_parameters)
)
return HttpRequest(RequestType.GET, self.host, path) return HttpRequest(RequestType.GET, self.host, path)
@ -110,10 +107,7 @@ class MatrixClient:
# type: (str, str, str) -> HttpRequest # type: (str, str, str) -> HttpRequest
query_parameters = {"access_token": self.access_token} query_parameters = {"access_token": self.access_token}
body = { body = {"msgtype": "m.text", "body": content}
"msgtype": "m.text",
"body": content
}
if formatted_content: if formatted_content:
body["format"] = "org.matrix.custom.html" body["format"] = "org.matrix.custom.html"
@ -160,14 +154,12 @@ class MatrixClient:
return HttpRequest(RequestType.PUT, self.host, path, content) return HttpRequest(RequestType.PUT, self.host, path, content)
def room_get_messages( def room_get_messages(self,
self,
room_id, room_id,
start_token, start_token,
end_token="", end_token="",
limit=10, limit=10,
direction='b' direction='b'):
):
query_parameters = { query_parameters = {
"access_token": self.access_token, "access_token": self.access_token,
"from": start_token, "from": start_token,
@ -222,6 +214,7 @@ class MatrixClient:
class MatrixMessage(): class MatrixMessage():
def __init__( def __init__(
self, self,
message_type, # type: MessageType message_type, # type: MessageType
@ -229,6 +222,7 @@ class MatrixMessage():
func_args, func_args,
): ):
# type: (...) -> None # type: (...) -> None
# yapf: disable
self.type = message_type # type: MessageType self.type = message_type # type: MessageType
self.request = None # type: HttpRequest self.request = None # type: HttpRequest
@ -241,13 +235,12 @@ class MatrixMessage():
self.event = None self.event = None
self.request = request_func(**func_args) self.request = request_func(**func_args)
# yapf: enable
def decode_body(self, server): def decode_body(self, server):
try: try:
self.decoded_response = json.loads( self.decoded_response = json.loads(
self.response.body, self.response.body, encoding='utf-8')
encoding='utf-8'
)
return (True, None) return (True, None)
except Exception as error: except Exception as error:
return (False, error) return (False, error)
@ -268,33 +261,23 @@ class MatrixMessage():
class MatrixLoginMessage(MatrixMessage): class MatrixLoginMessage(MatrixMessage):
def __init__(self, client, user, password, device_name, device_id=None): def __init__(self, client, user, password, device_name, device_id=None):
data = { data = {"user": user, "password": password, "device_name": device_name}
"user": user,
"password": password,
"device_name": device_name
}
if device_id: if device_id:
data["device_id"] = device_id data["device_id"] = device_id
MatrixMessage.__init__( MatrixMessage.__init__(self, MessageType.LOGIN, client.login, data)
self,
MessageType.LOGIN,
client.login,
data
)
def decode_body(self, server): def decode_body(self, server):
object_hook = partial( object_hook = partial(MatrixEvents.MatrixLoginEvent.from_dict, server)
MatrixEvents.MatrixLoginEvent.from_dict,
server
)
return self._decode(server, object_hook) return self._decode(server, object_hook)
class MatrixSyncMessage(MatrixMessage): class MatrixSyncMessage(MatrixMessage):
def __init__(self, client, next_batch=None, limit=None): def __init__(self, client, next_batch=None, limit=None):
data = {} data = {}
@ -302,19 +285,13 @@ class MatrixSyncMessage(MatrixMessage):
data["next_batch"] = next_batch data["next_batch"] = next_batch
if limit: if limit:
data["sync_filter"] = { data["sync_filter"] = {"room": {"timeline": {"limit": limit}}}
"room": {"timeline": {"limit": limit}}
}
MatrixMessage.__init__( MatrixMessage.__init__(self, MessageType.SYNC, client.sync, data)
self,
MessageType.SYNC,
client.sync,
data
)
class MatrixSendMessage(MatrixMessage): class MatrixSendMessage(MatrixMessage):
def __init__(self, client, room_id, formatted_message): def __init__(self, client, room_id, formatted_message):
self.room_id = room_id self.room_id = room_id
self.formatted_message = formatted_message self.formatted_message = formatted_message
@ -330,12 +307,8 @@ class MatrixSendMessage(MatrixMessage):
if self.formatted_message.is_formatted: if self.formatted_message.is_formatted:
data["formatted_content"] = self.formatted_message.to_html() data["formatted_content"] = self.formatted_message.to_html()
MatrixMessage.__init__( MatrixMessage.__init__(self, MessageType.SEND, client.room_send_message,
self, data)
MessageType.SEND,
client.room_send_message,
data
)
def decode_body(self, server): def decode_body(self, server):
object_hook = partial( object_hook = partial(
@ -349,21 +322,14 @@ class MatrixSendMessage(MatrixMessage):
class MatrixTopicMessage(MatrixMessage): class MatrixTopicMessage(MatrixMessage):
def __init__(self, client, room_id, topic): def __init__(self, client, room_id, topic):
self.room_id = room_id self.room_id = room_id
self.topic = topic self.topic = topic
data = { data = {"room_id": self.room_id, "topic": self.topic}
"room_id": self.room_id,
"topic": self.topic
}
MatrixMessage.__init__( MatrixMessage.__init__(self, MessageType.TOPIC, client.room_topic, data)
self,
MessageType.TOPIC,
client.room_topic,
data
)
def decode_body(self, server): def decode_body(self, server):
object_hook = partial( object_hook = partial(
@ -377,25 +343,19 @@ class MatrixTopicMessage(MatrixMessage):
class MatrixRedactMessage(MatrixMessage): class MatrixRedactMessage(MatrixMessage):
def __init__(self, client, room_id, event_id, reason=None): def __init__(self, client, room_id, event_id, reason=None):
self.room_id = room_id self.room_id = room_id
self.event_id = event_id self.event_id = event_id
self.reason = reason self.reason = reason
data = { data = {"room_id": self.room_id, "event_id": self.event_id}
"room_id": self.room_id,
"event_id": self.event_id
}
if reason: if reason:
data["reason"] = reason data["reason"] = reason
MatrixMessage.__init__( MatrixMessage.__init__(self, MessageType.REDACT, client.room_redact,
self, data)
MessageType.REDACT,
client.room_redact,
data
)
def decode_body(self, server): def decode_body(self, server):
object_hook = partial( object_hook = partial(
@ -409,6 +369,7 @@ class MatrixRedactMessage(MatrixMessage):
class MatrixBacklogMessage(MatrixMessage): class MatrixBacklogMessage(MatrixMessage):
def __init__(self, client, room_id, token, limit): def __init__(self, client, room_id, token, limit):
self.room_id = room_id self.room_id = room_id
@ -419,95 +380,68 @@ class MatrixBacklogMessage(MatrixMessage):
"limit": limit "limit": limit
} }
MatrixMessage.__init__( MatrixMessage.__init__(self, MessageType.ROOM_MSG,
self, client.room_get_messages, data)
MessageType.ROOM_MSG,
client.room_get_messages,
data
)
def decode_body(self, server): def decode_body(self, server):
object_hook = partial( object_hook = partial(MatrixEvents.MatrixBacklogEvent.from_dict, server,
MatrixEvents.MatrixBacklogEvent.from_dict,
server,
self.room_id) self.room_id)
return self._decode(server, object_hook) return self._decode(server, object_hook)
class MatrixJoinMessage(MatrixMessage): class MatrixJoinMessage(MatrixMessage):
def __init__(self, client, room_id): def __init__(self, client, room_id):
self.room_id = room_id self.room_id = room_id
data = {"room_id": self.room_id} data = {"room_id": self.room_id}
MatrixMessage.__init__( MatrixMessage.__init__(self, MessageType.JOIN, client.room_join, data)
self,
MessageType.JOIN,
client.room_join,
data
)
def decode_body(self, server): def decode_body(self, server):
object_hook = partial( object_hook = partial(MatrixEvents.MatrixJoinEvent.from_dict, server,
MatrixEvents.MatrixJoinEvent.from_dict, self.room_id)
server,
self.room_id
)
return self._decode(server, object_hook) return self._decode(server, object_hook)
class MatrixPartMessage(MatrixMessage): class MatrixPartMessage(MatrixMessage):
def __init__(self, client, room_id): def __init__(self, client, room_id):
self.room_id = room_id self.room_id = room_id
data = {"room_id": self.room_id} data = {"room_id": self.room_id}
MatrixMessage.__init__( MatrixMessage.__init__(self, MessageType.PART, client.room_leave, data)
self,
MessageType.PART,
client.room_leave,
data
)
def decode_body(self, server): def decode_body(self, server):
object_hook = partial( object_hook = partial(MatrixEvents.MatrixPartEvent.from_dict, server,
MatrixEvents.MatrixPartEvent.from_dict, self.room_id)
server,
self.room_id
)
return self._decode(server, object_hook) return self._decode(server, object_hook)
class MatrixInviteMessage(MatrixMessage): class MatrixInviteMessage(MatrixMessage):
def __init__(self, client, room_id, user_id): def __init__(self, client, room_id, user_id):
self.room_id = room_id self.room_id = room_id
self.user_id = user_id self.user_id = user_id
data = {"room_id": self.room_id, data = {"room_id": self.room_id, "user_id": self.user_id}
"user_id": self.user_id}
MatrixMessage.__init__( MatrixMessage.__init__(self, MessageType.INVITE, client.room_invite,
self, data)
MessageType.INVITE,
client.room_invite,
data
)
def decode_body(self, server): def decode_body(self, server):
object_hook = partial( object_hook = partial(MatrixEvents.MatrixInviteEvent.from_dict, server,
MatrixEvents.MatrixInviteEvent.from_dict, self.room_id, self.user_id)
server,
self.room_id,
self.user_id
)
return self._decode(server, object_hook) return self._decode(server, object_hook)
class MatrixUser: class MatrixUser:
def __init__(self, name, display_name): def __init__(self, name, display_name):
self.name = name # type: str self.name = name # type: str
self.display_name = display_name # type: str self.display_name = display_name # type: str
@ -517,8 +451,10 @@ class MatrixUser:
class MatrixRoom: class MatrixRoom:
def __init__(self, room_id): def __init__(self, room_id):
# type: (str) -> None # type: (str) -> None
# yapf: disable
self.room_id = room_id # type: str self.room_id = room_id # type: str
self.alias = room_id # type: str self.alias = room_id # type: str
self.topic = "" # type: str self.topic = "" # type: str
@ -527,3 +463,4 @@ class MatrixRoom:
self.prev_batch = "" # type: str self.prev_batch = "" # type: str
self.users = dict() # type: Dict[str, MatrixUser] self.users = dict() # type: Dict[str, MatrixUser]
self.encrypted = False # type: bool self.encrypted = False # type: bool
# yapf: enable

View file

@ -30,19 +30,15 @@ try:
except ImportError: except ImportError:
from html.parser import HTMLParser from html.parser import HTMLParser
FormattedString = namedtuple('FormattedString', ['text', 'attributes'])
FormattedString = namedtuple(
'FormattedString',
['text', 'attributes']
)
class Formatted(): class Formatted():
def __init__(self, substrings): def __init__(self, substrings):
# type: (List[FormattedString]) -> None # type: (List[FormattedString]) -> None
self.substrings = substrings self.substrings = substrings
def is_formatted(self): def is_formatted(self):
# type: (Formatted) -> bool # type: (Formatted) -> bool
for string in self.substrings: for string in self.substrings:
@ -154,24 +150,16 @@ class Formatted():
def add_attribute(string, name, value): def add_attribute(string, name, value):
if name == "bold" and value: if name == "bold" and value:
return "{bold_on}{text}{bold_off}".format( return "{bold_on}{text}{bold_off}".format(
bold_on="<strong>", bold_on="<strong>", text=string, bold_off="</strong>")
text=string,
bold_off="</strong>")
elif name == "italic" and value: elif name == "italic" and value:
return "{italic_on}{text}{italic_off}".format( return "{italic_on}{text}{italic_off}".format(
italic_on="<em>", italic_on="<em>", text=string, italic_off="</em>")
text=string,
italic_off="</em>")
elif name == "underline" and value: elif name == "underline" and value:
return "{underline_on}{text}{underline_off}".format( return "{underline_on}{text}{underline_off}".format(
underline_on="<u>", underline_on="<u>", text=string, underline_off="</u>")
text=string,
underline_off="</u>")
elif name == "strikethrough" and value: elif name == "strikethrough" and value:
return "{strike_on}{text}{strike_off}".format( return "{strike_on}{text}{strike_off}".format(
strike_on="<del>", strike_on="<del>", text=string, strike_off="</del>")
text=string,
strike_off="</del>")
elif name == "quote" and value: elif name == "quote" and value:
return "{quote_on}{text}{quote_off}".format( return "{quote_on}{text}{quote_off}".format(
quote_on="<blockquote>", quote_on="<blockquote>",
@ -180,8 +168,7 @@ class Formatted():
elif name == "fgcolor" and value: elif name == "fgcolor" and value:
return "{color_on}{text}{color_off}".format( return "{color_on}{text}{color_off}".format(
color_on="<font color={color}>".format( color_on="<font color={color}>".format(
color=color_weechat_to_html(value) color=color_weechat_to_html(value)),
),
text=string, text=string,
color_off="</font>") color_off="</font>")
@ -293,8 +280,7 @@ class MatrixHtmlParser(HTMLParser):
def _toggle_attribute(self, attribute): def _toggle_attribute(self, attribute):
if self.text: if self.text:
self.substrings.append( self.substrings.append(
FormattedString(self.text, self.attributes.copy()) FormattedString(self.text, self.attributes.copy()))
)
self.text = "" self.text = ""
self.attributes[attribute] = not self.attributes[attribute] self.attributes[attribute] = not self.attributes[attribute]
@ -321,8 +307,7 @@ class MatrixHtmlParser(HTMLParser):
if self.text: if self.text:
self.substrings.append( self.substrings.append(
FormattedString(self.text, self.attributes.copy()) FormattedString(self.text, self.attributes.copy()))
)
self.text = "" self.text = ""
self.attributes["fgcolor"] = color self.attributes["fgcolor"] = color
else: else:
@ -342,8 +327,7 @@ class MatrixHtmlParser(HTMLParser):
elif tag == "font": elif tag == "font":
if self.text: if self.text:
self.substrings.append( self.substrings.append(
FormattedString(self.text, self.attributes.copy()) FormattedString(self.text, self.attributes.copy()))
)
self.text = "" self.text = ""
self.attributes["fgcolor"] = None self.attributes["fgcolor"] = None
else: else:
@ -355,8 +339,7 @@ class MatrixHtmlParser(HTMLParser):
def get_substrings(self): def get_substrings(self):
if self.text: if self.text:
self.substrings.append( self.substrings.append(
FormattedString(self.text, self.attributes.copy()) FormattedString(self.text, self.attributes.copy()))
)
return self.substrings return self.substrings
@ -477,6 +460,7 @@ def color_line_to_weechat(color_string):
# under the ISC license. # under the ISC license.
# More info: https://github.com/tmux/tmux/blob/master/colour.c # More info: https://github.com/tmux/tmux/blob/master/colour.c
def colour_dist_sq(R, G, B, r, g, b): def colour_dist_sq(R, G, B, r, g, b):
# pylint: disable=invalid-name,too-many-arguments # pylint: disable=invalid-name,too-many-arguments
# type: (int, int, int, int, int, int) -> int # type: (int, int, int, int, int, int) -> int
@ -593,7 +577,7 @@ def color_weechat_to_html(color):
"lightmagenta": "aqua", # 14 "lightmagenta": "aqua", # 14
"lightcyan": "white", # 15 "lightcyan": "white", # 15
} }
#yapf: disable
hex_colors = { hex_colors = {
"0": "#000000", "0": "#000000",
"1": "#800000", "1": "#800000",
@ -852,6 +836,7 @@ def color_weechat_to_html(color):
"254": "#e4e4e4", "254": "#e4e4e4",
"255": "#eeeeee" "255": "#eeeeee"
} }
# yapf: enable
if color in first_16: if color in first_16:
return first_16[color] return first_16[color]

View file

@ -29,12 +29,14 @@ class RequestType(Enum):
class HttpResponse: class HttpResponse:
def __init__(self, status, headers, body): def __init__(self, status, headers, body):
self.status = status # type: int self.status = status # type: int
self.headers = headers # type: Dict[str, str] self.headers = headers # type: Dict[str, str]
self.body = body # type: bytes self.body = body # type: bytes
# yapf: disable
class HttpRequest: class HttpRequest:
def __init__( def __init__(
self, self,
@ -52,11 +54,13 @@ class HttpRequest:
accept_header = 'Accept: */*' # type: str accept_header = 'Accept: */*' # type: str
end_separator = '\r\n' # type: str end_separator = '\r\n' # type: str
payload = "" # type: str payload = "" # type: str
# yapf: enable
if request_type == RequestType.GET: if request_type == RequestType.GET:
get = 'GET {location} HTTP/1.1'.format(location=location) get = 'GET {location} HTTP/1.1'.format(location=location)
request_list = [get, host_header, request_list = [
user_agent, accept_header, end_separator] get, host_header, user_agent, accept_header, end_separator
]
elif (request_type == RequestType.POST or elif (request_type == RequestType.POST or
request_type == RequestType.PUT): request_type == RequestType.PUT):
@ -69,18 +73,16 @@ class HttpRequest:
method = "PUT" method = "PUT"
request_line = '{method} {location} HTTP/1.1'.format( request_line = '{method} {location} HTTP/1.1'.format(
method=method, method=method, location=location)
location=location
)
type_header = 'Content-Type: application/x-www-form-urlencoded' type_header = 'Content-Type: application/x-www-form-urlencoded'
length_header = 'Content-Length: {length}'.format( length_header = 'Content-Length: {length}'.format(
length=len(json_data) length=len(json_data))
)
request_list = [request_line, host_header, request_list = [
user_agent, accept_header, request_line, host_header, user_agent, accept_header,
length_header, type_header, end_separator] length_header, type_header, end_separator
]
payload = json_data payload = json_data
request = '\r\n'.join(request_list) request = '\r\n'.join(request_list)

View file

@ -14,7 +14,6 @@
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import unicode_literals from __future__ import unicode_literals
from builtins import str, bytes from builtins import str, bytes
@ -26,12 +25,8 @@ from collections import deque
from http_parser.pyparser import HttpParser from http_parser.pyparser import HttpParser
from matrix.plugin_options import Option, DebugType from matrix.plugin_options import Option, DebugType
from matrix.utils import ( from matrix.utils import (key_from_value, prnt_debug, server_buffer_prnt,
key_from_value, create_server_buffer)
prnt_debug,
server_buffer_prnt,
create_server_buffer
)
from matrix.utf import utf8_decode from matrix.utf import utf8_decode
from matrix.globals import W, SERVERS, OPTIONS from matrix.globals import W, SERVERS, OPTIONS
from matrix.api import MatrixClient, MatrixSyncMessage, MatrixLoginMessage from matrix.api import MatrixClient, MatrixSyncMessage, MatrixLoginMessage
@ -41,6 +36,7 @@ class MatrixServer:
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
def __init__(self, name, config_file): def __init__(self, name, config_file):
# type: (str, weechat.config) -> None # type: (str, weechat.config) -> None
# yapf: disable
self.name = name # type: str self.name = name # type: str
self.user_id = "" self.user_id = ""
self.address = "" # type: str self.address = "" # type: str
@ -91,43 +87,27 @@ class MatrixServer:
self.ignore_event_list = [] # type: List[str] self.ignore_event_list = [] # type: List[str]
self._create_options(config_file) self._create_options(config_file)
# yapf: enable
def _create_options(self, config_file): def _create_options(self, config_file):
options = [ options = [
Option( Option('autoconnect', 'boolean', '', 0, 0, 'off',
'autoconnect', 'boolean', '', 0, 0, 'off', ("automatically connect to the matrix server when weechat "
( "is starting")),
"automatically connect to the matrix server when weechat " Option('address', 'string', '', 0, 0, '',
"is starting" "Hostname or IP address for the server"),
) Option('port', 'integer', '', 0, 65535, '8448',
), "Port for the server"),
Option( Option('ssl_verify', 'boolean', '', 0, 0, 'on',
'address', 'string', '', 0, 0, '', ("Check that the SSL connection is fully trusted")),
"Hostname or IP address for the server" Option('username', 'string', '', 0, 0, '',
), "Username to use on server"),
Option(
'port', 'integer', '', 0, 65535, '8448',
"Port for the server"
),
Option(
'ssl_verify', 'boolean', '', 0, 0, 'on',
(
"Check that the SSL connection is fully trusted"
)
),
Option(
'username', 'string', '', 0, 0, '',
"Username to use on server"
),
Option( Option(
'password', 'string', '', 0, 0, '', 'password', 'string', '', 0, 0, '',
("Password for server (note: content is evaluated, see /help " ("Password for server (note: content is evaluated, see /help "
"eval)") "eval)")),
), Option('device_name', 'string', '', 0, 0, 'Weechat Matrix',
Option( "Device name to use while logging in to the matrix server"),
'device_name', 'string', '', 0, 0, 'Weechat Matrix',
"Device name to use while logging in to the matrix server"
),
] ]
section = W.config_search_section(config_file, 'server') section = W.config_search_section(config_file, 'server')
@ -137,10 +117,10 @@ class MatrixServer:
server=self.name, option=option.name) server=self.name, option=option.name)
self.options[option.name] = W.config_new_option( self.options[option.name] = W.config_new_option(
config_file, section, option_name, config_file, section, option_name, option.type,
option.type, option.description, option.string_values, option.description, option.string_values, option.min,
option.min, option.max, option.value, option.value, 0, "", option.max, option.value, option.value, 0, "", "",
"", "matrix_config_server_change_cb", self.name, "", "") "matrix_config_server_change_cb", self.name, "", "")
def reset_parser(self): def reset_parser(self):
self.http_parser = HttpParser() self.http_parser = HttpParser()
@ -190,8 +170,7 @@ class MatrixServer:
prnt_debug(DebugType.MESSAGING, self, prnt_debug(DebugType.MESSAGING, self,
("{prefix} Failed sending message of type {t}. " ("{prefix} Failed sending message of type {t}. "
"Adding to queue").format( "Adding to queue").format(
prefix=W.prefix("error"), prefix=W.prefix("error"), t=message.type))
t=message.type))
self.send_queue.append(message) self.send_queue.append(message)
def try_send(self, message): def try_send(self, message):
@ -206,12 +185,7 @@ class MatrixServer:
sent = sock.send(message[total_sent:]) sent = sock.send(message[total_sent:])
except ssl.SSLWantWriteError: except ssl.SSLWantWriteError:
hook = W.hook_fd( hook = W.hook_fd(sock.fileno(), 0, 1, 0, "send_cb", self.name)
sock.fileno(),
0, 1, 0,
"send_cb",
self.name
)
self.send_fd_hook = hook self.send_fd_hook = hook
self.send_buffer = message[total_sent:] self.send_buffer = message[total_sent:]
return True return True
@ -225,14 +199,12 @@ class MatrixServer:
error_message = ("{prefix}Error while writing to " error_message = ("{prefix}Error while writing to "
"socket: {error}").format( "socket: {error}").format(
prefix=W.prefix("network"), prefix=W.prefix("network"), error=strerr)
error=strerr)
server_buffer_prnt(self, error_message) server_buffer_prnt(self, error_message)
server_buffer_prnt( server_buffer_prnt(
self, self, ("{prefix}matrix: disconnecting from server..."
("{prefix}matrix: disconnecting from server...").format( ).format(prefix=W.prefix("network")))
prefix=W.prefix("network")))
self.disconnect() self.disconnect()
return False return False
@ -245,9 +217,8 @@ class MatrixServer:
"{prefix}matrix: Error while writing to socket".format( "{prefix}matrix: Error while writing to socket".format(
prefix=W.prefix("network"))) prefix=W.prefix("network")))
server_buffer_prnt( server_buffer_prnt(
self, self, ("{prefix}matrix: disconnecting from server..."
("{prefix}matrix: disconnecting from server...").format( ).format(prefix=W.prefix("network")))
prefix=W.prefix("network")))
self.disconnect() self.disconnect()
return False return False
@ -269,7 +240,6 @@ class MatrixServer:
self.send_buffer = b"" self.send_buffer = b""
self.current_message = None self.current_message = None
def send(self, message): def send(self, message):
# type: (MatrixServer, MatrixMessage) -> bool # type: (MatrixServer, MatrixMessage) -> bool
if self.current_message: if self.current_message:
@ -287,8 +257,8 @@ class MatrixServer:
return True return True
def reconnect(self): def reconnect(self):
message = ("{prefix}matrix: reconnecting to server...").format( message = ("{prefix}matrix: reconnecting to server..."
prefix=W.prefix("network")) ).format(prefix=W.prefix("network"))
server_buffer_prnt(self, message) server_buffer_prnt(self, message)
@ -309,8 +279,7 @@ class MatrixServer:
message = ("{prefix}matrix: reconnecting to server in {t} " message = ("{prefix}matrix: reconnecting to server in {t} "
"seconds").format( "seconds").format(
prefix=W.prefix("network"), prefix=W.prefix("network"), t=self.reconnect_delay)
t=self.reconnect_delay)
server_buffer_prnt(self, message) server_buffer_prnt(self, message)
@ -347,8 +316,8 @@ class MatrixServer:
self.reconnect_time = None self.reconnect_time = None
if self.server_buffer: if self.server_buffer:
message = ("{prefix}matrix: disconnected from server").format( message = ("{prefix}matrix: disconnected from server"
prefix=W.prefix("network")) ).format(prefix=W.prefix("network"))
server_buffer_prnt(self, message) server_buffer_prnt(self, message)
if reconnect: if reconnect:
@ -375,13 +344,8 @@ class MatrixServer:
create_server_buffer(self) create_server_buffer(self)
if not self.timer_hook: if not self.timer_hook:
self.timer_hook = W.hook_timer( self.timer_hook = W.hook_timer(1 * 1000, 0, 0, "matrix_timer_cb",
1 * 1000, self.name)
0,
0,
"matrix_timer_cb",
self.name
)
ssl_message = " (SSL)" if self.ssl_context.check_hostname else "" ssl_message = " (SSL)" if self.ssl_context.check_hostname else ""
@ -394,35 +358,26 @@ class MatrixServer:
W.prnt(self.server_buffer, message) W.prnt(self.server_buffer, message)
W.hook_connect("", self.address, self.port, 1, 0, "", W.hook_connect("", self.address, self.port, 1, 0, "", "connect_cb",
"connect_cb", self.name) self.name)
return True return True
def sync(self): def sync(self):
message = MatrixSyncMessage( message = MatrixSyncMessage(self.client, self.next_batch,
self.client, OPTIONS.sync_limit)
self.next_batch,
OPTIONS.sync_limit
)
self.send_queue.append(message) self.send_queue.append(message)
def login(self): def login(self):
# type: (MatrixServer) -> None # type: (MatrixServer) -> None
message = MatrixLoginMessage( message = MatrixLoginMessage(self.client, self.user, self.password,
self.client, self.device_name)
self.user,
self.password,
self.device_name
)
self.send_or_queue(message) self.send_or_queue(message)
@utf8_decode @utf8_decode
def matrix_config_server_read_cb( def matrix_config_server_read_cb(data, config_file, section, option_name,
data, config_file, section, value):
option_name, value
):
return_code = W.WEECHAT_CONFIG_OPTION_SET_ERROR return_code = W.WEECHAT_CONFIG_OPTION_SET_ERROR
@ -479,8 +434,7 @@ def matrix_timer_cb(server_name, remaining_calls):
current_time = time.time() current_time = time.time()
if ((not server.connected) and if ((not server.connected) and server.reconnect_time and
server.reconnect_time and
current_time >= (server.reconnect_time + server.reconnect_delay)): current_time >= (server.reconnect_time + server.reconnect_delay)):
server.reconnect() server.reconnect()
return W.WEECHAT_RC_OK return W.WEECHAT_RC_OK
@ -504,8 +458,9 @@ def matrix_timer_cb(server_name, remaining_calls):
while server.send_queue: while server.send_queue:
message = server.send_queue.popleft() message = server.send_queue.popleft()
prnt_debug(DebugType.MESSAGING, server, prnt_debug(
("Timer hook found message of type {t} in queue. Sending " DebugType.MESSAGING,
server, ("Timer hook found message of type {t} in queue. Sending "
"out.".format(t=message.type))) "out.".format(t=message.type)))
if not server.send(message): if not server.send(message):