use std::fmt::Write; use clap::Subcommand; use conduit::Result; use ruma::{events::room::message::RoomMessageEventContent, OwnedRoomId, RoomId}; use crate::{escape_html, get_room_info, Command, PAGE_SIZE}; #[derive(Debug, Subcommand)] pub(crate) enum RoomDirectoryCommand { /// - Publish a room to the room directory Publish { /// The room id of the room to publish room_id: Box, }, /// - Unpublish a room to the room directory Unpublish { /// The room id of the room to unpublish room_id: Box, }, /// - List rooms that are published List { page: Option, }, } pub(super) async fn process(command: RoomDirectoryCommand, context: &Command<'_>) -> Result { let services = context.services; match command { RoomDirectoryCommand::Publish { room_id, } => match services.rooms.directory.set_public(&room_id) { Ok(()) => Ok(RoomMessageEventContent::text_plain("Room published")), Err(err) => Ok(RoomMessageEventContent::text_plain(format!("Unable to update room: {err}"))), }, RoomDirectoryCommand::Unpublish { room_id, } => match services.rooms.directory.set_not_public(&room_id) { Ok(()) => Ok(RoomMessageEventContent::text_plain("Room unpublished")), Err(err) => Ok(RoomMessageEventContent::text_plain(format!("Unable to update room: {err}"))), }, RoomDirectoryCommand::List { page, } => { // TODO: i know there's a way to do this with clap, but i can't seem to find it let page = page.unwrap_or(1); let mut rooms = services .rooms .directory .public_rooms() .filter_map(Result::ok) .map(|id: OwnedRoomId| get_room_info(services, &id)) .collect::>(); rooms.sort_by_key(|r| r.1); rooms.reverse(); let rooms = rooms .into_iter() .skip(page.saturating_sub(1).saturating_mul(PAGE_SIZE)) .take(PAGE_SIZE) .collect::>(); if rooms.is_empty() { return Ok(RoomMessageEventContent::text_plain("No more rooms.")); }; let output_plain = format!( "Rooms:\n{}", rooms .iter() .map(|(id, members, name)| format!("{id}\tMembers: {members}\tName: {name}")) .collect::>() .join("\n") ); let output_html = format!( "\n\t\t\n{}
Room directory - page \ {page}
idmembersname
", rooms .iter() .fold(String::new(), |mut output, (id, members, name)| { writeln!( output, "{}\t{}\t{}", escape_html(id.as_ref()), members, escape_html(name.as_ref()) ) .expect("should be able to write to string buffer"); output }) ); Ok(RoomMessageEventContent::text_html(output_plain, output_html)) }, } }