From 7b6464d5a4e995d79a6ec9340b6d0342bb7f2391 Mon Sep 17 00:00:00 2001 From: jude Date: Tue, 23 Feb 2021 13:45:25 +0000 Subject: [PATCH] help command now no longer relies on help_strings const timeparser updated to work with partially specified times --- .idea/.gitignore | 8 ---- .idea/dictionaries/jude.xml | 11 ----- .idea/misc.xml | 6 --- .idea/sqldialects.xml | 7 --- Cargo.lock | 2 +- Cargo.toml | 4 +- src/commands/info_cmds.rs | 28 ++++++++---- src/commands/moderation_cmds.rs | 4 +- src/commands/reminder_cmds.rs | 13 +++++- src/commands/todo_cmds.rs | 4 +- src/consts.rs | 25 ----------- src/framework.rs | 2 +- src/main.rs | 2 +- src/time_parser.rs | 76 ++++++++++++++++++++++----------- 14 files changed, 92 insertions(+), 100 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/dictionaries/jude.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/sqldialects.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 73f69e0..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/dictionaries/jude.xml b/.idea/dictionaries/jude.xml deleted file mode 100644 index eada3dc..0000000 --- a/.idea/dictionaries/jude.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - reqwest - subcommand - todos - webhook - webhooks - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 28a804d..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml deleted file mode 100644 index ea20568..0000000 --- a/.idea/sqldialects.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 1eb37ce..8906ffb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1303,7 +1303,7 @@ dependencies = [ [[package]] name = "reminder_rs" -version = "1.4.6" +version = "1.4.7" dependencies = [ "Inflector", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 9c4f13e..2867df8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "reminder_rs" -version = "1.4.6" +version = "1.4.7" authors = ["jellywx "] edition = "2018" @@ -25,4 +25,4 @@ serenity = { version = "0.10", features = ["collector"] } sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "macros", "mysql", "bigdecimal", "chrono"]} [dependencies.regex_command_attr] -path = "./regex_command_attr" +path = "./regex_command_attr" \ No newline at end of file diff --git a/src/commands/info_cmds.rs b/src/commands/info_cmds.rs index c598bb1..39120c1 100644 --- a/src/commands/info_cmds.rs +++ b/src/commands/info_cmds.rs @@ -6,14 +6,16 @@ use chrono::offset::Utc; use crate::{ command_help, - consts::{DEFAULT_PREFIX, HELP_STRINGS}, + consts::DEFAULT_PREFIX, get_ctx_data, language_manager::LanguageManager, models::{GuildData, UserData}, - THEME_COLOR, + FrameworkCtx, THEME_COLOR, }; +use crate::framework::RegexFramework; use serenity::builder::CreateEmbedFooter; +use std::mem; use std::sync::Arc; use std::time::{SystemTime, UNIX_EPOCH}; @@ -110,14 +112,24 @@ async fn help(ctx: &Context, msg: &Message, args: String) { let prefix = GuildData::prefix_from_id(msg.guild_id, &pool); if !args.is_empty() { - let matched = HELP_STRINGS - .iter() - .filter(|h| h.split_at(5).1 == args) - .next(); + let framework: Arc> = { + let framework_trait = ctx + .data + .read() + .await + .get::() + .cloned() + .expect("Could not get FrameworkCtx from data"); - if let Some(help_str) = matched { - let command_name = help_str.split_at(5).1; + unsafe { mem::transmute(framework_trait.clone()) } + }; + let matched = framework + .commands + .get(args.as_str()) + .map(|inner| inner.name); + + if let Some(command_name) = matched { command_help(ctx, msg, lm, &prefix.await, &language.await, command_name).await } else { default_help(ctx, msg, lm, &prefix.await, &language.await).await; diff --git a/src/commands/moderation_cmds.rs b/src/commands/moderation_cmds.rs index 3b9a85a..f0a1660 100644 --- a/src/commands/moderation_cmds.rs +++ b/src/commands/moderation_cmds.rs @@ -215,7 +215,7 @@ async fn timezone(ctx: &Context, msg: &Message, args: String) { } } -#[command] +#[command("meridian")] async fn change_meridian(ctx: &Context, msg: &Message, args: String) { let (pool, lm) = get_ctx_data(&ctx).await; @@ -258,7 +258,7 @@ async fn change_meridian(ctx: &Context, msg: &Message, args: String) { } } -#[command] +#[command("lang")] async fn language(ctx: &Context, msg: &Message, args: String) { let (pool, lm) = get_ctx_data(&ctx).await; diff --git a/src/commands/reminder_cmds.rs b/src/commands/reminder_cmds.rs index 81ab355..1e4fc8b 100644 --- a/src/commands/reminder_cmds.rs +++ b/src/commands/reminder_cmds.rs @@ -982,14 +982,23 @@ impl Content { #[command("countdown")] #[permission_level(Managed)] async fn countdown(ctx: &Context, msg: &Message, args: String) { - if !check_subscription_on_message(&ctx, &msg).await { - } else { + if check_subscription_on_message(&ctx, &msg).await { let (pool, lm) = get_ctx_data(&ctx).await; + let timezone = UserData::timezone_of(&msg.author, &pool).await; + let split_args = args.splitn(3, ' ').collect::>(); if split_args.len() == 3 { + let time = split_args.get(0).unwrap(); + let interval = split_args.get(1).unwrap(); + let event_name = split_args.get(2).unwrap(); + + let time_parser = TimeParser::new(*time, &timezone); + + if let Ok(target_ts) = time_parser.timestamp() {} } else { } + } else { } } */ diff --git a/src/commands/todo_cmds.rs b/src/commands/todo_cmds.rs index 6686cd8..a454ea0 100644 --- a/src/commands/todo_cmds.rs +++ b/src/commands/todo_cmds.rs @@ -367,7 +367,7 @@ impl Execute for Result { } } -#[command] +#[command("todo")] async fn todo_user(ctx: &Context, msg: &Message, args: String) { let mut split = args.split(' '); @@ -384,7 +384,7 @@ async fn todo_user(ctx: &Context, msg: &Message, args: String) { .await; } -#[command("todos")] +#[command("todoc")] #[supports_dm(false)] #[permission_level(Managed)] async fn todo_channel(ctx: &Context, msg: &Message, args: String) { diff --git a/src/consts.rs b/src/consts.rs index daa0415..dcd75c8 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -1,31 +1,6 @@ pub const DAY: u64 = 86_400; pub const HOUR: u64 = 3_600; pub const MINUTE: u64 = 60; -pub const HELP_STRINGS: [&'static str; 23] = [ - "help/lang", - "help/meridian", - "help/timezone", - "help/prefix", - "help/blacklist", - "help/restrict", - "help/alias", - "help/remind", - "help/interval", - "help/natural", - "help/look", - "help/del", - "help/offset", - "help/pause", - "help/nudge", - "help/info", - "help/help", - "help/donate", - "help/clock", - "help/todo", - "help/todos", - "help/todoc", - "help/timer", -]; pub const CHARACTERS: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; diff --git a/src/framework.rs b/src/framework.rs index 6172170..3e92d55 100644 --- a/src/framework.rs +++ b/src/framework.rs @@ -176,7 +176,7 @@ impl SendIterator for ChannelId { } pub struct RegexFramework { - commands: HashMap, + pub commands: HashMap, command_matcher: Regex, dm_regex_matcher: Regex, default_prefix: String, diff --git a/src/main.rs b/src/main.rs index 402a45b..6b307cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -290,7 +290,7 @@ async fn main() -> Result<(), Box> { data.insert::(pool); data.insert::(Arc::new(popular_timezones)); data.insert::(Arc::new(reqwest::Client::new())); - data.insert::(framework_arc); + data.insert::(framework_arc.clone()); data.insert::(Arc::new(language_manager)) } diff --git a/src/time_parser.rs b/src/time_parser.rs index ef8b110..821022c 100644 --- a/src/time_parser.rs +++ b/src/time_parser.rs @@ -4,7 +4,7 @@ use std::fmt::{Display, Formatter, Result as FmtResult}; use crate::consts::{LOCAL_TIMEZONE, PYTHON_LOCATION}; -use chrono::TimeZone; +use chrono::{DateTime, Datelike, Timelike, Utc}; use chrono_tz::Tz; use std::convert::TryFrom; use std::str::from_utf8; @@ -95,35 +95,63 @@ impl TimeParser { } fn process_explicit(&self) -> Result { - let segments = self.time_string.matches('-').count(); + let mut time = Utc::now() + .with_timezone(&self.timezone) + .with_second(0) + .unwrap(); - let parse_string = if segments == 1 { - let slashes = self.time_string.matches('/').count(); + let mut segments = self.time_string.rsplit('-'); + // this segment will always exist even if split fails + let hms = segments.next().unwrap(); - match slashes { - 0 => Ok("%d-".to_string()), - 1 => Ok("%d/%m-".to_string()), - 2 => Ok("%d/%m/%Y-".to_string()), - _ => Err(InvalidTime::ParseErrorDMY), + let h_m_s = hms.split(':'); + + for (t, setter) in h_m_s.take(3).zip(&[ + DateTime::with_hour, + DateTime::with_minute, + DateTime::with_second, + ]) { + time = setter(&time, t.parse().map_err(|_| InvalidTime::ParseErrorHMS)?) + .map_or_else(|| Err(InvalidTime::ParseErrorHMS), |inner| Ok(inner))?; + } + + if let Some(dmy) = segments.next() { + let mut d_m_y = dmy.split('/'); + + let day = d_m_y.next(); + let month = d_m_y.next(); + let year = d_m_y.next(); + + for (t, setter) in [day, month] + .iter() + .zip(&[DateTime::with_day, DateTime::with_month]) + { + if let Some(t) = t { + time = setter(&time, t.parse().map_err(|_| InvalidTime::ParseErrorDMY)?) + .map_or_else(|| Err(InvalidTime::ParseErrorDMY), |inner| Ok(inner))?; + } } - } else { - Ok("".to_string()) - }? + { - let colons = self.time_string.matches(':').count(); - match colons { - 1 => Ok("%H:%M"), - 2 => Ok("%H:%M:%S"), - _ => Err(InvalidTime::ParseErrorHMS), + if let Some(year) = year { + if year.len() == 4 { + time = time + .with_year(year.parse().map_err(|_| InvalidTime::ParseErrorDMY)?) + .map_or_else(|| Err(InvalidTime::ParseErrorDMY), |inner| Ok(inner))?; + } else if year.len() == 2 { + time = time + .with_year( + format!("20{}", year) + .parse() + .map_err(|_| InvalidTime::ParseErrorDMY)?, + ) + .map_or_else(|| Err(InvalidTime::ParseErrorDMY), |inner| Ok(inner))?; + } else { + Err(InvalidTime::ParseErrorDMY)?; + } } - }?; + } - let dt = self - .timezone - .datetime_from_str(self.time_string.as_str(), &parse_string) - .map_err(|_| InvalidTime::ParseErrorChrono)?; - - Ok(dt.timestamp() as i64) + Ok(time.timestamp() as i64) } fn process_displacement(&self) -> Result {