From fd84a57e82c9e29bd1dd15ed0fe8a91e3ce657f0 Mon Sep 17 00:00:00 2001 From: jude Date: Sat, 17 Oct 2020 15:21:00 +0100 Subject: [PATCH] improvements to todo interface, now using todos and todoc as with old versionn --- src/commands/todo_cmds.rs | 305 ++++++++++++++++++-------------------- src/main.rs | 13 +- 2 files changed, 153 insertions(+), 165 deletions(-) diff --git a/src/commands/todo_cmds.rs b/src/commands/todo_cmds.rs index ea8287d..b0847b2 100644 --- a/src/commands/todo_cmds.rs +++ b/src/commands/todo_cmds.rs @@ -19,6 +19,8 @@ use crate::{ use sqlx::MySqlPool; use std::convert::TryFrom; +use async_trait::async_trait; + #[derive(Debug)] struct TodoNotFound; @@ -232,6 +234,97 @@ DELETE FROM todos WHERE user_id = (SELECT id FROM users WHERE user = ?) AND guil Ok(()) } + + async fn execute(&self, ctx: &Context, msg: &Message, subcommand: SubCommand, extra: String) { + let pool = ctx + .data + .read() + .await + .get::() + .cloned() + .expect("Could not get SQLPool from data"); + + let user_data = UserData::from_user(&msg.author, &ctx, &pool).await.unwrap(); + let prefix = GuildData::prefix_from_id(msg.guild_id, &pool).await; + + match subcommand { + SubCommand::View => { + let todo_items = self.view(pool).await.unwrap(); + let mut todo_groups = vec!["".to_string()]; + let mut char_count = 0; + + todo_items.iter().enumerate().for_each(|(count, todo)| { + let display = format!("{}: {}\n", count + 1, todo.value); + + if char_count + display.len() > MESSAGE_CODE_LIMIT as usize { + char_count = display.len(); + + todo_groups.push(display); + } else { + char_count += display.len(); + + let last_group = todo_groups.pop().unwrap(); + + todo_groups.push(format!("{}{}", last_group, display)); + } + }); + + for group in todo_groups { + let _ = msg + .channel_id + .send_message(&ctx, |m| { + m.embed(|e| e.title(format!("{} Todo", self.name())).description(group)) + }) + .await; + } + } + + SubCommand::Add => { + let content = user_data + .response(&pool, "todo/added") + .await + .replacen("{name}", &extra, 1); + + self.add(extra, pool).await.unwrap(); + + let _ = msg.channel_id.say(&ctx, content).await; + } + + SubCommand::Remove => { + let _ = if let Ok(num) = extra.parse::() { + if let Ok(todo) = self.remove(num - 1, &pool).await { + let content = user_data.response(&pool, "todo/removed").await.replacen( + "{}", + &todo.value, + 1, + ); + + msg.channel_id.say(&ctx, content) + } else { + msg.channel_id + .say(&ctx, user_data.response(&pool, "todo/error_index").await) + } + } else { + let content = user_data + .response(&pool, "todo/error_value") + .await + .replacen("{prefix}", &prefix, 1) + .replacen("{command}", &self.command(Some(subcommand)), 1); + + msg.channel_id.say(&ctx, content) + } + .await; + } + + SubCommand::Clear => { + self.clear(&pool).await.unwrap(); + + let content = user_data.response(&pool, "todo/cleared").await; + + let _ = msg.channel_id.say(&ctx, content).await; + } + } + } } enum SubCommand { @@ -252,7 +345,7 @@ impl TryFrom> for SubCommand { Some("clear") => Ok(SubCommand::Clear), - None => Ok(SubCommand::View), + None | Some("") => Ok(SubCommand::View), Some(_unrecognised) => Err(()), } @@ -271,6 +364,22 @@ impl ToString for SubCommand { } } +#[async_trait] +trait Execute { + async fn execute(self, ctx: &Context, msg: &Message, extra: String, target: TodoTarget); +} + +#[async_trait] +impl Execute for Result { + async fn execute(self, ctx: &Context, msg: &Message, extra: String, target: TodoTarget) { + if let Ok(subcommand) = self { + target.execute(ctx, msg, subcommand, extra).await; + } else { + show_help(&ctx, msg, Some(target)).await; + } + } +} + #[command] #[permission_level(Managed)] async fn todo_user(ctx: &Context, msg: &Message, args: String) -> CommandResult { @@ -284,83 +393,51 @@ async fn todo_user(ctx: &Context, msg: &Message, args: String) -> CommandResult let subcommand_opt = SubCommand::try_from(split.next()); - if let Ok(subcommand) = subcommand_opt { - todo( - ctx, - msg, - target, - subcommand, - split.collect::>().join(" "), - ) + subcommand_opt + .execute(ctx, msg, split.collect::>().join(" "), target) .await; - } else { - show_help(&ctx, msg, Some(target)).await; - } Ok(()) } #[command] +#[supports_dm(false)] #[permission_level(Managed)] -async fn todo_parse(ctx: &Context, msg: &Message, args: String) -> CommandResult { +async fn todo_channel(ctx: &Context, msg: &Message, args: String) -> CommandResult { let mut split = args.split(' '); - if let Some(target) = split.next() { - let target_opt = match target { - "user" => Some(TodoTarget { - user: msg.author.id, - guild: None, - channel: None, - }), + let target = TodoTarget { + user: msg.author.id, + guild: msg.guild_id, + channel: Some(msg.channel_id), + }; - "channel" => { - if let Some(gid) = msg.guild_id { - Some(TodoTarget { - user: msg.author.id, - guild: Some(gid), - channel: Some(msg.channel_id), - }) - } else { - None - } - } + let subcommand_opt = SubCommand::try_from(split.next()); - "server" | "guild" => { - if let Some(gid) = msg.guild_id { - Some(TodoTarget { - user: msg.author.id, - guild: Some(gid), - channel: None, - }) - } else { - None - } - } + subcommand_opt + .execute(ctx, msg, split.collect::>().join(" "), target) + .await; - _ => None, - }; + Ok(()) +} - if let Some(target) = target_opt { - let subcommand_opt = SubCommand::try_from(split.next()); +#[command] +#[supports_dm(false)] +#[permission_level(Managed)] +async fn todo_guild(ctx: &Context, msg: &Message, args: String) -> CommandResult { + let mut split = args.split(' '); - if let Ok(subcommand) = subcommand_opt { - todo( - ctx, - msg, - target, - subcommand, - split.collect::>().join(" "), - ) - .await; - } else { - show_help(&ctx, msg, Some(target)).await; - } - } else { - show_help(&ctx, msg, None).await; - } - } else { - show_help(&ctx, msg, None).await; - } + let target = TodoTarget { + user: msg.author.id, + guild: msg.guild_id, + channel: None, + }; + + let subcommand_opt = SubCommand::try_from(split.next()); + + subcommand_opt + .execute(ctx, msg, split.collect::>().join(" "), target) + .await; Ok(()) } @@ -390,103 +467,3 @@ async fn show_help(ctx: &Context, msg: &Message, target: Option) { let _ = msg.channel_id.say(&ctx, content).await; } - -async fn todo( - ctx: &Context, - msg: &Message, - target: TodoTarget, - subcommand: SubCommand, - extra: String, -) { - let pool = ctx - .data - .read() - .await - .get::() - .cloned() - .expect("Could not get SQLPool from data"); - - let user_data = UserData::from_user(&msg.author, &ctx, &pool).await.unwrap(); - let prefix = GuildData::prefix_from_id(msg.guild_id, &pool).await; - - match subcommand { - SubCommand::View => { - let todo_items = target.view(pool).await.unwrap(); - let mut todo_groups = vec!["".to_string()]; - let mut char_count = 0; - - todo_items.iter().enumerate().for_each(|(count, todo)| { - let display = format!("{}: {}\n", count + 1, todo.value); - - if char_count + display.len() > MESSAGE_CODE_LIMIT as usize { - char_count = display.len(); - - todo_groups.push(display); - } else { - char_count += display.len(); - - let last_group = todo_groups.pop().unwrap(); - - todo_groups.push(format!("{}{}", last_group, display)); - } - }); - - for group in todo_groups { - let _ = msg - .channel_id - .send_message(&ctx, |m| { - m.embed(|e| { - e.title(format!("{} Todo", target.name())) - .description(group) - }) - }) - .await; - } - } - - SubCommand::Add => { - let content = user_data - .response(&pool, "todo/added") - .await - .replacen("{name}", &extra, 1); - - target.add(extra, pool).await.unwrap(); - - let _ = msg.channel_id.say(&ctx, content).await; - } - - SubCommand::Remove => { - let _ = if let Ok(num) = extra.parse::() { - if let Ok(todo) = target.remove(num - 1, &pool).await { - let content = user_data.response(&pool, "todo/removed").await.replacen( - "{}", - &todo.value, - 1, - ); - - msg.channel_id.say(&ctx, content) - } else { - msg.channel_id - .say(&ctx, user_data.response(&pool, "todo/error_index").await) - } - } else { - let content = user_data - .response(&pool, "todo/error_value") - .await - .replacen("{prefix}", &prefix, 1) - .replacen("{command}", &target.command(Some(subcommand)), 1); - - msg.channel_id.say(&ctx, content) - } - .await; - } - - SubCommand::Clear => { - target.clear(&pool).await.unwrap(); - - let content = user_data.response(&pool, "todo/cleared").await; - - let _ = msg.channel_id.say(&ctx, content).await; - } - } -} diff --git a/src/main.rs b/src/main.rs index 15a3148..22a2a52 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,6 +70,7 @@ async fn main() -> Result<(), Box> { let framework = RegexFramework::new(logged_in_id) .default_prefix(DEFAULT_PREFIX.clone()) .ignore_bots(env::var("IGNORE_BOTS").map_or(true, |var| var == "1")) + // info commands .add_command("ping", &info_cmds::PING_COMMAND) .add_command("help", &info_cmds::HELP_COMMAND) .add_command("info", &info_cmds::INFO_COMMAND) @@ -77,6 +78,7 @@ async fn main() -> Result<(), Box> { .add_command("donate", &info_cmds::DONATE_COMMAND) .add_command("dashboard", &info_cmds::DASHBOARD_COMMAND) .add_command("clock", &info_cmds::CLOCK_COMMAND) + // reminder commands .add_command("timer", &reminder_cmds::TIMER_COMMAND) .add_command("remind", &reminder_cmds::REMIND_COMMAND) .add_command("r", &reminder_cmds::REMIND_COMMAND) @@ -85,9 +87,18 @@ async fn main() -> Result<(), Box> { .add_command("natural", &reminder_cmds::NATURAL_COMMAND) .add_command("n", &reminder_cmds::NATURAL_COMMAND) .add_command("", &reminder_cmds::NATURAL_COMMAND) + // management commands .add_command("look", &reminder_cmds::LOOK_COMMAND) .add_command("del", &reminder_cmds::DELETE_COMMAND) - .add_command("todo", &todo_cmds::TODO_PARSE_COMMAND) + // to-do commands + .add_command("todo", &todo_cmds::TODO_USER_COMMAND) + .add_command("todo user", &todo_cmds::TODO_USER_COMMAND) + .add_command("todoc", &todo_cmds::TODO_CHANNEL_COMMAND) + .add_command("todo channel", &todo_cmds::TODO_CHANNEL_COMMAND) + .add_command("todos", &todo_cmds::TODO_GUILD_COMMAND) + .add_command("todo server", &todo_cmds::TODO_GUILD_COMMAND) + .add_command("todo guild", &todo_cmds::TODO_GUILD_COMMAND) + // moderation commands .add_command("blacklist", &moderation_cmds::BLACKLIST_COMMAND) .add_command("restrict", &moderation_cmds::RESTRICT_COMMAND) .add_command("timezone", &moderation_cmds::TIMEZONE_COMMAND)