Implement /kick.

This commit is contained in:
Denis Kasak 2018-03-05 23:38:14 +01:00 committed by poljar
parent 7434285ffb
commit b0872922ec
5 changed files with 109 additions and 8 deletions

View file

@ -43,7 +43,8 @@ from matrix.commands import (hook_commands, hook_page_up, matrix_command_cb,
matrix_command_join_cb, matrix_command_part_cb, matrix_command_join_cb, matrix_command_part_cb,
matrix_command_invite_cb, matrix_command_topic_cb, matrix_command_invite_cb, matrix_command_topic_cb,
matrix_command_pgup_cb, matrix_redact_command_cb, matrix_command_pgup_cb, matrix_redact_command_cb,
matrix_command_buf_clear_cb, matrix_me_command_cb) matrix_command_buf_clear_cb, matrix_me_command_cb,
matrix_command_kick_cb)
from matrix.server import ( from matrix.server import (
MatrixServer, MatrixServer,

View file

@ -207,6 +207,23 @@ class MatrixClient:
return HttpRequest(RequestType.POST, self.host, path, content) return HttpRequest(RequestType.POST, self.host, path, content)
def room_kick(self, room_id, user_id, reason=None):
query_parameters = {"access_token": self.access_token}
content = {"user_id": user_id}
if reason:
content["reason"] = reason
path = ("{api}/rooms/{room_id}/kick?"
"{query_parameters}").format(
api=MATRIX_API_PATH,
room_id=quote(room_id),
query_parameters=urlencode(query_parameters))
h = HttpRequest(RequestType.POST, self.host, path, content)
return h
def mxc_to_http(self, mxc): def mxc_to_http(self, mxc):
# type: (str) -> str # type: (str) -> str
url = urlparse(mxc) url = urlparse(mxc)
@ -469,3 +486,27 @@ class MatrixInviteMessage(MatrixMessage):
self.room_id, self.user_id) self.room_id, self.user_id)
return self._decode(server, object_hook) return self._decode(server, object_hook)
class MatrixKickMessage(MatrixMessage):
def __init__(self, client, room_id, user_id, reason=None):
self.room_id = room_id
self.user_id = user_id
self.reason = reason
data = {"room_id": self.room_id,
"user_id": self.user_id,
"reason": reason}
MatrixMessage.__init__(self, client.room_kick, data)
def decode_body(self, server):
object_hook = partial(
MatrixEvents.MatrixKickEvent.from_dict,
server,
self.room_id,
self.user_id,
self.reason)
return self._decode(server, object_hook)

View file

