Render !rooms entries as blockquote cards (name/members, topic, join link); v2.1.6

This commit is contained in:
Eddy de Vink 2026-09-04 15:54:30 +02:00
commit 874e84af76
4 changed files with 59 additions and 34 deletions

4
.gitignore vendored
View file

@ -101,6 +101,10 @@ jspm_packages/
ehthumbs.db
Thumbs.db
# Python
__pycache__/
*.pyc
# Test files
test/fixtures/
test/sample-pdfs/

View file

@ -1,6 +1,6 @@
maubot: 0.1.0
id: nl.roomsoverview
version: 2.1.2
version: 2.1.6
license: MIT
modules:
- roomsoverview

Binary file not shown.

View file

@ -244,8 +244,37 @@ class RoomsOverviewPlugin(Plugin):
pl = int(users.get(user_id, default) or 0)
return pl >= MOD_POWER_LEVEL
async def _room_exists(self, room_id: str) -> bool:
"""Bestaat de room nog? Alleen een duidelijke 404 telt als "weg".
200 en 403 (geen lid) betekenen "bestaat". Netwerk- en andere fouten
worden als "bestaat" behandeld, zodat er nooit per ongeluk data
verdwijnt.
"""
base = self._base_url()
h = self._headers()
rid = quote(room_id, safe="")
for path in (
f"{base}/_matrix/client/v3/rooms/{rid}/state/m.room.create",
f"{base}/_matrix/client/v3/rooms/{rid}/joined_members",
):
try:
async with self.http.get(
path, headers=h, timeout=_REQUEST_TIMEOUT
) as r:
if r.status == 404:
continue
return True # 200, 403, … alles behalve 404 = bestaat
except Exception:
return True
return False
async def _validate_all(self) -> Tuple[int, int]:
"""Valideer alle rooms in de index; verwijder verdwenen. (removed, total)"""
"""Valideer: verwijder alleen rooms die niet meer bestaan (404).
Werkt metadata NOOIT bij, alleen een duidelijke 404 op meerdere
endpoints verwijdert een rij. (removed, total)
"""
async with self._refresh_lock:
rows = await self.database.fetch(
"SELECT room_id FROM roomsoverview_rooms"
@ -253,24 +282,11 @@ class RoomsOverviewPlugin(Plugin):
removed = 0
for row in rows:
rid = row["room_id"]
info = await self._get_room_info(rid)
if info is None:
if not await self._room_exists(rid):
await self.database.execute(
"DELETE FROM roomsoverview_rooms WHERE room_id = $1", rid
)
removed += 1
else:
await self.database.execute(
"UPDATE roomsoverview_rooms SET display_name = $2, "
"canonical_alias = $3, topic = $4, member_count = $5, "
"last_checked = $6 WHERE room_id = $1",
rid,
info["name"] or None,
info["alias"] or None,
info["topic"] or None,
info["members"],
int(time.time()),
)
if removed:
self.log.info(f"validatie: {removed} room(s) verwijderd (bestaan niet meer)")
return removed, len(rows)
@ -301,35 +317,40 @@ class RoomsOverviewPlugin(Plugin):
rooms.sort(key=sort_key)
lines = []
rooms_blocks = []
for r in rooms:
display = r.get("display_name") or ""
alias = r.get("canonical_alias") or ""
room_id = r["room_id"]
link_target = quote(alias if alias else room_id, safe="!")
member_count = r.get("member_count")
topic = (r.get("topic") or "").strip().replace("\n", " ")
suffix = f" ({member_count} leden)" if member_count is not None else ""
if display:
label = _escape_md(display)
else:
label = room_id
link = f"[{_escape_md(alias) if alias else room_id}](https://matrix.to/#/{link_target})"
if display:
line = f"* **{label}**{suffix} — {link}"
else:
line = f"* {link}{suffix}"
# Elke room wordt een blockquote-kaart: een afgebakend blok met
# gekleurde kantlijn, naam + ledental als kop, omschrijving eronder
# en onderaan de join-link.
link_target = alias if alias else room_id
address = _escape_md(alias if alias else room_id)
lines = []
title = _escape_md(display) if display else address
meta = f"**{title}**"
if member_count is not None:
meta += f" · {member_count} leden"
lines.append(meta)
if topic:
line += f" — {_escape_md(topic)}"
lines.append(line)
lines.append(_escape_md(topic))
# Linktekst = volledige matrix.to URL (fragment mag rauw # en : bevatten)
lines.append(f"[{address}](https://matrix.to/#/{link_target})")
rooms_blocks.append("\n".join(f"> {l}" for l in lines))
chunk_size = max(1, int(self.config.get("rooms_per_message", 50) or 50))
chunks = [lines[i : i + chunk_size] for i in range(0, len(lines), chunk_size)]
total = len(lines)
chunks = [
rooms_blocks[i : i + chunk_size]
for i in range(0, len(rooms_blocks), chunk_size)
]
total = len(rooms_blocks)
for idx, chunk in enumerate(chunks, start=1):
header = f"**Rooms overzicht ({total} rooms getoond, deel {idx}/{len(chunks)}):**\n\n"
await evt.respond(header + "\n".join(chunk), markdown=True)
await evt.respond(header + "\n\n".join(chunk), markdown=True)
@command.new(
name="rooms",
@ -380,7 +401,7 @@ class RoomsOverviewPlugin(Plugin):
target = info["alias"] or room_id
await evt.reply(
f"Room toegevoegd: **{info['name'] or room_id}** "
f"([{target}](https://matrix.to/#/{quote(target, safe='!')}))"
f"([{target}](https://matrix.to/#/{target}))"
)
@handle_rooms.subcommand(name="remove", help="Verwijder een room (moderator+)")