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 {