Implement `room tombstone` command

This commit is contained in:
Jez Cope 2021-07-21 20:10:28 +01:00
parent dc5ce6082f
commit 10313d29ab
3 changed files with 77 additions and 5 deletions

View File

@ -9,9 +9,12 @@ TODO: policy on maintenance and contributions
- [x] Login and store session info
- [ ] Log out
- [x] Show login status
- [ ] Tombstone room
- [x] Tombstone room
- [x] Add room alias
- [x] Remove room alias
- [ ] Set canonical room alias
- [ ] Optionally create alias in one command
- [ ] Remove canonical room alias
- [x] List rooms
- [ ] Filter room list in various ways (esp. Spaces!)
- [ ] Handle multiple accounts on different homeservers

View File

@ -1,6 +1,10 @@
use anyhow::{Context, Result};
use matrix_sdk::{
ruma::{api::client::r0::alias, RoomAliasId, RoomId, UserId},
ruma::{
api::client::r0::alias,
events::{room::tombstone::TombstoneEventContent, AnyStateEventContent},
RoomAliasId, RoomId, UserId,
},
Client, Session, SyncSettings,
};
use rpassword::prompt_password_stderr;
@ -108,6 +112,35 @@ pub async fn list_rooms() -> CommandResult {
Ok(())
}
pub async fn tombstone_room(old_room_id: &str, new_room_id: &str, msg: &str) -> CommandResult {
let old_room_id = RoomId::try_from(old_room_id)
.with_context(|| format!("Failed to parse '{}' as room ID", old_room_id))?;
let new_room_id = RoomId::try_from(new_room_id)
.with_context(|| format!("Failed to parse '{}' as room ID", new_room_id))?;
let client = restore_session().await?;
let mut sync_settings = SyncSettings::new();
if let Some(token) = client.sync_token().await {
sync_settings = sync_settings.token(token);
}
print!("Syncing...");
io::stderr().flush().unwrap();
client
.sync_once(sync_settings)
.await
.context("Sync failed")?;
println!(" done");
if let Some(old_room) = client.get_joined_room(&old_room_id) {
let event = TombstoneEventContent::new(msg.to_string(), new_room_id);
let content = AnyStateEventContent::RoomTombstone(event);
old_room.send_state_event(content, "").await?;
} else {
println!("Room {} not joined", old_room_id);
}
Ok(())
}
pub async fn add_alias(room_id: &str, alias: &str) -> CommandResult {
let room_id = RoomId::try_from(room_id)
.with_context(|| format!("Failed to parse '{}' as room ID", room_id))?;

View File

@ -10,7 +10,7 @@ mod commands;
mod session;
use anyhow::Result;
use clap::SubCommand;
use clap::{Arg, SubCommand};
#[tokio::main]
async fn main() -> Result<()> {
@ -22,7 +22,30 @@ async fn main() -> Result<()> {
)
.subcommand(SubCommand::with_name("logout").about("ends the current session"))
.subcommand(SubCommand::with_name("status").about("displays current session status"))
.subcommand(SubCommand::with_name("list-rooms").about("lists rooms available to the user"))
.subcommand(
SubCommand::with_name("room")
.about("room subcommands")
.subcommand(
SubCommand::with_name("list")
.alias("ls")
.about("lists rooms available to the user"),
)
.subcommand(
SubCommand::with_name("tombstone")
.about("add a tombstone redirecting one room to another")
.args_from_usage(
"<OLD_ROOM_ID> 'The ID of the source room'
<NEW_ROOM_ID> 'The ID of the target room'",
)
.arg(
Arg::with_name("MSG")
.short("m")
.long("message")
.help("The message to display in the old rom")
.default_value("This room has been replaced"),
),
),
)
.subcommand(
SubCommand::with_name("alias")
.about("alias subcommands")
@ -45,7 +68,20 @@ async fn main() -> Result<()> {
match matches.subcommand() {
("login", Some(submatches)) => commands::login(submatches.value_of("user")).await?,
("status", Some(_)) => commands::status().await?,
("list-rooms", Some(_)) => commands::list_rooms().await?,
("room", Some(room)) => match room.subcommand() {
("list", Some(_)) => commands::list_rooms().await?,
("tombstone", Some(submatches)) => {
commands::tombstone_room(
submatches.value_of("OLD_ROOM_ID").unwrap(),
submatches.value_of("NEW_ROOM_ID").unwrap(),
submatches.value_of("MSG").unwrap(),
)
.await?
}
(c, _) => {
todo!("Subcommand '{}' not implemented yet!", c);
}
},
("alias", Some(alias)) => match alias.subcommand() {
("add", Some(submatches)) => {
commands::add_alias(