From eb8a83010dfa39d3cefdf265bffa503424670fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?poljar=20=28Damir=20Jeli=C4=87=29?= Date: Fri, 6 Jul 2018 18:16:13 +0200 Subject: [PATCH] buffer: Handle power level events. --- matrix/buffer.py | 37 ++++++++++++++++++++++++++++++++++++- matrix/rooms.py | 38 +++++++++++++------------------------- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/matrix/buffer.py b/matrix/buffer.py index 82a6d9e..aafdfc4 100644 --- a/matrix/buffer.py +++ b/matrix/buffer.py @@ -48,7 +48,8 @@ from .rooms import ( RoomMessageUnknown, RoomRedactionEvent, RoomRedactedMessageEvent, - RoomEncryptionEvent + RoomEncryptionEvent, + RoomPowerLevels ) @@ -92,6 +93,22 @@ class RoomUser(WeechatUser): prefix = self._get_prefix(power_level) return super().__init__(nick, user_id, prefix) + @property + def power_level(self): + # This shouldn't be used since it's a lossy function. It's only here + # for the setter + if self.prefix == "&": + return 100 + if self.prefix == "@": + return 50 + if self.prefix == "+": + return 10 + return 0 + + @power_level.setter + def power_level(self, level): + self.prefix = self._get_prefix(level) + @staticmethod def _get_prefix(power_level): # type: (int) -> str @@ -804,11 +821,26 @@ class RoomBuffer(object): def get_event_tags(event): return ["matrix_id_{}".format(event.event_id)] + def _handle_power_level(self, event): + for user_id in self.room.power_levels: + if user_id in self.displayed_nicks: + nick = self.find_nick(user_id) + + user = self.weechat_buffer.users[nick] + user.power_level = self.room.power_levels[user_id] + + # There is no way to change the group of a user without + # removing him from the nicklist + self.weechat_buffer._remove_user_from_nicklist(user) + self.weechat_buffer._add_user_to_nicklist(user) + def handle_state_event(self, event): if isinstance(event, RoomMembershipEvent): self.handle_membership_events(event, True) elif isinstance(event, RoomTopicEvent): self._handle_topic(event, True) + elif isinstance(event, RoomPowerLevels): + self._handle_power_level(event) def handle_timeline_event(self, event): if isinstance(event, RoomMembershipEvent): @@ -891,6 +923,9 @@ class RoomBuffer(object): "this room.") self.weechat_buffer.error(message) + elif isinstance(event, RoomPowerLevels): + self._handle_power_level(event) + def self_message(self, message): nick = self.find_nick(self.room.own_user_id) data = (message.formatted_message.to_weechat() diff --git a/matrix/rooms.py b/matrix/rooms.py index 8a1a7c5..10c9a51 100644 --- a/matrix/rooms.py +++ b/matrix/rooms.py @@ -48,6 +48,7 @@ class MatrixRoom: self.users = dict() # type: Dict[str, MatrixUser] self.encrypted = False # type: bool self.backlog_pending = False # type: bool + self.power_levels = {} # yapf: enable def display_name(self, own_user_id): @@ -145,6 +146,9 @@ class MatrixRoom: user.display_name = event.display_name else: short_name = shorten_sender(event.sender) + # TODO the default power level doesn't have to be 0 + level = (self.power_levels[event.sender] if event.sender in + self.power_levels else 0) user = MatrixUser(short_name, event.display_name) self.users[event.sender] = user return True @@ -163,6 +167,14 @@ class MatrixRoom: elif isinstance(event, RoomEncryptionEvent): self.encrypted = True + elif isinstance(event, RoomPowerLevels): + self.power_levels = event.power_levels + + # Update the power levels of the joined users + for user_id, level in self.power_levels.items(): + if user_id in self.users: + self.users[user_id].power_level = level + return False @@ -560,35 +572,11 @@ class RoomPowerLevels(RoomEvent): event_id = sanitize_id(event_dict["event_id"]) sender = sanitize_id(event_dict["sender"]) timestamp = sanitize_ts(event_dict["origin_server_ts"]) - power_levels = [] - for user, level in event_dict["content"]["users"].items(): - power_levels.append( - PowerLevel(sanitize_id(user), sanitize_power_level(level))) + power_levels = event_dict["content"].pop("users") return cls(event_id, sender, timestamp, power_levels) - def _set_power_level(self, room, buff, power_level): - user_id = power_level.user - level = power_level.level - - if user_id not in room.users: - return - - user = room.users[user_id] - user.power_level = level - user.prefix = get_prefix_for_level(level) - - nick_pointer = W.nicklist_search_nick(buff, "", user_id) - - if nick_pointer: - W.nicklist_remove_nick(buff, nick_pointer) - add_user_to_nicklist(buff, user_id, user) - - def execute(self, server, room, buff, tags): - for level in self.power_levels: - self._set_power_level(room, buff, level) - class RoomTopicEvent(RoomEvent):