4c8e4bf726
All tools successfully used for what I needed them for
172 lines
5.6 KiB
Rust
172 lines
5.6 KiB
Rust
use std::{path::PathBuf, process::ExitCode};
|
|
|
|
use clap::Parser;
|
|
use eyre::{bail, Context};
|
|
use matricks::{
|
|
aliases_remove, parse_alias_batch_file, parse_room_batch_file,
|
|
rooms_aliases::{self, AliasesArgs},
|
|
rooms_make_read_only, space_tree,
|
|
};
|
|
use matrix_sdk::ruma::{OwnedRoomAliasId, OwnedRoomId, OwnedRoomOrAliasId};
|
|
use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt};
|
|
|
|
#[derive(Clone, Parser)]
|
|
pub struct Options {
|
|
#[command(subcommand)]
|
|
command: TopLevelCommand,
|
|
}
|
|
|
|
#[derive(Clone, Parser)]
|
|
pub enum TopLevelCommand {
|
|
#[command(subcommand)]
|
|
Space(SpaceCommand),
|
|
|
|
Rooms {
|
|
/// Operate on one room
|
|
#[arg(long = "one")]
|
|
one: Option<OwnedRoomId>,
|
|
/// Operate on all room IDs found in the given Room Batch File.
|
|
/// See the README for documentation on what a Room Batch File looks like.
|
|
#[arg(long = "file")]
|
|
file: Option<PathBuf>,
|
|
#[command(subcommand)]
|
|
subcommand: RoomsCommand,
|
|
},
|
|
|
|
Aliases {
|
|
/// Operate on one alias
|
|
#[arg(long = "one")]
|
|
one: Option<OwnedRoomAliasId>,
|
|
/// Operate on all room aliases found in the given Alias Batch File.
|
|
/// See the README for documentation on what a Alias Batch File looks like.
|
|
#[arg(long = "file")]
|
|
file: Option<PathBuf>,
|
|
#[command(subcommand)]
|
|
subcommand: AliasesCommand,
|
|
},
|
|
}
|
|
|
|
#[derive(Clone, Parser)]
|
|
pub enum SpaceCommand {
|
|
Tree { root_space: OwnedRoomOrAliasId },
|
|
}
|
|
|
|
#[derive(Clone, Parser)]
|
|
pub enum RoomsCommand {
|
|
/// Make the room(s) read-only except to sufficiently privileged users.
|
|
///
|
|
/// This is suitable for archiving rooms that are no longer used.
|
|
MakeReadOnly {
|
|
/// The power level to set as the required threshold for sending room messages.
|
|
/// 100 (Admin) or 50 (Moderator) is usually a sensible choice.
|
|
#[arg(long = "power-level")]
|
|
power_level: u32,
|
|
},
|
|
|
|
/// Lists aliases assigned to the rooms, with some filtering options.
|
|
///
|
|
/// The output format is in Alias Batch File.
|
|
Aliases(AliasesArgs),
|
|
}
|
|
|
|
#[derive(Clone, Parser)]
|
|
pub enum AliasesCommand {
|
|
/// Remove the aliases.
|
|
Remove,
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> eyre::Result<ExitCode> {
|
|
tracing_subscriber::registry()
|
|
.with(fmt::layer().with_writer(std::io::stderr))
|
|
.with(
|
|
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
|
|
let matricks_level = std::env::var("MATRICKS_LOG").unwrap_or("info".to_owned());
|
|
format!("matricks={matricks_level},matrix_sdk_base=error,info").into()
|
|
}),
|
|
)
|
|
.init();
|
|
|
|
let options = Options::parse();
|
|
|
|
match &options.command {
|
|
TopLevelCommand::Space(space_command) => match space_command {
|
|
SpaceCommand::Tree { root_space } => {
|
|
let client = matricks::get_client_from_env()
|
|
.await
|
|
.context("could not get client from env")?;
|
|
|
|
space_tree::run(&client, root_space).await?;
|
|
}
|
|
},
|
|
TopLevelCommand::Rooms {
|
|
one,
|
|
file,
|
|
subcommand,
|
|
} => {
|
|
let room_sources_count = one.is_some() as u32 + file.is_some() as u32;
|
|
if room_sources_count != 1 {
|
|
bail!("Exactly one of --one and --file must be provided.");
|
|
}
|
|
|
|
let room_ids = if let Some(one) = one {
|
|
vec![one.clone()]
|
|
} else if let Some(file) = file {
|
|
parse_room_batch_file(file)
|
|
.await
|
|
.context("could not parse --file Room Batch File")?
|
|
} else {
|
|
// We already checked if one of the sources was provided, so we can't hit this
|
|
unreachable!();
|
|
};
|
|
|
|
match subcommand {
|
|
RoomsCommand::MakeReadOnly { power_level } => {
|
|
let client = matricks::get_client_from_env()
|
|
.await
|
|
.context("could not get client from env")?;
|
|
rooms_make_read_only::run(&client, &room_ids, *power_level).await?
|
|
}
|
|
RoomsCommand::Aliases(args) => {
|
|
let client = matricks::get_client_from_env()
|
|
.await
|
|
.context("could not get client from env")?;
|
|
rooms_aliases::run(&client, &room_ids, args).await?;
|
|
}
|
|
}
|
|
}
|
|
TopLevelCommand::Aliases {
|
|
one,
|
|
file,
|
|
subcommand,
|
|
} => {
|
|
let alias_sources_count = one.is_some() as u32 + file.is_some() as u32;
|
|
if alias_sources_count != 1 {
|
|
bail!("Exactly one of --one and --file must be provided.");
|
|
}
|
|
|
|
let room_aliases = if let Some(one) = one {
|
|
vec![one.clone()]
|
|
} else if let Some(file) = file {
|
|
parse_alias_batch_file(file)
|
|
.await
|
|
.context("could not parse --file Alias Batch File")?
|
|
} else {
|
|
// We already checked if one of the sources was provided, so we can't hit this
|
|
unreachable!();
|
|
};
|
|
|
|
match subcommand {
|
|
AliasesCommand::Remove => {
|
|
let client = matricks::get_client_from_env()
|
|
.await
|
|
.context("could not get client from env")?;
|
|
aliases_remove::run(&client, &room_aliases).await?;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(ExitCode::SUCCESS)
|
|
}
|