wip bump versions

This commit is contained in:
jude 2023-12-22 19:11:39 +00:00
parent e7803b98e8
commit cce0de7c75
9 changed files with 850 additions and 535 deletions

1059
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -7,12 +7,12 @@ license = "AGPL-3.0 only"
description = "Reminder Bot for Discord, now in Rust" description = "Reminder Bot for Discord, now in Rust"
[dependencies] [dependencies]
poise = "0.5" poise = "0.6.1-rc1"
dotenv = "0.15" dotenv = "0.15"
tokio = { version = "1", features = ["process", "full"] } tokio = { version = "1", features = ["process", "full"] }
reqwest = "0.11" reqwest = "0.11"
lazy-regex = "3.0.2" lazy-regex = "3.1"
regex = "1.9" regex = "1.10"
log = "0.4" log = "0.4"
env_logger = "0.10" env_logger = "0.10"
chrono = "0.4" chrono = "0.4"

View File

@ -405,7 +405,6 @@ WHERE
if fail_count >= 4 { if fail_count >= 4 {
self.log_error( self.log_error(
pool,
"Failed to update 4 times and so is being deleted", "Failed to update 4 times and so is being deleted",
None::<&'static str>, None::<&'static str>,
) )
@ -428,12 +427,7 @@ WHERE
} }
} }
async fn log_error( async fn log_error(&self, error: &'static str, debug_info: Option<impl std::fmt::Debug>) {
&self,
pool: impl Executor<'_, Database = Database> + Copy,
error: &'static str,
debug_info: Option<impl std::fmt::Debug>,
) {
let message = match debug_info { let message = match debug_info {
Some(info) => format!( Some(info) => format!(
"{} "{}
@ -447,7 +441,7 @@ WHERE
error!("[Reminder {}] {}", self.id, message); error!("[Reminder {}] {}", self.id, message);
} }
async fn log_success(&self, pool: impl Executor<'_, Database = Database> + Copy) {} async fn log_success(&self) {}
async fn set_sent(&self, pool: impl Executor<'_, Database = Database> + Copy) { async fn set_sent(&self, pool: impl Executor<'_, Database = Database> + Copy) {
sqlx::query!("UPDATE reminders SET `status` = 'sent' WHERE `id` = ?", self.id) sqlx::query!("UPDATE reminders SET `status` = 'sent' WHERE `id` = ?", self.id)
@ -640,7 +634,6 @@ WHERE
match http_error.error.code { match http_error.error.code {
10003 => { 10003 => {
self.log_error( self.log_error(
pool,
"Could not be sent as channel does not exist", "Could not be sent as channel does not exist",
None::<&'static str>, None::<&'static str>,
) )
@ -653,7 +646,6 @@ WHERE
} }
10004 => { 10004 => {
self.log_error( self.log_error(
pool,
"Could not be sent as guild does not exist", "Could not be sent as guild does not exist",
None::<&'static str>, None::<&'static str>,
) )
@ -663,7 +655,6 @@ WHERE
} }
50001 => { 50001 => {
self.log_error( self.log_error(
pool,
"Could not be sent as missing access", "Could not be sent as missing access",
None::<&'static str>, None::<&'static str>,
) )
@ -672,7 +663,6 @@ WHERE
} }
50007 => { 50007 => {
self.log_error( self.log_error(
pool,
"Could not be sent as user has DMs disabled", "Could not be sent as user has DMs disabled",
None::<&'static str>, None::<&'static str>,
) )
@ -682,7 +672,6 @@ WHERE
} }
50013 => { 50013 => {
self.log_error( self.log_error(
pool,
"Could not be sent as permissions are invalid", "Could not be sent as permissions are invalid",
None::<&'static str>, None::<&'static str>,
) )
@ -694,25 +683,21 @@ WHERE
.await; .await;
} }
_ => { _ => {
self.log_error( self.log_error("HTTP error sending reminder", Some(http_error))
pool, .await;
"HTTP error sending reminder",
Some(http_error),
)
.await;
self.refresh(pool).await; self.refresh(pool).await;
} }
} }
} else { } else {
self.log_error(pool, "(Likely) a parsing error", Some(error)).await; self.log_error("(Likely) a parsing error", Some(error)).await;
self.refresh(pool).await; self.refresh(pool).await;
} }
} else { } else {
self.log_error(pool, "Non-HTTP error", Some(e)).await; self.log_error("Non-HTTP error", Some(e)).await;
self.refresh(pool).await; self.refresh(pool).await;
} }
} else { } else {
self.log_success(pool).await; self.log_success().await;
self.refresh(pool).await; self.refresh(pool).await;
} }
} else { } else {

View File

@ -1,7 +1,7 @@
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use chrono_tz::TZ_VARIANTS; use chrono_tz::TZ_VARIANTS;
use poise::AutocompleteChoice; use poise::serenity_prelude::AutocompleteChoice;
use crate::{models::CtxData, time_parser::natural_parser, Context}; use crate::{models::CtxData, time_parser::natural_parser, Context};
@ -37,15 +37,9 @@ WHERE
.collect() .collect()
} }
pub async fn time_hint_autocomplete( pub async fn time_hint_autocomplete(ctx: Context<'_>, partial: &str) -> Vec<AutocompleteChoice> {
ctx: Context<'_>,
partial: &str,
) -> Vec<AutocompleteChoice<String>> {
if partial.is_empty() { if partial.is_empty() {
vec![AutocompleteChoice { vec![AutocompleteChoice::new("Start typing a time...".to_string(), "now".to_string())]
name: "Start typing a time...".to_string(),
value: "now".to_string(),
}]
} else { } else {
match natural_parser(partial, &ctx.timezone().await.to_string()).await { match natural_parser(partial, &ctx.timezone().await.to_string()).await {
Some(timestamp) => match SystemTime::now().duration_since(UNIX_EPOCH) { Some(timestamp) => match SystemTime::now().duration_since(UNIX_EPOCH) {
@ -53,64 +47,49 @@ pub async fn time_hint_autocomplete(
let diff = timestamp - now.as_secs() as i64; let diff = timestamp - now.as_secs() as i64;
if diff < 0 { if diff < 0 {
vec![AutocompleteChoice { vec![AutocompleteChoice::new(
name: "Time is in the past".to_string(), "Time is in the past".to_string(),
value: "1 year ago".to_string(), "1 year ago".to_string(),
}] )]
} else { } else {
if diff > 86400 { if diff > 86400 {
vec![ vec![
AutocompleteChoice { AutocompleteChoice::new(partial.to_string(), partial.to_string()),
name: partial.to_string(), AutocompleteChoice::new(
value: partial.to_string(), format!(
},
AutocompleteChoice {
name: format!(
"In approximately {} days, {} hours", "In approximately {} days, {} hours",
diff / 86400, diff / 86400,
(diff % 86400) / 3600 (diff % 86400) / 3600
), ),
value: partial.to_string(), partial.to_string(),
}, ),
] ]
} else if diff > 3600 { } else if diff > 3600 {
vec![ vec![
AutocompleteChoice { AutocompleteChoice::new(partial.to_string(), partial.to_string()),
name: partial.to_string(), AutocompleteChoice::new(
value: partial.to_string(), format!("In approximately {} hours", diff / 3600),
}, partial.to_string(),
AutocompleteChoice { ),
name: format!("In approximately {} hours", diff / 3600),
value: partial.to_string(),
},
] ]
} else { } else {
vec![ vec![
AutocompleteChoice { AutocompleteChoice::new(partial.to_string(), partial.to_string()),
name: partial.to_string(), AutocompleteChoice::new(
value: partial.to_string(), format!("In approximately {} minutes", diff / 60),
}, partial.to_string(),
AutocompleteChoice { ),
name: format!("In approximately {} minutes", diff / 60),
value: partial.to_string(),
},
] ]
} }
} }
} }
Err(_) => { Err(_) => {
vec![AutocompleteChoice { vec![AutocompleteChoice::new(partial.to_string(), partial.to_string())]
name: partial.to_string(),
value: partial.to_string(),
}]
} }
}, },
None => { None => {
vec![AutocompleteChoice { vec![AutocompleteChoice::new("Time not recognised".to_string(), "now".to_string())]
name: "Time not recognised".to_string(),
value: "now".to_string(),
}]
} }
} }
} }

View File

@ -1,5 +1,5 @@
use lazy_regex::regex; use lazy_regex::regex;
use poise::serenity_prelude::command::CommandOptionType; use poise::serenity_prelude::CommandOptionType;
use regex::Captures; use regex::Captures;
use serde_json::{json, Value}; use serde_json::{json, Value};

View File

@ -5,9 +5,7 @@ use chrono_tz::Tz;
use log::warn; use log::warn;
use num_integer::Integer; use num_integer::Integer;
use poise::{ use poise::{
serenity_prelude::{ serenity_prelude::{builder::CreateEmbed, model::channel::Channel, ButtonStyle, ReactionType},
builder::CreateEmbed, component::ButtonStyle, model::channel::Channel, ReactionType,
},
CreateReply, Modal, CreateReply, Modal,
}; };

View File

@ -1,8 +1,6 @@
// todo split pager out into a single struct // todo split pager out into a single struct
use chrono_tz::Tz; use chrono_tz::Tz;
use poise::serenity_prelude::{ use poise::serenity_prelude::{ButtonStyle, CreateActionRow, CreateButton};
builder::CreateComponents, model::application::component::ButtonStyle,
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_repr::*; use serde_repr::*;
@ -11,7 +9,7 @@ use crate::{component_models::ComponentDataModel, models::reminder::look_flags::
pub trait Pager { pub trait Pager {
fn next_page(&self, max_pages: usize) -> usize; fn next_page(&self, max_pages: usize) -> usize;
fn create_button_row(&self, max_pages: usize, comp: &mut CreateComponents); fn create_button_row(&self, max_pages: usize) -> CreateActionRow;
} }
#[derive(Serialize_repr, Deserialize_repr)] #[derive(Serialize_repr, Deserialize_repr)]
@ -43,41 +41,33 @@ impl Pager for LookPager {
} }
} }
fn create_button_row(&self, max_pages: usize, comp: &mut CreateComponents) { fn create_button_row(&self, max_pages: usize) -> CreateActionRow {
let next_page = self.next_page(max_pages); let next_page = self.next_page(max_pages);
let (page_first, page_prev, page_refresh, page_next, page_last) = let (page_first, page_prev, page_refresh, page_next, page_last) =
LookPager::buttons(self.flags, next_page, self.timezone); LookPager::buttons(self.flags, next_page, self.timezone);
comp.create_action_row(|row| { CreateActionRow::Buttons(vec![
row.create_button(|b| { CreateButton::new(page_first.to_custom_id())
b.label("⏮️") .label("⏮️")
.style(ButtonStyle::Primary) .style(ButtonStyle::Primary)
.custom_id(page_first.to_custom_id()) .disabled(next_page == 0),
.disabled(next_page == 0) CreateButton::new(page_prev.to_custom_id())
}) .label("◀️")
.create_button(|b| { .style(ButtonStyle::Secondary)
b.label("◀️") .disabled(next_page == 0),
.style(ButtonStyle::Secondary) CreateButton::new(page_refresh.to_custom_id())
.custom_id(page_prev.to_custom_id()) .label("🔁")
.disabled(next_page == 0) .style(ButtonStyle::Secondary),
}) CreateButton::new(page_next.to_custom_id())
.create_button(|b| { .label("▶️")
b.label("🔁").style(ButtonStyle::Secondary).custom_id(page_refresh.to_custom_id()) .style(ButtonStyle::Secondary)
}) .disabled(next_page + 1 == max_pages),
.create_button(|b| { CreateButton::new(page_last.to_custom_id())
b.label("▶️") .label("⏭️")
.style(ButtonStyle::Secondary) .style(ButtonStyle::Primary)
.custom_id(page_next.to_custom_id()) .disabled(next_page + 1 == max_pages),
.disabled(next_page + 1 == max_pages) ])
})
.create_button(|b| {
b.label("⏭️")
.style(ButtonStyle::Primary)
.custom_id(page_last.to_custom_id())
.disabled(next_page + 1 == max_pages)
})
});
} }
} }
@ -150,41 +140,33 @@ impl Pager for DelPager {
} }
} }
fn create_button_row(&self, max_pages: usize, comp: &mut CreateComponents) { fn create_button_row(&self, max_pages: usize) -> CreateActionRow {
let next_page = self.next_page(max_pages); let next_page = self.next_page(max_pages);
let (page_first, page_prev, page_refresh, page_next, page_last) = let (page_first, page_prev, page_refresh, page_next, page_last) =
DelPager::buttons(next_page, self.timezone); DelPager::buttons(next_page, self.timezone);
comp.create_action_row(|row| { CreateActionRow::Buttons(vec![
row.create_button(|b| { CreateButton::new(page_first.to_custom_id())
b.label("⏮️") .label("⏮️")
.style(ButtonStyle::Primary) .style(ButtonStyle::Primary)
.custom_id(page_first.to_custom_id()) .disabled(next_page == 0),
.disabled(next_page == 0) CreateButton::new(page_prev.to_custom_id())
}) .label("◀️")
.create_button(|b| { .style(ButtonStyle::Secondary)
b.label("◀️") .disabled(next_page == 0),
.style(ButtonStyle::Secondary) CreateButton::new(page_refresh.to_custom_id())
.custom_id(page_prev.to_custom_id()) .label("🔁")
.disabled(next_page == 0) .style(ButtonStyle::Secondary),
}) CreateButton::new(page_next.to_custom_id())
.create_button(|b| { .label("▶️")
b.label("🔁").style(ButtonStyle::Secondary).custom_id(page_refresh.to_custom_id()) .style(ButtonStyle::Secondary)
}) .disabled(next_page + 1 == max_pages),
.create_button(|b| { CreateButton::new(page_last.to_custom_id())
b.label("▶️") .label("⏭️")
.style(ButtonStyle::Secondary) .style(ButtonStyle::Primary)
.custom_id(page_next.to_custom_id()) .disabled(next_page + 1 == max_pages),
.disabled(next_page + 1 == max_pages) ])
})
.create_button(|b| {
b.label("⏭️")
.style(ButtonStyle::Primary)
.custom_id(page_last.to_custom_id())
.disabled(next_page + 1 == max_pages)
})
});
} }
} }
@ -233,41 +215,33 @@ impl Pager for TodoPager {
} }
} }
fn create_button_row(&self, max_pages: usize, comp: &mut CreateComponents) { fn create_button_row(&self, max_pages: usize) -> CreateActionRow {
let next_page = self.next_page(max_pages); let next_page = self.next_page(max_pages);
let (page_first, page_prev, page_refresh, page_next, page_last) = let (page_first, page_prev, page_refresh, page_next, page_last) =
TodoPager::buttons(next_page, self.user_id, self.channel_id, self.guild_id); TodoPager::buttons(next_page, self.user_id, self.channel_id, self.guild_id);
comp.create_action_row(|row| { CreateActionRow::Buttons(vec![
row.create_button(|b| { CreateButton::new(page_first.to_custom_id())
b.label("⏮️") .label("⏮️")
.style(ButtonStyle::Primary) .style(ButtonStyle::Primary)
.custom_id(page_first.to_custom_id()) .disabled(next_page == 0),
.disabled(next_page == 0) CreateButton::new(page_prev.to_custom_id())
}) .label("◀️")
.create_button(|b| { .style(ButtonStyle::Secondary)
b.label("◀️") .disabled(next_page == 0),
.style(ButtonStyle::Secondary) CreateButton::new(page_refresh.to_custom_id())
.custom_id(page_prev.to_custom_id()) .label("🔁")
.disabled(next_page == 0) .style(ButtonStyle::Secondary),
}) CreateButton::new(page_next.to_custom_id())
.create_button(|b| { .label("▶️")
b.label("🔁").style(ButtonStyle::Secondary).custom_id(page_refresh.to_custom_id()) .style(ButtonStyle::Secondary)
}) .disabled(next_page + 1 == max_pages),
.create_button(|b| { CreateButton::new(page_last.to_custom_id())
b.label("▶️") .label("⏭️")
.style(ButtonStyle::Secondary) .style(ButtonStyle::Primary)
.custom_id(page_next.to_custom_id()) .disabled(next_page + 1 == max_pages),
.disabled(next_page + 1 == max_pages) ])
})
.create_button(|b| {
b.label("⏭️")
.style(ButtonStyle::Primary)
.custom_id(page_last.to_custom_id())
.disabled(next_page + 1 == max_pages)
})
});
} }
} }
@ -350,41 +324,33 @@ impl Pager for MacroPager {
} }
} }
fn create_button_row(&self, max_pages: usize, comp: &mut CreateComponents) { fn create_button_row(&self, max_pages: usize) -> CreateActionRow {
let next_page = self.next_page(max_pages); let next_page = self.next_page(max_pages);
let (page_first, page_prev, page_refresh, page_next, page_last) = let (page_first, page_prev, page_refresh, page_next, page_last) =
MacroPager::buttons(next_page); MacroPager::buttons(next_page);
comp.create_action_row(|row| { CreateActionRow::Buttons(vec![
row.create_button(|b| { CreateButton::new(page_first.to_custom_id())
b.label("⏮️") .label("⏮️")
.style(ButtonStyle::Primary) .style(ButtonStyle::Primary)
.custom_id(page_first.to_custom_id()) .disabled(next_page == 0),
.disabled(next_page == 0) CreateButton::new(page_prev.to_custom_id())
}) .label("◀️")
.create_button(|b| { .style(ButtonStyle::Secondary)
b.label("◀️") .disabled(next_page == 0),
.style(ButtonStyle::Secondary) CreateButton::new(page_refresh.to_custom_id())
.custom_id(page_prev.to_custom_id()) .label("🔁")
.disabled(next_page == 0) .style(ButtonStyle::Secondary),
}) CreateButton::new(page_next.to_custom_id())
.create_button(|b| { .label("▶️")
b.label("🔁").style(ButtonStyle::Secondary).custom_id(page_refresh.to_custom_id()) .style(ButtonStyle::Secondary)
}) .disabled(next_page + 1 == max_pages),
.create_button(|b| { CreateButton::new(page_last.to_custom_id())
b.label("▶️") .label("⏭️")
.style(ButtonStyle::Secondary) .style(ButtonStyle::Primary)
.custom_id(page_next.to_custom_id()) .disabled(next_page + 1 == max_pages),
.disabled(next_page + 1 == max_pages) ])
})
.create_button(|b| {
b.label("⏭️")
.style(ButtonStyle::Primary)
.custom_id(page_last.to_custom_id())
.disabled(next_page + 1 == max_pages)
})
});
} }
} }

1
web/static/assets Symbolic link
View File

@ -0,0 +1 @@
/home/jude/reminder-bot/reminder-dashboard/dist/static/assets

1
web/static/index.html Symbolic link
View File

@ -0,0 +1 @@
/home/jude/reminder-bot/reminder-dashboard/dist/index.html