diff --git a/matrix/buffer.py b/matrix/buffer.py index e08d038..f27d20b 100644 --- a/matrix/buffer.py +++ b/matrix/buffer.py @@ -122,8 +122,8 @@ class WeechatChannelBuffer(object): membership_messages = { "join": "has joined", "part": "has left", - "kick": "has been kicked", - "invite": "has been invited" + "kick": "has been kicked from", + "invite": "has been invited to" } def __init__(self, name, server_name, user): @@ -352,6 +352,8 @@ class WeechatChannelBuffer(object): # type: (WeechatUser, str) -> str action_color = ("green" if message_type == "join" or message_type == "invite" else "red") + prefix = ("join" if message_type == "join" or message_type == "invite" + else "quit") membership_message = self.membership_messages[message_type] @@ -359,7 +361,7 @@ class WeechatChannelBuffer(object): "{del_color}({host_color}{host}{del_color})" "{action_color} {message} " "{channel_color}{room}{ncolor}").format( - prefix=W.prefix(message_type), + prefix=W.prefix(prefix), color=W.color(user.color), author=user.nick, ncolor=W.color("reset"), @@ -369,7 +371,7 @@ class WeechatChannelBuffer(object): action_color=W.color(action_color), message=membership_message, channel_color=W.color("chat_channel"), - room=self.name) + room=self.short_name) return message @@ -391,10 +393,14 @@ class WeechatChannelBuffer(object): def _remove_user_from_nicklist(self, user): # type: (WeechatUser) -> None - pass + nick_pointer = W.nicklist_search_nick(self._ptr, "", user.nick) - def _leave(self, user, date, message, leave_type, extra_tags): - # type: (WeechatUser, int, bool, str, List[str]) -> None + if nick_pointer: + W.nicklist_remove_nick(self._ptr, nick_pointer) + + def _leave(self, nick, date, message, leave_type, extra_tags): + # type: (str, int, bool, str, List[str]) -> None + user = self._get_user(nick) self._remove_user_from_nicklist(user) if message: @@ -405,13 +411,13 @@ class WeechatChannelBuffer(object): if user.nick in self.users: del self.users[user.nick] - def part(self, user, date, message=True, extra_tags=[]): - # type: (WeechatUser, int, Optional[bool], Optional[List[str]]) -> None - self._leave(user, date, message, "leave", extra_tags) + def part(self, nick, date, message=True, extra_tags=[]): + # type: (str, int, Optional[bool], Optional[List[str]]) -> None + self._leave(nick, date, message, "part", extra_tags) - def kick(self, user, date, message=True, extra_tags=[]): - # type: (WeechatUser, int, Optional[bool], Optional[List[str]]) -> None - self._leave(user, date, message, "kick", extra_tags=[]) + def kick(self, nick, date, message=True, extra_tags=[]): + # type: (str, int, Optional[bool], Optional[List[str]]) -> None + self._leave(nick, date, message, "kick", extra_tags=[]) def _print_topic(self, nick, topic, date): user = self._get_user(nick) diff --git a/matrix/rooms.py b/matrix/rooms.py index 4900ccf..f03251f 100644 --- a/matrix/rooms.py +++ b/matrix/rooms.py @@ -143,6 +143,20 @@ class MatrixRoom: """ return not self.is_named() + def handle_event(self, event): + if isinstance(event, RoomMemberJoin): + if event.sender in self.users: + user = self.users[event.sender] + if event.display_name: + user.display_name = event.display_name + else: + short_name = shorten_sender(event.sender) + user = MatrixUser(short_name, event.display_name) + self.users[event.sender] = user + elif isinstance(event, RoomMemberLeave): + if event.leaving_user in self.users: + del self.users[event.leaving_user] + class MatrixUser: @@ -513,43 +527,11 @@ class RoomMessageMedia(RoomMessageEvent): self._print_message(msg, room, buff, tags) -class RoomMembershipMessage(RoomEvent): - def __init__(self, event_id, sender, timestamp, message, prefix): - self.message = message - self.prefix = prefix - RoomEvent.__init__(self, event_id, sender, timestamp) - - def execute(self, server, room, buff, tags): - nick, color_name = sender_to_nick_and_color(room, self.sender) - event_tags = add_event_tags(self.event_id, nick, None, []) - # TODO this should be configurable - action_color = "red" if self.prefix == "quit" else "green" - - data = ("{prefix}{color}{author}{ncolor} " - "{del_color}({host_color}{user_id}{del_color})" - "{action_color} {message} " - "{channel_color}{room}{ncolor}").format( - prefix=W.prefix(self.prefix), - color=W.color(color_name), - author=nick, - ncolor=W.color("reset"), - del_color=W.color("chat_delimiters"), - host_color=W.color("chat_host"), - user_id=self.sender, - action_color=W.color(action_color), - message=self.message, - channel_color=W.color("chat_channel"), - room="" if room.is_group() else room.named_room_name()) - date = server_ts_to_weechat(self.timestamp) - tags_string = ",".join(event_tags) - - W.prnt_date_tags(buff, date, tags_string, data) - - class RoomMemberJoin(RoomEvent): - def __init__(self, event_id, sender, timestamp, display_name): + def __init__(self, event_id, sender, timestamp, display_name, state_key): self.display_name = display_name + self.state_key = state_key RoomEvent.__init__(self, event_id, sender, timestamp) @classmethod @@ -557,6 +539,7 @@ class RoomMemberJoin(RoomEvent): event_id = sanitize_id(event_dict["event_id"]) sender = sanitize_id(event_dict["sender"]) timestamp = sanitize_ts(event_dict["origin_server_ts"]) + state_key = sanitize_id(event_dict["state_key"]) display_name = None if event_dict["content"]: @@ -564,7 +547,7 @@ class RoomMemberJoin(RoomEvent): display_name = sanitize_text( event_dict["content"]["displayname"]) - return cls(event_id, sender, timestamp, display_name) + return cls(event_id, sender, timestamp, display_name, state_key) class RoomMemberLeave(RoomEvent): @@ -582,19 +565,6 @@ class RoomMemberLeave(RoomEvent): return cls(event_id, sender, leaving_user, timestamp) - def execute(self, server, room, buff, tags): - if self.leaving_user in room.users: - nick_pointer = W.nicklist_search_nick(buff, "", self.leaving_user) - - if nick_pointer: - W.nicklist_remove_nick(buff, nick_pointer) - - del room.users[self.leaving_user] - - # calculate room display name and set it as the buffer list name - room_name = room.display_name(server.user_id) - W.buffer_set(buff, "short_name", room_name) - class RoomPowerLevels(RoomEvent): diff --git a/matrix/server.py b/matrix/server.py index 2cff3ce..694e86b 100644 --- a/matrix/server.py +++ b/matrix/server.py @@ -639,38 +639,39 @@ class MatrixServer: is_state_event ): if isinstance(event, RoomMemberJoin): - if event.sender in room.users: - user = room.users[event.sender] - if event.display_name: - user.display_name = event.display_name - else: - short_name = shorten_sender(event.sender) - user = MatrixUser(short_name, event.display_name) - buffer_user = RoomUser(user.name, event.sender) - # TODO remove this duplication - user.nick_color = buffer_user.color - room.users[event.sender] = user + room.handle_event(event) + user = room.users[event.sender] + buffer_user = RoomUser(user.name, event.sender) + # TODO remove this duplication + user.nick_color = buffer_user.color - if self.user_id == event.sender: - buffer_user.color = "weechat.color.chat_nick_self" - user.nick_color = "weechat.color.chat_nick_self" + if self.user_id == event.sender: + buffer_user.color = "weechat.color.chat_nick_self" + user.nick_color = "weechat.color.chat_nick_self" - room_buffer.join( - buffer_user, - server_ts_to_weechat(event.timestamp), - not is_state_event - ) + room_buffer.join( + buffer_user, + server_ts_to_weechat(event.timestamp), + not is_state_event + ) - # calculate room display name and set it as the buffer list name - room_name = room.display_name(self.user_id) - room_buffer.short_name = room_name - - # A user has joined an encrypted room, we need to check for - # new devices - if room.encrypted: - self.device_check_timestamp = None elif isinstance(event, RoomMemberLeave): - pass + user = room.users[event.sender] + date = server_ts_to_weechat(event.timestamp) + + if event.sender == event.leaving_user: + room_buffer.part(user.name, date, not is_state_event) + else: + room_buffer.kick(user.name, date, not is_state_event) + + # calculate room display name and set it as the buffer list name + room_name = room.display_name(self.user_id) + room_buffer.short_name = room_name + + # A user has joined or left an encrypted room, we need to check for + # new devices and create a new group session + if room.encrypted: + self.device_check_timestamp = None def handle_room_event(self, room, room_buffer, event, is_state_event): if isinstance(event, (RoomMemberJoin, RoomMemberLeave)):