Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
matrix_olm_command_cb, matrix_devices_command_cb,
matrix_room_command_cb, matrix_uploads_command_cb,
matrix_upload_command_cb, matrix_send_anyways_cb,
matrix_reply_command_cb,
matrix_reply_command_cb, matrix_query_command_cb,
matrix_cursor_reply_signal_cb)
from matrix.completion import (init_completion, matrix_command_completion_cb,
matrix_debug_completion_cb,
Expand Down
7 changes: 7 additions & 0 deletions matrix/buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
RedactedEvent,
RedactionEvent,
RoomAliasEvent,
RoomCreateEvent,
RoomEncryptionEvent,
RoomMemberEvent,
RoomMessage,
Expand Down Expand Up @@ -749,6 +750,9 @@ def invite(self, nick, date, extra_tags=None):
message = self._membership_message(user, "invite")
self.print_date_tags(message, date, tags + (extra_tags or []))

def display(self):
W.buffer_set(self._ptr, "display", "1")

def remove_user_from_nicklist(self, user):
# type: (WeechatUser) -> None
nick_pointer = W.nicklist_search_nick(self._ptr, "", user.nick)
Expand Down Expand Up @@ -1543,6 +1547,9 @@ def handle_timeline_event(self, event, extra_tags=None):
elif isinstance(event, UnknownEvent):
pass

elif isinstance(event, RoomCreateEvent):
pass

elif isinstance(event, BadEvent):
self.print_bad_event(event, extra_tags)

Expand Down
68 changes: 68 additions & 0 deletions matrix/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ def invite(args):

return WeechatCommandParser._run_parser(parser, args)

@staticmethod
def query(args):
parser = WeechatArgParse(prog="query")
parser.add_argument("user_id")

return WeechatCommandParser._run_parser(parser, args)

@staticmethod
def join(args):
parser = WeechatArgParse(prog="join")
Expand Down Expand Up @@ -388,6 +395,23 @@ def hook_commands():
"",
)

W.hook_command(
# Command name and short description
"query",
"query an user",
# Synopsis
("<user-id>"),
# Description
(
"user-id: user-id of the room to join"
),
# Completions
"",
# Callback
"matrix_query_command_cb",
"",
)

W.hook_command(
# Command name and short description
"part",
Expand Down Expand Up @@ -1106,6 +1130,50 @@ def matrix_join_command_cb(data, buffer, args):

return W.WEECHAT_RC_OK

@utf8_decode
def matrix_query_command_cb(data, buffer, args):
parsed_args = WeechatCommandParser.query(args)
if not parsed_args:
return W.WEECHAT_RC_OK

user_id = parsed_args.user_id
matrix_user_id = ':' in user_id and '.' in user_id.split(':')[-1]

if not user_id.startswith('@'):
user_id = f"@{user_id}"

def join_or_create_user_room(user_id):
room = server.find_room_from_user_id(user_id)
if room and room.joined:
room.weechat_buffer.display()
return
# if not room.joined:
# server.room_join(room.room.room_id)
# FIXME: we may still need to create a new room and replace the
# one already existing
server.create_private_messaging_room(user_id)

for server in SERVERS.values():
if buffer == server.server_buffer:
if not matrix_user_id:
user_id = f"{user_id}:{server.address}"

join_or_create_user_room(user_id)
break
else:
buffer = server.find_room_from_ptr(buffer)
if buffer:
if not matrix_user_id:
user_id = f"{user_id}:{server.address}"
for room_user in buffer.weechat_buffer.users.values():
if parsed_args.user_id == room_user.nick:
user_id = room_user.host
break
join_or_create_user_room(user_id)
break

return W.WEECHAT_RC_OK


@utf8_decode
def matrix_part_command_cb(data, buffer, args):
Expand Down
34 changes: 34 additions & 0 deletions matrix/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
LocalProtocolError,
LoginResponse,
LoginInfoResponse,
JoinedRoomsResponse,
Response,
Rooms,
RoomSendResponse,
Expand All @@ -59,6 +60,7 @@
DeleteDevicesAuthResponse,
DeleteDevicesResponse,
TransportType,
RoomCreateResponse,
RoomMessagesResponse,
RoomMessagesError,
EncryptionError,
Expand Down Expand Up @@ -1636,6 +1638,17 @@ def handle_response(self, response):
elif isinstance(response, RoomSendResponse):
self.handle_own_messages(response)

elif isinstance(response, JoinedRoomsResponse):
for room_id in response.rooms:
try:
self.find_room_from_id(room_id)
except KeyError:
self.create_room_buffer(room_id, self.next_batch)

if len(response.rooms) == 1:
buffer = self.find_room_from_id(response.rooms[0])
buffer.weechat_buffer.display()

elif isinstance(response, RoomMessagesResponse):
self.handle_backlog_response(response)

Expand All @@ -1651,6 +1664,14 @@ def handle_response(self, response):
elif isinstance(response, DeleteDevicesResponse):
self.info("Device successfully deleted")

elif isinstance(response, RoomCreateResponse):
try:
buffer = self.find_room_from_id(response.room_id)
except KeyError:
self.create_room_buffer(response.room_id, self.next_batch)
buffer = self.find_room_from_id(response.room_id)
buffer.weechat_buffer.display()

elif isinstance(response, KeysQueryResponse):
self.keys_queried = False
W.bar_item_update("buffer_modes")
Expand Down Expand Up @@ -1766,6 +1787,10 @@ def create_room_buffer(self, room_id, prev_batch):
self.room_buffers[room_id] = buf
self.buffers[room_id] = buf.weechat_buffer._ptr

def create_private_messaging_room(self, user_id):
_, request = self.client.room_create(is_direct=True, invite={user_id})
self.send_or_queue(request)

def find_room_from_ptr(self, pointer):
try:
room_id = key_from_value(self.buffers, pointer)
Expand All @@ -1779,6 +1804,15 @@ def find_room_from_id(self, room_id):
room_buffer = self.room_buffers[room_id]
return room_buffer

def find_room_from_user_id(self, user_id):
for room_buffer in self.room_buffers.values():
if (room_buffer.weechat_buffer.type == "private" and
len(room_buffer.weechat_buffer.users) <= 2):
user_ids = [
u.host for u in room_buffer.weechat_buffer.users.values()]
if self.user_id and user_id in user_ids:
return room_buffer

def garbage_collect_users(self):
""" Remove inactive users.
This tries to keep the number of users added to the nicklist less than
Expand Down