From 5de3d744361941899a7a39376a5ef05e9b71858f Mon Sep 17 00:00:00 2001 From: timedout Date: Sat, 31 Oct 2026 22:30:23 +0000 Subject: [PATCH] feat: Move `list-extremities` to `graph` room subcommand --- src/admin/debug/commands.rs | 42 +-------------------------- src/admin/debug/mod.rs | 4 --- src/admin/room/graph.rs | 57 +++++++++++++++++++++++++++++++++++++ src/admin/room/mod.rs | 17 +++++++---- 4 files changed, 69 insertions(+), 51 deletions(-) create mode 100644 src/admin/room/graph.rs diff --git a/src/admin/debug/commands.rs b/src/admin/debug/commands.rs index eba80b214..ce304a1e8 100644 --- a/src/admin/debug/commands.rs +++ b/src/admin/debug/commands.rs @@ -13,7 +13,7 @@ use conduwuit::{ }, trace, utils, utils::{ - stream::{BroadbandExt, IterStream, ReadyExt}, + stream::{IterStream, ReadyExt}, string::EMPTY, }, warn, @@ -1084,44 +1084,4 @@ impl crate::Context<'_> { )) .await } - - pub(super) async fn room_extremities(&self, room_id: OwnedRoomId) -> Result { - let mut extremities = self - .services - .rooms - .state - .get_forward_extremities(&room_id) - .broad_filter_map(|event_id| async move { - self.services.rooms.timeline.get_pdu(&event_id).await.ok() - }) - .collect::>() - .await; - extremities.sort_by_key(|pdu| (pdu.depth, pdu.origin_server_ts)); - if extremities.is_empty() { - return Err!("No room extremities."); - } - self.write_str("| Event ID | Kind | Sender | Timestamp | Depth |\n") - .await?; - self.write_str("| -------- | ---- | ------ | --------- | ----- |\n") - .await?; - for pdu in extremities { - let url = format!( - "https://matrix.to/#/{}/{}?via={}", - room_id, - pdu.event_id(), - self.services.server.name - ); - self.write_str(&format!( - "| [`{}`]({url}) | `{}` | `{}` | `{}` | `{}` |\n", - pdu.event_id(), - pdu.kind(), - pdu.sender(), - pdu.origin_server_ts, - pdu.depth - )) - .await?; - } - - Ok(()) - } } diff --git a/src/admin/debug/mod.rs b/src/admin/debug/mod.rs index 6cf211109..6b49ae980 100644 --- a/src/admin/debug/mod.rs +++ b/src/admin/debug/mod.rs @@ -204,10 +204,6 @@ pub enum DebugCommand { page: Option, }, - RoomExtremities { - room_id: OwnedRoomId, - }, - /// Developer test stubs #[command(subcommand)] #[allow(non_snake_case)] diff --git a/src/admin/room/graph.rs b/src/admin/room/graph.rs new file mode 100644 index 000000000..988f64111 --- /dev/null +++ b/src/admin/room/graph.rs @@ -0,0 +1,57 @@ +use clap::Subcommand; +use conduwuit::{Err, Event, Result, utils::stream::BroadbandExt}; +use conduwuit_macros::admin_command_dispatch; +use futures::StreamExt; +use ruma::OwnedRoomOrAliasId; + +#[admin_command_dispatch] +#[derive(Debug, Subcommand)] +pub enum GraphCommand { + /// Lists all forward extremities in a room. + ListExtremities { + room: OwnedRoomOrAliasId, + }, +} + +impl crate::Context<'_> { + pub(super) async fn list_extremities(&self, room: OwnedRoomOrAliasId) -> Result { + let room_id = self.services.rooms.alias.resolve(&room).await?; + let mut extremities = self + .services + .rooms + .state + .get_forward_extremities(&room_id) + .broad_filter_map(|event_id| async move { + self.services.rooms.timeline.get_pdu(&event_id).await.ok() + }) + .collect::>() + .await; + extremities.sort_by_key(|pdu| (pdu.depth, pdu.origin_server_ts)); + if extremities.is_empty() { + return Err!("No room extremities."); + } + self.write_str("| Event ID | Type | Sender | Timestamp | Depth |\n") + .await?; + self.write_str("| -------- | ---- | ------ | --------- | ----- |\n") + .await?; + for pdu in extremities { + let url = format!( + "https://matrix.to/#/{}/{}?via={}", + room_id, + pdu.event_id(), + self.services.server.name + ); + self.write_str(&format!( + "| [`{}`]({url}) | `{}` | `{}` | `{}` | `{}` |\n", + pdu.event_id(), + pdu.kind(), + pdu.sender(), + pdu.origin_server_ts, + pdu.depth + )) + .await?; + } + + Ok(()) + } +} diff --git a/src/admin/room/mod.rs b/src/admin/room/mod.rs index 82ac3145d..2704169a9 100644 --- a/src/admin/room/mod.rs +++ b/src/admin/room/mod.rs @@ -1,6 +1,7 @@ mod alias; mod commands; mod directory; +mod graph; mod info; mod moderation; @@ -9,8 +10,8 @@ use conduwuit::Result; use ruma::{OwnedEventId, OwnedRoomId, OwnedRoomOrAliasId}; use self::{ - alias::RoomAliasCommand, directory::RoomDirectoryCommand, info::RoomInfoCommand, - moderation::RoomModerationCommand, + alias::RoomAliasCommand, directory::RoomDirectoryCommand, graph::GraphCommand, + info::RoomInfoCommand, moderation::RoomModerationCommand, }; use crate::admin_command_dispatch; @@ -40,22 +41,26 @@ pub enum RoomCommand { no_details: bool, }, - #[command(subcommand)] /// View information about a room we know about + #[command(subcommand)] Info(RoomInfoCommand), - #[command(subcommand)] /// Manage moderation of remote or local rooms + #[command(subcommand)] Moderation(RoomModerationCommand), - #[command(subcommand)] /// Manage rooms' aliases + #[command(subcommand)] Alias(RoomAliasCommand), - #[command(subcommand)] /// Manage the room directory + #[command(subcommand)] Directory(RoomDirectoryCommand), + /// Interface with room graphs directly (advanced). + #[command(subcommand)] + Graph(GraphCommand), + /// Check if we know about a room Exists { room_id: OwnedRoomId,