From d6c9fd8004941626af2b99d2c600863ee7631454 Mon Sep 17 00:00:00 2001 From: Eddy de Vink Date: Sun, 6 Sep 2026 14:34:04 +0200 Subject: [PATCH] Add !rooms over search: filter rooms by name/alias/topic (case-insensitive, all terms must match); v2.4.0 --- maubot.yaml | 2 +- roomsoverview.mbp | Bin 8762 -> 9148 bytes roomsoverview.py | 97 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 79 insertions(+), 20 deletions(-) diff --git a/maubot.yaml b/maubot.yaml index b114188..a41b9dd 100644 --- a/maubot.yaml +++ b/maubot.yaml @@ -1,6 +1,6 @@ maubot: 0.1.0 id: nl.roomsoverview -version: 2.3.1 +version: 2.4.0 license: MIT modules: - roomsoverview diff --git a/roomsoverview.mbp b/roomsoverview.mbp index 35e6db815435335eca7fa6e391b6739910a333dc..1b34b3da6809baf0df29e146c5e62585a5218019 100644 GIT binary patch delta 8743 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 delta 8353 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 diff --git a/roomsoverview.py b/roomsoverview.py index 7f1d0bb..677cf8c 100644 --- a/roomsoverview.py +++ b/roomsoverview.py @@ -435,23 +435,16 @@ class RoomsOverviewPlugin(Plugin): ) return [dict(r) for r in rows] - async def _send_list(self, evt: MessageEvent) -> None: - rooms = await self._list_rooms() - if not rooms: - await evt.reply( - "De room-index is nog leeg. Moderators kunnen rooms toevoegen met " - "`!rooms add `." - ) - return + def _sort_rooms(self, rooms: List[Dict[str, Any]]) -> List[Dict[str, Any]]: + return sorted( + rooms, + key=lambda r: ( + r.get("display_name") or r.get("canonical_alias") or r["room_id"] + ).lower(), + ) - def sort_key(r: Dict[str, Any]) -> str: - return ( - r.get("display_name") - or r.get("canonical_alias") - or r["room_id"] - ).lower() - - rooms.sort(key=sort_key) + def _build_cards(self, rooms: List[Dict[str, Any]]) -> List[Tuple[str, str]]: + """Bouw per room een blockquote-kaart (html, plain).""" # Elke room wordt een blockquote-kaart: icoontje + naam/leden als kop, # omschrijving eronder, onderaan de join-link. De formatted_body bouwen @@ -510,13 +503,21 @@ class RoomsOverviewPlugin(Plugin): f"{e(address)}

" ) cards.append(("".join(body_parts), plain)) + return cards + async def _send_cards( + self, + evt: MessageEvent, + cards: List[Tuple[str, str]], + subject: str, + count_label: str, + ) -> None: chunk_size = max(1, int(self.config.get("rooms_per_message", 50) or 50)) chunks = [cards[i : i + chunk_size] for i in range(0, len(cards), chunk_size)] total = len(cards) for idx, chunk in enumerate(chunks, start=1): - header = f"Rooms overzicht ({total} rooms getoond, deel {idx}/{len(chunks)}):" + header = f"{subject} ({total} {count_label}, deel {idx}/{len(chunks)}):" html_body = ( f'

{html.escape(header)}

' + "".join(html_part for html_part, _ in chunk) @@ -530,6 +531,47 @@ class RoomsOverviewPlugin(Plugin): ) await evt.respond(content) + async def _send_list(self, evt: MessageEvent) -> None: + rooms = self._sort_rooms(await self._list_rooms()) + if not rooms: + await evt.reply( + "De room-index is nog leeg. Moderators kunnen rooms toevoegen met " + "`!rooms add `." + ) + return + await self._send_cards( + evt, self._build_cards(rooms), "Rooms overzicht", "rooms getoond" + ) + + async def _search_rooms(self, terms: str) -> List[Dict[str, Any]]: + """Zoek rooms: alle termen moeten matchen (case-insensitive, substring) + in naam, alias of omschrijving.""" + needles = [t for t in (part.lower() for part in terms.split()) if t] + if not needles: + return [] + found = [] + for r in await self._list_rooms(): + hay = " ".join( + str(r.get(field) or "").lower() + for field in ("display_name", "canonical_alias", "topic") + ) + if all(n in hay for n in needles): + found.append(r) + return self._sort_rooms(found) + + async def _send_search(self, evt: MessageEvent, query: str) -> None: + found = await self._search_rooms(query) + query_label = " ".join(query.split()) + if not found: + await evt.reply(f"Geen rooms gevonden voor `{query_label}`.") + return + await self._send_cards( + evt, + self._build_cards(found), + f"Zoekresultaten voor '{query_label}'", + "gevonden", + ) + async def _send_help(self, evt: MessageEvent) -> None: """Uitgebreide Nederlandstalige handleiding voor !rooms.""" help_text = ( @@ -539,7 +581,10 @@ class RoomsOverviewPlugin(Plugin): "naast de naam.\n\n" "**Basis:**\n" "* `!rooms` — toon de volledige lijst (bij veel rooms verdeeld " - "over meerdere berichten)\n\n" + "over meerdere berichten)\n" + "* `!rooms over ` — zoek rooms op naam, alias en/of " + "omschrijving (bijv. `!rooms over linux`); alle termen moeten " + "matchen\n\n" "**Subcommando's (moderator of hoger vereist):**\n" "* `!rooms add ` — voeg een room toe aan de index\n" "* `!rooms edit =` — wijzig een " @@ -561,7 +606,7 @@ class RoomsOverviewPlugin(Plugin): @command.new( name="rooms", - help="Toon de room-index als kaarten; subcommands: add, edit, remove, refresh, help", + help="Toon de room-index als kaarten; subcommands: over (zoeken), add, edit, remove, refresh, help", require_subcommand=False, ) async def handle_rooms(self, evt: MessageEvent) -> None: @@ -572,6 +617,20 @@ class RoomsOverviewPlugin(Plugin): async def rooms_help(self, evt: MessageEvent) -> None: await self._send_help(evt) + @handle_rooms.subcommand( + name="over", + help="Zoek rooms op naam, alias of omschrijving: !rooms over ", + ) + @command.argument("terms", pass_raw=True, required=True) + async def search_over(self, evt: MessageEvent, terms: str) -> None: + if not terms.strip(): + await evt.reply( + "Gebruik: `!rooms over ` (bijv. `!rooms over linux`).\n" + "Zoekt op naam, alias en omschrijving; alle termen moeten matchen." + ) + return + await self._send_search(evt, terms) + @handle_rooms.subcommand( name="add", help="Voeg een room toe aan de index: !rooms add (moderator+)",