diff --git a/mautrix_appservice/appservice.py b/mautrix_appservice/appservice.py index 0b66d57b..70d883b3 100644 --- a/mautrix_appservice/appservice.py +++ b/mautrix_appservice/appservice.py @@ -56,6 +56,8 @@ class AppService: self.app.router.add_route("GET", "/rooms/{alias}", self._http_query_alias) self.app.router.add_route("GET", "/users/{user_id}", self._http_query_user) + self.matrix_event_handler(self.update_state_store) + @property def http_session(self): if self._http_session is None: @@ -150,6 +152,14 @@ class AppService: return web.json_response({}) + def update_state_store(self, event): + event_type = event["type"] + if event_type == "m.room.power_levels": + self.state_store.set_power_levels(event["room_id"], event["content"]) + elif event_type == "m.room.member": + self.state_store.set_membership(event["room_id"], event["state_key"], + event["content"]["membership"]) + def handle_matrix_event(self, event): for handler in self.event_handlers: try: diff --git a/mautrix_appservice/intent_api.py b/mautrix_appservice/intent_api.py index aa8b322c..34d0899f 100644 --- a/mautrix_appservice/intent_api.py +++ b/mautrix_appservice/intent_api.py @@ -225,8 +225,13 @@ class IntentAPI: self._ensure_has_power_level_for(room_id, "m.room.name") return self.client.set_room_name(room_id, name) - def get_power_levels(self, room_id): + def get_power_levels(self, room_id, ignore_cache=False): self._ensure_joined(room_id) + if not ignore_cache: + try: + return self.state_store.get_power_levels(room_id) + except KeyError: + pass levels = self.client.get_power_levels(room_id) self.state_store.set_power_levels(room_id, levels) return levels @@ -325,7 +330,7 @@ class IntentAPI: self.client.join_room(room_id) self.state_store.joined(room_id, self.mxid) except MatrixRequestError as e: - if matrix_error_code(e) != "M_FORBIDDEN" and not self.bot: + if matrix_error_code(e) != "M_FORBIDDEN" or not self.bot: raise IntentError(f"Failed to join room {room_id} as {self.mxid}", e) try: self.bot.invite_user(room_id, self.mxid) @@ -342,18 +347,20 @@ class IntentAPI: except MatrixRequestError as e: if matrix_error_code(e) != "M_USER_IN_USE": self.log.exception(f"Failed to register {self.mxid}!") - return # raise IntentError(f"Failed to register {self.mxid}", e) + return self.state_store.registered(self.mxid) def _ensure_has_power_level_for(self, room_id, event_type): - if not self.state_store.has_power_level_data(room_id): + if not self.state_store.has_power_levels(room_id): self.get_power_levels(room_id) if self.state_store.has_power_level(room_id, self.mxid, event_type): return elif not self.bot: - pass + self.log.warning( + f"Power level of {self.mxid} is not enough for {event_type} in {room_id}") # raise IntentError(f"Power level of {self.mxid} is not enough for {event_type} in {room_id}") + return # TODO implement # endregion diff --git a/mautrix_appservice/state_store.py b/mautrix_appservice/state_store.py index decc35d5..a7dba6f8 100644 --- a/mautrix_appservice/state_store.py +++ b/mautrix_appservice/state_store.py @@ -70,30 +70,34 @@ class StateStore: self.registrations.add(user) self._autosave() - def _get_membership(self, room, user): + def get_membership(self, room, user): return self.memberships.get(room, {}).get(user, "left") def is_joined(self, room, user): - return self._get_membership(room, user) == "join" + print("Is joined", room, user, self.get_membership(room, user), self.get_membership(room, user) == "join") + return self.get_membership(room, user) == "join" - def _set_membership(self, room, user, membership): + def set_membership(self, room, user, membership): if room not in self.memberships: self.memberships[room] = {} self.memberships[room][user] = membership self._autosave() def joined(self, room, user): - return self._set_membership(room, user, "join") + return self.set_membership(room, user, "join") def invited(self, room, user): - return self._set_membership(room, user, "invite") + return self.set_membership(room, user, "invite") def left(self, room, user): - return self._set_membership(room, user, "left") + return self.set_membership(room, user, "left") - def has_power_level_data(self, room): + def has_power_levels(self, room): return room in self.power_levels + def get_power_levels(self, room): + return self.power_levels[room] + def has_power_level(self, room, user, event): room_levels = self.power_levels.get(room, {}) required = room_levels["events"].get(event, 95)