tuwunel_admin/room/
info.rs1use clap::Subcommand;
2use futures::StreamExt;
3use ruma::OwnedRoomId;
4use tuwunel_core::{Err, Result, utils::ReadyExt};
5
6use crate::{admin_command, admin_command_dispatch};
7
8#[admin_command_dispatch]
9#[derive(Debug, Subcommand)]
10pub(crate) enum RoomInfoCommand {
11 ListJoinedMembers {
13 room_id: OwnedRoomId,
14
15 #[arg(long)]
17 local_only: bool,
18 },
19
20 ViewRoomTopic {
25 room_id: OwnedRoomId,
26 },
27}
28
29#[admin_command]
30async fn list_joined_members(&self, room_id: OwnedRoomId, local_only: bool) -> Result {
31 let room_name = self
32 .services
33 .state_accessor
34 .get_name(&room_id)
35 .await
36 .unwrap_or_else(|_| room_id.to_string());
37
38 let member_info: Vec<_> = self
39 .services
40 .state_cache
41 .room_members(&room_id)
42 .ready_filter(|user_id| {
43 local_only
44 .then(|| self.services.globals.user_is_local(user_id))
45 .unwrap_or(true)
46 })
47 .map(ToOwned::to_owned)
48 .filter_map(async |user_id| {
49 Some((
50 self.services
51 .users
52 .displayname(&user_id)
53 .await
54 .unwrap_or_else(|_| user_id.to_string()),
55 user_id,
56 ))
57 })
58 .collect()
59 .await;
60
61 let num = member_info.len();
62 let body = member_info
63 .into_iter()
64 .map(|(displayname, mxid)| format!("{mxid} | {displayname}"))
65 .collect::<Vec<_>>()
66 .join("\n");
67
68 self.write_str(&format!("{num} Members in Room \"{room_name}\":\n```\n{body}\n```"))
69 .await
70}
71
72#[admin_command]
73async fn view_room_topic(&self, room_id: OwnedRoomId) -> Result {
74 let Ok(room_topic) = self
75 .services
76 .state_accessor
77 .get_room_topic(&room_id)
78 .await
79 else {
80 return Err!("Room does not have a room topic set.");
81 };
82
83 self.write_str(&format!("Room topic:\n```\n{room_topic}\n```"))
84 .await
85}