comparison libervia/backend/plugins/plugin_xep_0045.py @ 4359:a987a8ce34b9

plugin XEP-0045: add MUC search to plugin JID search results.
author Goffi <goffi@goffi.org>
date Fri, 11 Apr 2025 18:19:28 +0200
parents 0d7bb4df2343
children b74a76a8e168
comparison
equal deleted inserted replaced
4358:c8d089b0e478 4359:a987a8ce34b9
15 # GNU Affero General Public License for more details. 15 # GNU Affero General Public License for more details.
16 16
17 # You should have received a copy of the GNU Affero General Public License 17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 import difflib
20 import time 21 import time
21 from typing import Optional 22 from typing import Optional, cast
22 import uuid 23 import uuid
23 24
24 import shortuuid 25 import shortuuid
25 from twisted.internet import defer 26 from twisted.internet import defer
26 from twisted.python import failure 27 from twisted.python import failure
35 from libervia.backend.core.core_types import SatXMPPEntity 36 from libervia.backend.core.core_types import SatXMPPEntity
36 from libervia.backend.core.constants import Const as C 37 from libervia.backend.core.constants import Const as C
37 from libervia.backend.core.i18n import D_, _ 38 from libervia.backend.core.i18n import D_, _
38 from libervia.backend.core.log import getLogger 39 from libervia.backend.core.log import getLogger
39 from libervia.backend.memory import memory 40 from libervia.backend.memory import memory
41 from libervia.backend.plugins import plugin_misc_jid_search
40 from libervia.backend.tools import xml_tools, utils 42 from libervia.backend.tools import xml_tools, utils
41 43
42 44
43 log = getLogger(__name__) 45 log = getLogger(__name__)
44 46
47 C.PI_NAME: "XEP-0045 Plugin", 49 C.PI_NAME: "XEP-0045 Plugin",
48 C.PI_IMPORT_NAME: "XEP-0045", 50 C.PI_IMPORT_NAME: "XEP-0045",
49 C.PI_TYPE: "XEP", 51 C.PI_TYPE: "XEP",
50 C.PI_MODES: C.PLUG_MODE_BOTH, 52 C.PI_MODES: C.PLUG_MODE_BOTH,
51 C.PI_PROTOCOLS: ["XEP-0045"], 53 C.PI_PROTOCOLS: ["XEP-0045"],
52 C.PI_DEPENDENCIES: ["XEP-0359"], 54 C.PI_DEPENDENCIES: ["XEP-0359", "JID_SEARCH"],
53 C.PI_RECOMMENDATIONS: [C.TEXT_CMDS, "XEP-0313"], 55 C.PI_RECOMMENDATIONS: [C.TEXT_CMDS, "XEP-0313"],
54 C.PI_MAIN: "XEP_0045", 56 C.PI_MAIN: "XEP_0045",
55 C.PI_HANDLER: "yes", 57 C.PI_HANDLER: "yes",
56 C.PI_DESCRIPTION: _("""Implementation of Multi-User Chat"""), 58 C.PI_DESCRIPTION: _("""Implementation of Multi-User Chat"""),
57 } 59 }
87 89
88 def __init__(self, host): 90 def __init__(self, host):
89 log.info(_("Plugin XEP_0045 initialization")) 91 log.info(_("Plugin XEP_0045 initialization"))
90 self.host = host 92 self.host = host
91 self._sessions = memory.Sessions() 93 self._sessions = memory.Sessions()
94 self._jid_search = cast(
95 plugin_misc_jid_search.JidSearch, host.plugins["JID_SEARCH"]
96 )
92 # return same arguments as muc_room_joined + a boolean set to True is the room was 97 # return same arguments as muc_room_joined + a boolean set to True is the room was
93 # already joined (first argument) 98 # already joined (first argument)
94 host.bridge.add_method( 99 host.bridge.add_method(
95 "muc_join", 100 "muc_join",
96 ".plugin", 101 ".plugin",
202 host.trigger.add("presence_received", self.presence_received_trigger) 207 host.trigger.add("presence_received", self.presence_received_trigger)
203 host.trigger.add( 208 host.trigger.add(
204 "message_received", self.message_received_trigger, priority=1000000 209 "message_received", self.message_received_trigger, priority=1000000
205 ) 210 )
206 host.trigger.add("message_parse", self._message_parse_trigger) 211 host.trigger.add("message_parse", self._message_parse_trigger)
212 host.trigger.add(
213 "JID_SEARCH_perform_search", self.jid_search_perform_search_trigger
214 )
207 215
208 async def profile_connected(self, client): 216 async def profile_connected(self, client):
209 client.muc_service = await self.get_muc_service(client) 217 client.muc_service = await self.get_muc_service(client)
210 218
211 def _message_parse_trigger(self, client, message_elt, data): 219 def _message_parse_trigger(self, client, message_elt, data):
248 "joined, ignoring it: {}".format(message_elt.toXml()) 256 "joined, ignoring it: {}".format(message_elt.toXml())
249 ) 257 )
250 return False 258 return False
251 return True 259 return True
252 260
261 async def jid_search_perform_search_trigger(
262 self,
263 client: SatXMPPEntity,
264 search_term: str,
265 options: plugin_misc_jid_search.Options,
266 sequence_matcher: difflib.SequenceMatcher,
267 matches: plugin_misc_jid_search.SearchItems
268 ) -> bool:
269 if options.groupchat:
270 if client.muc_service is not None:
271 # FIXME: RSM is not handled, we need proper RSM handling as number of
272 # rooms may be large.
273 disco_items = await self.host.memory.disco.get_items(
274 client,
275 client.muc_service
276 )
277 for disco_item in disco_items:
278 search_item = plugin_misc_jid_search.RoomSearchItem(
279 entity = disco_item.entity,
280 name = disco_item.name or "",
281 local = True
282 )
283 self._jid_search.process_matching(
284 search_term, sequence_matcher, matches,search_item
285 )
286 return True
287
253 def get_room(self, client: SatXMPPEntity, room_jid: jid.JID) -> muc.Room: 288 def get_room(self, client: SatXMPPEntity, room_jid: jid.JID) -> muc.Room:
254 """Retrieve Room instance from its jid 289 """Retrieve Room instance from its jid
255 290
256 @param room_jid: jid of the room 291 @param room_jid: jid of the room
257 @raise exceptions.NotFound: the room has not been joined 292 @raise exceptions.NotFound: the room has not been joined