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 35e6db8..1b34b3d 100644
Binary files a/roomsoverview.mbp and b/roomsoverview.mbp differ
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+)",