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]]
|
||||
name = "reminder_rs"
|
||||
version = "1.4.6"
|
||||
version = "1.4.7"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"chrono",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "reminder_rs"
|
||||
version = "1.4.6"
|
||||
version = "1.4.7"
|
||||
authors = ["jellywx <judesouthworth@pm.me>"]
|
||||
edition = "2018"
|
||||
|
||||
|
@ -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<Box<RegexFramework>> = {
|
||||
let framework_trait = ctx
|
||||
.data
|
||||
.read()
|
||||
.await
|
||||
.get::<FrameworkCtx>()
|
||||
.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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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::<Vec<&str>>();
|
||||
|
||||
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 {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -367,7 +367,7 @@ impl Execute for Result<SubCommand, ()> {
|
||||
}
|
||||
}
|
||||
|
||||
#[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) {
|
||||
|
@ -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_";
|
||||
|
||||
|
@ -176,7 +176,7 @@ impl SendIterator for ChannelId {
|
||||
}
|
||||
|
||||
pub struct RegexFramework {
|
||||
commands: HashMap<String, &'static Command>,
|
||||
pub commands: HashMap<String, &'static Command>,
|
||||
command_matcher: Regex,
|
||||
dm_regex_matcher: Regex,
|
||||
default_prefix: String,
|
||||
|
@ -290,7 +290,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
data.insert::<SQLPool>(pool);
|
||||
data.insert::<PopularTimezones>(Arc::new(popular_timezones));
|
||||
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))
|
||||
}
|
||||
|
||||
|
@ -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<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 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))?;
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
Ok("".to_string())
|
||||
}? + {
|
||||
let colons = self.time_string.matches(':').count();
|
||||
|
||||
match colons {
|
||||
1 => Ok("%H:%M"),
|
||||
2 => Ok("%H:%M:%S"),
|
||||
_ => Err(InvalidTime::ParseErrorHMS),
|
||||
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<i64, InvalidTime> {
|
||||
|
Loading…
Reference in New Issue
Block a user