diff --git a/src/bot/event_handlers.rs b/src/bot/event_handlers.rs index 11e1673..0e22433 100644 --- a/src/bot/event_handlers.rs +++ b/src/bot/event_handlers.rs @@ -1,6 +1,7 @@ use super::DiceBot; use crate::db::Database; use crate::error::BotError; +use crate::matrix; use async_trait::async_trait; use log::{debug, error, info, warn}; use matrix_sdk::{ @@ -10,8 +11,7 @@ use matrix_sdk::{ room::message::{MessageEventContent, TextMessageEventContent}, StrippedStateEvent, SyncMessageEvent, SyncStateEvent, }, - identifiers::RoomId, - Client, EventEmitter, SyncRoom, + EventEmitter, SyncRoom, }; use std::clone::Clone; use std::ops::Sub; @@ -92,19 +92,6 @@ fn should_process_event(db: &Database, room_id: &str, event_id: &str) -> bool { }) } -async fn get_users_in_room(client: &Client, room_id: &RoomId) -> Vec { - if let Some(joined_room) = client.get_joined_room(room_id).await { - let joined_room: matrix_sdk::Room = joined_room.read().await.clone(); - joined_room - .joined_members - .keys() - .map(|user_id| format!("@{}:{}", user_id.localpart(), user_id.server_name())) - .collect() - } else { - vec![] - } -} - /// This event emitter listens for messages with dice rolling commands. /// Originally adapted from the matrix-rust-sdk examples. #[async_trait] @@ -137,7 +124,7 @@ impl EventEmitter for DiceBot { self.db.rooms.clear_info(room_id) } else if event_affects_us && adding_user { info!("Joined room {}; recording user information", room_id); - let usernames = get_users_in_room(&self.client, &room.room_id).await; + let usernames = matrix::get_users_in_room(&self.client, &room.room_id).await; usernames .into_iter() .filter(|username| username != &event.state_key) diff --git a/src/commands.rs b/src/commands.rs index 8a67178..dd2c89e 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -5,6 +5,7 @@ use thiserror::Error; pub mod basic_rolling; pub mod cofd; pub mod cthulhu; +pub mod management; pub mod misc; pub mod parser; pub mod variables; diff --git a/src/commands/management.rs b/src/commands/management.rs new file mode 100644 index 0000000..8964c86 --- /dev/null +++ b/src/commands/management.rs @@ -0,0 +1,44 @@ +use super::{Command, Execution}; +use crate::context::Context; +use crate::db::errors::DataError; +use crate::matrix; +use async_trait::async_trait; +use matrix_sdk::identifiers::RoomId; +use std::convert::TryFrom; + +pub struct ResyncCommand; + +type ResyncResult = Result<(), DataError>; + +#[async_trait] +impl Command for ResyncCommand { + fn name(&self) -> &'static str { + "resync room information" + } + + async fn execute(&self, ctx: &Context<'_>) -> Execution { + let room_id = RoomId::try_from(ctx.room_id).expect("failed to decode room ID"); + let usernames = matrix::get_users_in_room(&ctx.matrix_client, &room_id).await; + + let result: ResyncResult = usernames + .into_iter() + //.filter(|username| username != &event.state_key) + .map(|username| ctx.db.rooms.add_user_to_room(&username, room_id.as_str())) + .collect(); //Make use of collect impl on Result. + + let (plain, html) = match result { + Ok(()) => { + let plain = "Room information resynced".to_string(); + let html = "

Room information resynced.

".to_string(); + (plain, html) + } + Err(e) => { + let plain = format!("Error: {}", e); + let html = format!("

Error: {}

", e); + (plain, html) + } + }; + + Execution { plain, html } + } +} diff --git a/src/commands/parser.rs b/src/commands/parser.rs index 9bd4f6a..b319c38 100644 --- a/src/commands/parser.rs +++ b/src/commands/parser.rs @@ -4,6 +4,7 @@ use crate::commands::{ basic_rolling::RollCommand, cofd::PoolRollCommand, cthulhu::{CthAdvanceRoll, CthRoll}, + management::ResyncCommand, misc::HelpCommand, variables::{ DeleteVariableCommand, GetAllVariablesCommand, GetVariableCommand, SetVariableCommand, @@ -78,6 +79,10 @@ fn get_all_variables() -> Result, BotError> { Ok(Box::new(GetAllVariablesCommand)) } +fn parse_resync() -> Result, BotError> { + Ok(Box::new(ResyncCommand)) +} + fn help(topic: &str) -> Result, BotError> { let topic = parse_help_topic(topic); Ok(Box::new(HelpCommand(topic))) @@ -124,6 +129,7 @@ pub fn parse_command(input: &str) -> Result, BotError> { "get" => parse_get_variable_command(&cmd_input), "set" => parse_set_variable_command(&cmd_input), "del" => parse_delete_variable_command(&cmd_input), + "resync" => parse_resync(), "r" | "roll" => parse_roll(&cmd_input), "rp" | "pool" => parse_pool_roll(&cmd_input), "cthroll" | "cthRoll" => parse_cth_roll(&cmd_input), diff --git a/src/lib.rs b/src/lib.rs index 50ed009..8340421 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ pub mod db; pub mod dice; pub mod error; mod help; +pub mod matrix; pub mod models; mod parser; pub mod state; diff --git a/src/matrix.rs b/src/matrix.rs new file mode 100644 index 0000000..497f0aa --- /dev/null +++ b/src/matrix.rs @@ -0,0 +1,15 @@ +use matrix_sdk::{identifiers::RoomId, Client, Room}; + +/// Retrieve a list of users in a given room. +pub async fn get_users_in_room(client: &Client, room_id: &RoomId) -> Vec { + if let Some(joined_room) = client.get_joined_room(room_id).await { + let joined_room: Room = joined_room.read().await.clone(); + joined_room + .joined_members + .keys() + .map(|user_id| format!("@{}:{}", user_id.localpart(), user_id.server_name())) + .collect() + } else { + vec![] + } +}