From c4e3a2b0153204b10fa0cd17eda39a144c4f5278 Mon Sep 17 00:00:00 2001 From: Goffi Date: Fri, 25 Sep 2026 15:02:04 +0200 Subject: [PATCH] plugin XEP-0045: add `set_room_configuration` and `is_jid_in_room` methods: The `set_room_configuration` allow to update configuration with well-known options. The `is_jid_in_room` check if an entity with the given real JID is in the room. --- libervia/backend/plugins/plugin_xep_0045.py | 62 +++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/libervia/backend/plugins/plugin_xep_0045.py b/libervia/backend/plugins/plugin_xep_0045.py index d18b1f77..96c342c5 100644 --- a/libervia/backend/plugins/plugin_xep_0045.py +++ b/libervia/backend/plugins/plugin_xep_0045.py @@ -743,6 +743,46 @@ class XEP_0045: del self._sessions[raw_data["session_id"]] return d + async def set_room_configuration( + self, client: SatXMPPEntity, room_jid: jid.JID, options: dict + ) -> None: + """Set MUC configuration. + + Values from ``options`` are set if the corresponding field exists in the room's + configuration form, otherwise they are ignored; a ``None`` value removes the + field's value. Other fields are not modified. + + @param client: The client instance. + @param options: option name -> value. + """ + muc_client = client.get_plugin_data(IMPORT_NAME, MUCClientData).muc_client + form = await muc_client.getConfiguration(room_jid) + if form is None: + log.warning( + f"[{client.profile}] can't get the configuration form of " + f"{room_jid}, not applying {options}" + ) + return + config: dict = {} + for field in form.fields.values(): + if field.values: + # DataForm values are always lists (even single-valued fields + # have one element); `configure()` accepts a list for any field + config[field.var] = field.values + for var, value in options.items(): + if var in form.fields: + config[var] = value + else: + log.warning( + f"[{client.profile}] config field {var} not present in the form of " + f"{room_jid}, ignoring it" + ) + await muc_client.configure(room_jid, config) + log.info( + f"[{client.profile}] room {room_jid.userhost()} configuration updated with " + f"{options}" + ) + def is_nick_in_room( self, client: SatXMPPEntity, room_jid: jid.JID, nick: str ) -> bool: @@ -754,6 +794,28 @@ class XEP_0045: .inRoster(muc.User(nick)) ) + def is_jid_in_room( + self, client: SatXMPPEntity, room_jid: jid.JID, user_jid: jid.JID + ) -> bool: + """Tell if a read JIDcurrently present in a room. + + Only the bare JID will be checked. This can work only if profile can access real + JIDs in the room (owner of the room, or the room is not anonymous). + + @param room_jid: JID of the room to check. + @param user_jid: JID of the entity to check. + + """ + try: + room = self.get_room(client, room_jid) + except exceptions.NotFound: + return False + bare_jid = user_jid.userhost() + return any( + user.entity is not None and user.entity.userhost() == bare_jid + for user in room.roster.values() + ) + # Text commands def _get_muc_service(