@ -27,7 +27,7 @@ from matrix.utf import utf8_decode
from matrix.api import (MatrixTopicMessage, MatrixRedactMessage, from matrix.api import (MatrixTopicMessage, MatrixRedactMessage,
MatrixBacklogMessage, MatrixJoinMessage, MatrixBacklogMessage, MatrixJoinMessage,
MatrixPartMessage, MatrixInviteMessage, MatrixPartMessage, MatrixInviteMessage,
MatrixEmoteMessage) MatrixEmoteMessage, MatrixKickMessage)
from matrix.utils import key_from_value, tags_from_line_data from matrix.utils import key_from_value, tags_from_line_data
from matrix.plugin_options import DebugType from matrix.plugin_options import DebugType
from matrix.server import MatrixServer from matrix.server import MatrixServer
@ -103,6 +103,7 @@ def hook_commands():
W.hook_command_run('/join', 'matrix_command_join_cb', '') W.hook_command_run('/join', 'matrix_command_join_cb', '')
W.hook_command_run('/part', 'matrix_command_part_cb', '') W.hook_command_run('/part', 'matrix_command_part_cb', '')
W.hook_command_run('/invite', 'matrix_command_invite_cb', '') W.hook_command_run('/invite', 'matrix_command_invite_cb', '')
W.hook_command_run('/kick', 'matrix_command_kick_cb', '')
if OPTIONS.enable_backlog: if OPTIONS.enable_backlog:
hook_page_up() hook_page_up()
@ -309,6 +310,42 @@ def matrix_command_invite_cb(data, buffer, command):
return W.WEECHAT_RC_OK return W.WEECHAT_RC_OK
@utf8_decode
def matrix_command_kick_cb(data, buffer, command):
def kick(server, buf, args):
split_args = args.split(" ", 1)[1:]
if (len(split_args) < 1 or
split_args[0].startswith("#") and len(split_args) < 2):
error_msg = (
'{prefix}Error with command "/kick" (help on '
'command: /help kick)').format(prefix=W.prefix("error"))
W.prnt("", error_msg)
return
if split_args[0].startswith("#"):
assert len(split_args) >= 2
room_id = split_args[0]
kicked_user = split_args[1]
reason = split_args[2:] or None
else:
room_id = key_from_value(server.buffers, buf)
kicked_user = split_args[0]
reason = split_args[1:] or None
message = MatrixKickMessage(
server.client, room_id=room_id, user_id=kicked_user, reason=reason)
server.send_or_queue(message)
for server in SERVERS.values():
if buffer in server.buffers.values():
kick(server, buffer, command)
return W.WEECHAT_RC_OK_EAT
return W.WEECHAT_RC_OK
def event_id_from_line(buf, target_number): def event_id_from_line(buf, target_number):
# type: (weechat.buffer, int) -> str # type: (weechat.buffer, int) -> str
own_lines = W.hdata_pointer(W.hdata_get('buffer'), buf, 'own_lines') own_lines = W.hdata_pointer(W.hdata_get('buffer'), buf, 'own_lines')
@ -918,7 +955,7 @@ def matrix_command_topic_cb(data, buffer, command):
elif buffer == server.server_buffer: elif buffer == server.server_buffer:
message = ("{prefix}matrix: command \"topic\" must be " message = ("{prefix}matrix: command \"topic\" must be "
"executed on a Matrix channel buffer" "executed on a Matrix channel buffer"
).format(prefix=W.prefix("error")) ).format(prefix=W.prefix("error"))
W.prnt(buffer, message) W.prnt(buffer, message)
return W.WEECHAT_RC_OK_EAT return W.WEECHAT_RC_OK_EAT

View file

@ -246,6 +246,26 @@ class MatrixInviteEvent(MatrixEvent):
False, parsed_dict) False, parsed_dict)
class MatrixKickEvent(MatrixEvent):
def __init__(self, server, room_id, user_id, reason):
self.room_id = room_id
self.user_id = user_id
self.reason = reason
MatrixEvent.__init__(self, server)
@classmethod
def from_dict(cls, server, room_id, user_id, reason, parsed_dict):
try:
if parsed_dict == {}:
return cls(server, room_id, user_id, reason)
raise KeyError
except KeyError:
return MatrixErrorEvent.from_dict(server, "Error kicking user",
False, parsed_dict)
class MatrixBacklogEvent(MatrixEvent): class MatrixBacklogEvent(MatrixEvent):
def __init__(self, server, room_id, end_token, events): def __init__(self, server, room_id, end_token, events):

View file

@ -465,25 +465,27 @@ class RoomMemberJoin(RoomEvent):
class RoomMemberLeave(RoomEvent): class RoomMemberLeave(RoomEvent):
def __init__(self, event_id, sender, age): def __init__(self, event_id, sender, leaving_user, age):
self.leaving_user = leaving_user
RoomEvent.__init__(self, event_id, sender, age) RoomEvent.__init__(self, event_id, sender, age)
@classmethod @classmethod
def from_dict(cls, event_dict): def from_dict(cls, event_dict):
event_id = sanitize_id(event_dict["event_id"]) event_id = sanitize_id(event_dict["event_id"])
sender = sanitize_id(event_dict["sender"]) sender = sanitize_id(event_dict["sender"])
leaving_user = sanitize_id(event_dict["state_key"])
age = sanitize_age(event_dict["unsigned"]["age"]) age = sanitize_age(event_dict["unsigned"]["age"])
return cls(event_id, sender, age) return cls(event_id, sender, leaving_user, age)
def execute(self, server, room, buff, tags): def execute(self, server, room, buff, tags):
if self.sender in room.users: if self.leaving_user in room.users:
nick_pointer = W.nicklist_search_nick(buff, "", self.sender) nick_pointer = W.nicklist_search_nick(buff, "", self.leaving_user)
if nick_pointer: if nick_pointer:
W.nicklist_remove_nick(buff, nick_pointer) W.nicklist_remove_nick(buff, nick_pointer)
del room.users[self.sender] del room.users[self.leaving_user]
class RoomPowerLevels(RoomEvent): class RoomPowerLevels(RoomEvent):