help command now no longer relies on help_strings const
timeparser updated to work with partially specified times
This commit is contained in:
parent
3075e34fe1
commit
7b6464d5a4
8
.idea/.gitignore
vendored
8
.idea/.gitignore
vendored
@ -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/
|
|
@ -1,11 +0,0 @@
|
|||||||
<component name="ProjectDictionaryState">
|
|
||||||
<dictionary name="jude">
|
|
||||||
<words>
|
|
||||||
<w>reqwest</w>
|
|
||||||
<w>subcommand</w>
|
|
||||||
<w>todos</w>
|
|
||||||
<w>webhook</w>
|
|
||||||
<w>webhooks</w>
|
|
||||||
</words>
|
|
||||||
</dictionary>
|
|
||||||
</component>
|
|
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="JavaScriptSettings">
|
|
||||||
<option name="languageLevel" value="ES6" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="SqlDialectMappings">
|
|
||||||
<file url="file://$PROJECT_DIR$/create.sql" dialect="GenericSQL" />
|
|
||||||
<file url="PROJECT" dialect="MySQL" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1303,7 +1303,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reminder_rs"
|
name = "reminder_rs"
|
||||||
version = "1.4.6"
|
version = "1.4.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "reminder_rs"
|
name = "reminder_rs"
|
||||||
version = "1.4.6"
|
version = "1.4.7"
|
||||||
authors = ["jellywx <judesouthworth@pm.me>"]
|
authors = ["jellywx <judesouthworth@pm.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
@ -6,14 +6,16 @@ use chrono::offset::Utc;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
command_help,
|
command_help,
|
||||||
consts::{DEFAULT_PREFIX, HELP_STRINGS},
|
consts::DEFAULT_PREFIX,
|
||||||
get_ctx_data,
|
get_ctx_data,
|
||||||
language_manager::LanguageManager,
|
language_manager::LanguageManager,
|
||||||
models::{GuildData, UserData},
|
models::{GuildData, UserData},
|
||||||
THEME_COLOR,
|
FrameworkCtx, THEME_COLOR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::framework::RegexFramework;
|
||||||
use serenity::builder::CreateEmbedFooter;
|
use serenity::builder::CreateEmbedFooter;
|
||||||
|
use std::mem;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
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);
|
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool);
|
||||||
|
|
||||||
if !args.is_empty() {
|
if !args.is_empty() {
|
||||||
let matched = HELP_STRINGS
|
let framework: Arc<Box<RegexFramework>> = {
|
||||||
.iter()
|
let framework_trait = ctx
|
||||||
.filter(|h| h.split_at(5).1 == args)
|
.data
|
||||||
.next();
|
.read()
|
||||||
|
.await
|
||||||
|
.get::<FrameworkCtx>()
|
||||||
|
.cloned()
|
||||||
|
.expect("Could not get FrameworkCtx from data");
|
||||||
|
|
||||||
if let Some(help_str) = matched {
|
unsafe { mem::transmute(framework_trait.clone()) }
|
||||||
let command_name = help_str.split_at(5).1;
|
};
|
||||||
|
|
||||||
|
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
|
command_help(ctx, msg, lm, &prefix.await, &language.await, command_name).await
|
||||||
} else {
|
} else {
|
||||||
default_help(ctx, msg, lm, &prefix.await, &language.await).await;
|
default_help(ctx, msg, lm, &prefix.await, &language.await).await;
|
||||||
|
@ -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) {
|
async fn change_meridian(ctx: &Context, msg: &Message, args: String) {
|
||||||
let (pool, lm) = get_ctx_data(&ctx).await;
|
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) {
|
async fn language(ctx: &Context, msg: &Message, args: String) {
|
||||||
let (pool, lm) = get_ctx_data(&ctx).await;
|
let (pool, lm) = get_ctx_data(&ctx).await;
|
||||||
|
|
||||||
|
@ -982,14 +982,23 @@ impl Content {
|
|||||||
#[command("countdown")]
|
#[command("countdown")]
|
||||||
#[permission_level(Managed)]
|
#[permission_level(Managed)]
|
||||||
async fn countdown(ctx: &Context, msg: &Message, args: String) {
|
async fn countdown(ctx: &Context, msg: &Message, args: String) {
|
||||||
if !check_subscription_on_message(&ctx, &msg).await {
|
if check_subscription_on_message(&ctx, &msg).await {
|
||||||
} else {
|
|
||||||
let (pool, lm) = get_ctx_data(&ctx).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::<Vec<&str>>();
|
let split_args = args.splitn(3, ' ').collect::<Vec<&str>>();
|
||||||
|
|
||||||
if split_args.len() == 3 {
|
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 {
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -367,7 +367,7 @@ impl Execute for Result<SubCommand, ()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
#[command("todo")]
|
||||||
async fn todo_user(ctx: &Context, msg: &Message, args: String) {
|
async fn todo_user(ctx: &Context, msg: &Message, args: String) {
|
||||||
let mut split = args.split(' ');
|
let mut split = args.split(' ');
|
||||||
|
|
||||||
@ -384,7 +384,7 @@ async fn todo_user(ctx: &Context, msg: &Message, args: String) {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[command("todos")]
|
#[command("todoc")]
|
||||||
#[supports_dm(false)]
|
#[supports_dm(false)]
|
||||||
#[permission_level(Managed)]
|
#[permission_level(Managed)]
|
||||||
async fn todo_channel(ctx: &Context, msg: &Message, args: String) {
|
async fn todo_channel(ctx: &Context, msg: &Message, args: String) {
|
||||||
|
@ -1,31 +1,6 @@
|
|||||||
pub const DAY: u64 = 86_400;
|
pub const DAY: u64 = 86_400;
|
||||||
pub const HOUR: u64 = 3_600;
|
pub const HOUR: u64 = 3_600;
|
||||||
pub const MINUTE: u64 = 60;
|
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_";
|
pub const CHARACTERS: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ impl SendIterator for ChannelId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct RegexFramework {
|
pub struct RegexFramework {
|
||||||
commands: HashMap<String, &'static Command>,
|
pub commands: HashMap<String, &'static Command>,
|
||||||
command_matcher: Regex,
|
command_matcher: Regex,
|
||||||
dm_regex_matcher: Regex,
|
dm_regex_matcher: Regex,
|
||||||
default_prefix: String,
|
default_prefix: String,
|
||||||
|
@ -290,7 +290,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|||||||
data.insert::<SQLPool>(pool);
|
data.insert::<SQLPool>(pool);
|
||||||
data.insert::<PopularTimezones>(Arc::new(popular_timezones));
|
data.insert::<PopularTimezones>(Arc::new(popular_timezones));
|
||||||
data.insert::<ReqwestClient>(Arc::new(reqwest::Client::new()));
|
data.insert::<ReqwestClient>(Arc::new(reqwest::Client::new()));
|
||||||
data.insert::<FrameworkCtx>(framework_arc);
|
data.insert::<FrameworkCtx>(framework_arc.clone());
|
||||||
data.insert::<LanguageManager>(Arc::new(language_manager))
|
data.insert::<LanguageManager>(Arc::new(language_manager))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ use std::fmt::{Display, Formatter, Result as FmtResult};
|
|||||||
|
|
||||||
use crate::consts::{LOCAL_TIMEZONE, PYTHON_LOCATION};
|
use crate::consts::{LOCAL_TIMEZONE, PYTHON_LOCATION};
|
||||||
|
|
||||||
use chrono::TimeZone;
|
use chrono::{DateTime, Datelike, Timelike, Utc};
|
||||||
use chrono_tz::Tz;
|
use chrono_tz::Tz;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
@ -95,35 +95,63 @@ impl TimeParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn process_explicit(&self) -> Result<i64, InvalidTime> {
|
fn process_explicit(&self) -> Result<i64, InvalidTime> {
|
||||||
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 mut segments = self.time_string.rsplit('-');
|
||||||
let slashes = self.time_string.matches('/').count();
|
// this segment will always exist even if split fails
|
||||||
|
let hms = segments.next().unwrap();
|
||||||
|
|
||||||
match slashes {
|
let h_m_s = hms.split(':');
|
||||||
0 => Ok("%d-".to_string()),
|
|
||||||
1 => Ok("%d/%m-".to_string()),
|
for (t, setter) in h_m_s.take(3).zip(&[
|
||||||
2 => Ok("%d/%m/%Y-".to_string()),
|
DateTime::with_hour,
|
||||||
_ => Err(InvalidTime::ParseErrorDMY),
|
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))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
} else {
|
||||||
Ok("".to_string())
|
Err(InvalidTime::ParseErrorDMY)?;
|
||||||
}? + {
|
}
|
||||||
let colons = self.time_string.matches(':').count();
|
}
|
||||||
|
|
||||||
match colons {
|
|
||||||
1 => Ok("%H:%M"),
|
|
||||||
2 => Ok("%H:%M:%S"),
|
|
||||||
_ => Err(InvalidTime::ParseErrorHMS),
|
|
||||||
}
|
}
|
||||||
}?;
|
|
||||||
|
|
||||||
let dt = self
|
Ok(time.timestamp() as i64)
|
||||||
.timezone
|
|
||||||
.datetime_from_str(self.time_string.as_str(), &parse_string)
|
|
||||||
.map_err(|_| InvalidTime::ParseErrorChrono)?;
|
|
||||||
|
|
||||||
Ok(dt.timestamp() as i64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_displacement(&self) -> Result<i64, InvalidTime> {
|
fn process_displacement(&self) -> Result<i64, InvalidTime> {
|
||||||
|
Loading…
Reference in New Issue
Block a user