diff --git a/Cargo.lock b/Cargo.lock index b38e730..13eceda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -588,6 +588,12 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "go-parse-duration" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558b88954871f5e5b2af0e62e2e176c8bde7a6c2c4ed41b13d138d96da2e2cbd" + [[package]] name = "h2" version = "0.3.16" @@ -1297,6 +1303,7 @@ dependencies = [ "decancer", "dirs", "dotenv", + "go-parse-duration", "hmac-sha256", "mongodb", "poise", diff --git a/Cargo.toml b/Cargo.toml index dfad295..b6a060b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,3 +34,4 @@ tracing = { version = "0.1.37", features = ["max_level_debug", "release_max_leve tracing-subscriber = "0.3.16" hmac-sha256 = "1.1.6" base64 = "0.21.0" +go-parse-duration = "0.1.1" diff --git a/src/commands/moderation.rs b/src/commands/moderation.rs index 1f9073d..165fa82 100644 --- a/src/commands/moderation.rs +++ b/src/commands/moderation.rs @@ -1,8 +1,12 @@ use bson::{doc, Document}; -use chrono::{Duration, Utc}; +use chrono::Utc; use mongodb::options::{UpdateModifications, UpdateOptions}; use poise::serenity_prelude::{ - self as serenity, Mentionable, PermissionOverwrite, Permissions, UserId, + self as serenity, + Mentionable, + PermissionOverwrite, + Permissions, + UserId, }; use tracing::{debug, error, trace}; @@ -10,8 +14,13 @@ use crate::db::model::{LockedChannel, Muted}; use crate::utils::bot::get_member; use crate::utils::macros::to_user; use crate::utils::moderation::{ - ban_moderation, queue_unmute_member, respond_moderation, BanKind, ModerationKind, + ban_moderation, + queue_unmute_member, + respond_moderation, + BanKind, + ModerationKind, }; +use crate::utils::parse_duration; use crate::{Context, Error}; /// Lock a channel. @@ -89,14 +98,11 @@ pub async fn lock(ctx: Context<'_>) -> Result<(), Error> { let permission = Permissions::SEND_MESSAGES & Permissions::ADD_REACTIONS; if let Err(err) = channel - .create_permission( - http, - &PermissionOverwrite { - allow: permission_overwrite.allow & !permission, - deny: permission_overwrite.deny | permission, - kind: permission_overwrite.kind, - }, - ) + .create_permission(http, &PermissionOverwrite { + allow: permission_overwrite.allow & !permission, + deny: permission_overwrite.deny | permission, + kind: permission_overwrite.kind, + }) .await { error!("Failed to create the new permission: {:?}", err); @@ -197,45 +203,17 @@ pub async fn unmute( } /// Mute a member. -#[allow(clippy::too_many_arguments)] #[poise::command(slash_command)] pub async fn mute( ctx: Context<'_>, #[description = "The member to mute"] member: UserId, - #[description = "Seconds"] seconds: Option, - #[description = "Minutes"] minutes: Option, - #[description = "Hours"] hours: Option, - #[description = "Days"] days: Option, - #[description = "Months"] months: Option, + #[description = "The duration of the mute"] duration: String, #[description = "The reason of the mute"] reason: String, ) -> Result<(), Error> { let user = to_user!(member, ctx); let id = user.id; let now = Utc::now(); - let mut mute_duration = Duration::zero(); - - if let Some(seconds) = seconds { - mute_duration = mute_duration - .checked_add(&Duration::seconds(seconds)) - .unwrap(); - } - if let Some(minutes) = minutes { - mute_duration = mute_duration - .checked_add(&Duration::minutes(minutes)) - .unwrap(); - } - if let Some(hours) = hours { - mute_duration = mute_duration.checked_add(&Duration::hours(hours)).unwrap(); - } - if let Some(days) = days { - mute_duration = mute_duration.checked_add(&Duration::days(days)).unwrap(); - } - if let Some(months) = months { - const DAYS_IN_MONTH: i64 = 30; - mute_duration = mute_duration - .checked_add(&Duration::days(months * DAYS_IN_MONTH)) - .unwrap(); - } + let mute_duration = parse_duration(duration).map_err(|e| Error::from(format!("{:?}", e)))?; let data = &mut *ctx.data().write().await; let configuration = &data.configuration; diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 6d1e09d..2aef1de 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,3 +1,4 @@ +use chrono::Duration; use poise::serenity_prelude::{self as serenity, Member, RoleId}; pub mod autorespond; @@ -9,3 +10,8 @@ pub mod macros; pub mod media_channel; pub mod moderation; pub mod poll; + +pub fn parse_duration(duration: String) -> Result { + let d = go_parse_duration::parse_duration(&duration)?; + Ok(Duration::nanoseconds(d)) +} diff --git a/src/utils/moderation.rs b/src/utils/moderation.rs index 4bff8f2..a8dd5b1 100644 --- a/src/utils/moderation.rs +++ b/src/utils/moderation.rs @@ -18,10 +18,10 @@ use crate::{Context, Error}; pub enum ModerationKind { Mute(User, User, String, Option, Option), /* User, Command author, Reason, Expires, Error */ Unmute(User, User, Option), // User, Command author, Error - Ban(User, User, Option, Option), // User, Command author, Reason, Error - Unban(User, User, Option), // User, Command author, Error - Lock(GuildChannel, User, Option), // Channel name, Command author, Error - Unlock(GuildChannel, User, Option), // Channel name, Command author, Error + Ban(User, User, Option, Option), // User, Command author, Reason, Error + Unban(User, User, Option), // User, Command author, Error + Lock(GuildChannel, User, Option), // Channel name, Command author, Error + Unlock(GuildChannel, User, Option), // Channel name, Command author, Error } pub enum BanKind { Ban(User, Option, Option), // User, Amount of days to delete messages, Reason @@ -399,3 +399,4 @@ pub async fn mute_moderation( Ok((is_currently_muted, removed_roles)) } +