diff --git a/Cargo.toml b/Cargo.toml index 5ea800c..7880461 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ built = { version = "0.6.0", features = ["git2", "chrono"] } [dependencies] built = { version = "0.6.0", features = ["git2", "chrono"] } chrono = "0.4.26" +chrono-tz = "0.8.3" clap = "4.3.4" config = { version = "0.13.1", features = [ "yaml" ] } d20 = "0.1.0" diff --git a/src/commands/admin.rs b/src/commands/admin.rs new file mode 100644 index 0000000..ed4f9c3 --- /dev/null +++ b/src/commands/admin.rs @@ -0,0 +1,54 @@ +use poise::serenity_prelude::Activity; +use crate::{ManifoldContext, ManifoldData, ManifoldResult}; +use crate::error::ManifoldError; + +#[poise::command(slash_command, prefix_command, owners_only)] +async fn dump_config(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { + let config = &ctx.data().bot_config; + + ctx.say(format!("Config dump; {:?}", config.config)).await?; + + Ok(()) +} + +#[poise::command(slash_command, prefix_command, owners_only)] +async fn get_environment(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { + let environment = ctx.data().bot_config.get_environment(); + + ctx.say(format!("Currently running under the {} environment", environment)).await?; + + Ok(()) +} + +#[poise::command(slash_command, prefix_command, owners_only)] +async fn get_config(ctx: ManifoldContext<'_>, #[description="Config key"] key: String) -> ManifoldResult<()> { + let config = &ctx.data().bot_config; + + let value = match config.get_value(&key) { + Ok(v) => v.clone(), + Err(_) => "not found, sorry!".to_string() + }; + + ctx.say(format!("Value for key {} was {}", &key, &value)).await?; + + Ok(()) +} + +#[poise::command(slash_command, prefix_command, owners_only)] +async fn register_commands(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { + poise::builtins::register_application_commands_buttons(ctx).await?; + + Ok(()) +} + +#[poise::command(slash_command, prefix_command, track_edits, aliases("sa"), required_permissions = "MODERATE_MEMBERS")] +async fn set_activity(ctx: ManifoldContext<'_>, #[rest] #[description="Who to watch"] target: String) -> ManifoldResult<()> { + ctx.serenity_context().set_activity(Activity::watching(&target)).await; + + ctx.say(format!("Okay, I'll start watching {}", target)).await?; + Ok(()) +} + +pub fn commands() -> [poise::Command; 5] { + [dump_config(), get_environment(), get_config(), register_commands(), set_activity()] +} diff --git a/src/commands/core.rs b/src/commands/core.rs index 4d0c7bc..b3d1e47 100644 --- a/src/commands/core.rs +++ b/src/commands/core.rs @@ -1,8 +1,9 @@ use poise::serenity_prelude::*; use crate::{ManifoldContext, ManifoldData}; -use crate::built_info; +use chrono_tz::Tz; use crate::error::{ManifoldError, ManifoldResult}; +use crate::models::user::UserInfo; #[poise::command(prefix_command, track_edits, slash_command)] async fn help( @@ -34,21 +35,6 @@ async fn ping(ctx: ManifoldContext<'_>,) -> ManifoldResult<()> { Ok(()) } -#[poise::command(slash_command, prefix_command, owners_only)] -async fn register_commands(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { - poise::builtins::register_application_commands_buttons(ctx).await?; - - Ok(()) -} - -#[poise::command(slash_command, prefix_command, track_edits, aliases("sa"), required_permissions = "MODERATE_MEMBERS")] -async fn set_activity(ctx: ManifoldContext<'_>, #[rest] #[description="Who to watch"] target: String) -> ManifoldResult<()> { - ctx.serenity_context().set_activity(Activity::watching(&target)).await; - - ctx.say(format!("Okay, I'll start watching {}", target)).await?; - Ok(()) -} - #[poise::command(slash_command, prefix_command)] async fn version(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { let version_string = &ctx.data().version_string; @@ -60,38 +46,38 @@ async fn version(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { Ok(()) } -#[poise::command(slash_command, prefix_command, owners_only)] -async fn get_config(ctx: ManifoldContext<'_>, #[description="Config key"] key: String) -> ManifoldResult<()> { - let config = &ctx.data().bot_config; +#[poise::command(slash_command, prefix_command, aliases("st"))] +async fn set_timezone(ctx: ManifoldContext<'_>, input_timezone: String) -> ManifoldResult<()> { + let mut userinfo = ctx.data().user_info.lock().await; - let value = match config.get_value(&key) { - Ok(v) => v.clone(), - Err(_) => "not found, sorry!".to_string() + let validated_timezone: Tz = match input_timezone.parse() { + Ok(r) => r, + Err(e) => { + error!("Problem parsing timezone input: {:?}", e); + ctx.send(|f| f.content(format!("Are you having a laugh? What kind of timezone is that? {:?}", e)).reply(true)).await?; + Err(e)? + } }; - ctx.say(format!("Value for key {} was {}", &key, &value)).await?; + if let Some(user) = userinfo.get_mut(ctx.author().id.as_u64()) { + user.timezone = Some(validated_timezone.to_string()); + ctx.send(|f| f.content(format!("I have set your timezone to {}, but we all know that UTC is the One True Timezone.", validated_timezone.to_string())).reply(true)).await?; + } else { + let new_user = UserInfo { + user_id: ctx.author().id.as_u64().to_owned() as i64, + username: ctx.author().name.to_owned(), + weather_location: None, + weather_units: None, + timezone: Some(validated_timezone.to_string()), + last_seen: Some(chrono::Utc::now().timestamp()) + }; + userinfo.insert(ctx.author().id.as_u64().clone(), new_user); + ctx.send(|f| f.content(format!("I have set your timezone to {}, but we all know that UTC is the One True Timezone.", validated_timezone.to_string())).reply(true)).await?; + } Ok(()) } -#[poise::command(slash_command, prefix_command, owners_only)] -async fn dump_config(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { - let config = &ctx.data().bot_config; - - ctx.say(format!("Config dump; {:?}", config.config)).await?; - - Ok(()) -} - -#[poise::command(slash_command, prefix_command, owners_only)] -async fn get_environment(ctx: ManifoldContext<'_>) -> ManifoldResult<()> { - let environment = ctx.data().bot_config.get_environment(); - - ctx.say(format!("Currently running under the {} environment", environment)).await?; - - Ok(()) -} - -pub fn commands() -> [poise::Command; 8] { - [help(), ping(), register_commands(), set_activity(), version(), get_config(), dump_config(), get_environment()] +pub fn commands() -> [poise::Command; 4] { + [help(), ping(), version(), set_timezone()] } diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 9485790..9a28727 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,3 +1,4 @@ +mod admin; mod core; mod weather; @@ -5,6 +6,7 @@ use crate::ManifoldCommand; pub fn collect_commands(injected: Vec) -> Vec { core::commands().into_iter() + .chain(admin::commands()) .chain(weather::commands()) .chain(injected) .collect() diff --git a/src/events.rs b/src/events.rs index a721179..194416b 100644 --- a/src/events.rs +++ b/src/events.rs @@ -1,19 +1,15 @@ use std::sync::atomic::AtomicBool; use poise::{Event, FrameworkContext}; -use poise::futures_util::future::ok; -use poise::serenity_prelude::async_trait; use poise::serenity_prelude::model::{ gateway::Ready, id::ChannelId, }; -use poise::serenity_prelude::{Context, EventHandler, Message}; -use crate::{ManifoldConfig, ManifoldContext, ManifoldData, ManifoldDataInner}; +use poise::serenity_prelude::{Context, Message}; +use crate::ManifoldData; use crate::error::{ManifoldError, ManifoldResult}; use crate::models::user::UserInfo; -use crate::responses::Responses; - pub struct Handler { pub timer_running: AtomicBool, }