moved postman into separate crate
This commit is contained in:
parent
d62c8c95c2
commit
a3844dde9e
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -1073,6 +1073,22 @@ version = "0.3.24"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "postman"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"chrono-tz",
|
||||||
|
"env_logger",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"num-integer",
|
||||||
|
"regex",
|
||||||
|
"serenity",
|
||||||
|
"sqlx",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@ -1228,6 +1244,7 @@ dependencies = [
|
|||||||
"levenshtein",
|
"levenshtein",
|
||||||
"log",
|
"log",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
|
"postman",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"regex",
|
"regex",
|
||||||
"regex_command_attr",
|
"regex_command_attr",
|
||||||
|
@ -28,6 +28,9 @@ base64 = "0.13.0"
|
|||||||
[dependencies.regex_command_attr]
|
[dependencies.regex_command_attr]
|
||||||
path = "command_attributes"
|
path = "command_attributes"
|
||||||
|
|
||||||
|
[dependencies.postman]
|
||||||
|
path = "postman"
|
||||||
|
|
||||||
[dependencies.serenity]
|
[dependencies.serenity]
|
||||||
git = "https://github.com/serenity-rs/serenity"
|
git = "https://github.com/serenity-rs/serenity"
|
||||||
branch = "next"
|
branch = "next"
|
||||||
|
32
postman/Cargo.toml
Normal file
32
postman/Cargo.toml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
[package]
|
||||||
|
name = "postman"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1", features = ["process", "full"] }
|
||||||
|
regex = "1.4"
|
||||||
|
log = "0.4"
|
||||||
|
env_logger = "0.8"
|
||||||
|
chrono = "0.4"
|
||||||
|
chrono-tz = { version = "0.5", features = ["serde"] }
|
||||||
|
lazy_static = "1.4"
|
||||||
|
num-integer = "0.1"
|
||||||
|
sqlx = { version = "0.5.10", features = ["runtime-tokio-rustls", "macros", "mysql", "bigdecimal", "chrono"]}
|
||||||
|
|
||||||
|
[dependencies.serenity]
|
||||||
|
git = "https://github.com/serenity-rs/serenity"
|
||||||
|
branch = "next"
|
||||||
|
default-features = false
|
||||||
|
features = [
|
||||||
|
"builder",
|
||||||
|
"client",
|
||||||
|
"cache",
|
||||||
|
"gateway",
|
||||||
|
"http",
|
||||||
|
"model",
|
||||||
|
"utils",
|
||||||
|
"rustls_backend",
|
||||||
|
"collector",
|
||||||
|
"unstable_discord_api"
|
||||||
|
]
|
33
postman/src/lib.rs
Normal file
33
postman/src/lib.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
mod sender;
|
||||||
|
|
||||||
|
use log::info;
|
||||||
|
use serenity::client::Context;
|
||||||
|
use sqlx::{Executor, MySql};
|
||||||
|
use std::env;
|
||||||
|
use tokio::time::sleep_until;
|
||||||
|
use tokio::time::{Duration, Instant};
|
||||||
|
|
||||||
|
type Database = MySql;
|
||||||
|
|
||||||
|
pub async fn initialize(ctx: Context, pool: impl Executor<'_, Database = Database> + Copy) {
|
||||||
|
let REMIND_INTERVAL = env::var("REMIND_INTERVAL")
|
||||||
|
.map(|inner| inner.parse::<u64>().ok())
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
.unwrap_or(10);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let sleep_to = Instant::now() + Duration::from_secs(REMIND_INTERVAL);
|
||||||
|
let reminders = sender::Reminder::fetch_reminders(pool).await;
|
||||||
|
|
||||||
|
if reminders.len() > 0 {
|
||||||
|
info!("Preparing to send {} reminders.", reminders.len());
|
||||||
|
|
||||||
|
for reminder in reminders {
|
||||||
|
reminder.send(pool, ctx.clone()).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep_until(sleep_to).await;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
|
use crate::Database;
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use chrono_tz::Tz;
|
use chrono_tz::Tz;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use num_integer::Integer;
|
use num_integer::Integer;
|
||||||
use regex::{Captures, Regex};
|
use regex::{Captures, Regex};
|
||||||
@ -15,7 +17,7 @@ use serenity::{
|
|||||||
};
|
};
|
||||||
use sqlx::{
|
use sqlx::{
|
||||||
types::chrono::{NaiveDateTime, Utc},
|
types::chrono::{NaiveDateTime, Utc},
|
||||||
MySqlPool,
|
Executor,
|
||||||
};
|
};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@ -114,7 +116,10 @@ struct EmbedField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Embed {
|
impl Embed {
|
||||||
pub async fn from_id(pool: &MySqlPool, id: u32) -> Option<Self> {
|
pub async fn from_id(
|
||||||
|
pool: impl Executor<'_, Database = Database> + Copy,
|
||||||
|
id: u32,
|
||||||
|
) -> Option<Self> {
|
||||||
let mut inner = sqlx::query_as_unchecked!(
|
let mut inner = sqlx::query_as_unchecked!(
|
||||||
EmbedInner,
|
EmbedInner,
|
||||||
"
|
"
|
||||||
@ -135,7 +140,7 @@ WHERE
|
|||||||
",
|
",
|
||||||
id
|
id
|
||||||
)
|
)
|
||||||
.fetch_one(&pool.clone())
|
.fetch_one(pool)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -265,7 +270,7 @@ pub struct Reminder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Reminder {
|
impl Reminder {
|
||||||
pub async fn fetch_reminders(pool: &MySqlPool) -> Vec<Self> {
|
pub async fn fetch_reminders(pool: impl Executor<'_, Database = Database> + Copy) -> Vec<Self> {
|
||||||
sqlx::query_as_unchecked!(
|
sqlx::query_as_unchecked!(
|
||||||
Reminder,
|
Reminder,
|
||||||
"
|
"
|
||||||
@ -317,7 +322,7 @@ WHERE
|
|||||||
.collect::<Vec<Self>>()
|
.collect::<Vec<Self>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn reset_webhook(&self, pool: &MySqlPool) {
|
async fn reset_webhook(&self, pool: impl Executor<'_, Database = Database> + Copy) {
|
||||||
let _ = sqlx::query!(
|
let _ = sqlx::query!(
|
||||||
"
|
"
|
||||||
UPDATE channels SET webhook_id = NULL, webhook_token = NULL WHERE channel = ?
|
UPDATE channels SET webhook_id = NULL, webhook_token = NULL WHERE channel = ?
|
||||||
@ -328,14 +333,15 @@ UPDATE channels SET webhook_id = NULL, webhook_token = NULL WHERE channel = ?
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn refresh(&self, pool: &MySqlPool) {
|
async fn refresh(&self, pool: impl Executor<'_, Database = Database> + Copy) {
|
||||||
if self.interval_seconds.is_some() || self.interval_months.is_some() {
|
if self.interval_seconds.is_some() || self.interval_months.is_some() {
|
||||||
let now = Utc::now().naive_local();
|
let now = Utc::now().naive_local();
|
||||||
let mut updated_reminder_time = self.utc_time;
|
let mut updated_reminder_time = self.utc_time;
|
||||||
|
|
||||||
if let Some(interval) = self.interval_months {
|
if let Some(interval) = self.interval_months {
|
||||||
let row = sqlx::query!(
|
let row = sqlx::query!(
|
||||||
"SELECT DATE_ADD(?, INTERVAL ? MONTH) AS new_time",
|
// use the second date_add to force return value to datetime
|
||||||
|
"SELECT DATE_ADD(DATE_ADD(?, INTERVAL ? MONTH), INTERVAL 0 SECOND) AS new_time",
|
||||||
updated_reminder_time,
|
updated_reminder_time,
|
||||||
interval
|
interval
|
||||||
)
|
)
|
||||||
@ -373,7 +379,7 @@ UPDATE reminders SET `utc_time` = ? WHERE `id` = ?
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn force_delete(&self, pool: &MySqlPool) {
|
async fn force_delete(&self, pool: impl Executor<'_, Database = Database> + Copy) {
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"
|
"
|
||||||
DELETE FROM reminders WHERE `id` = ?
|
DELETE FROM reminders WHERE `id` = ?
|
||||||
@ -389,7 +395,11 @@ DELETE FROM reminders WHERE `id` = ?
|
|||||||
let _ = http.as_ref().pin_message(self.channel_id, message_id.into(), None).await;
|
let _ = http.as_ref().pin_message(self.channel_id, message_id.into(), None).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(&self, pool: MySqlPool, cache_http: impl CacheHttp) {
|
pub async fn send(
|
||||||
|
&self,
|
||||||
|
pool: impl Executor<'_, Database = Database> + Copy,
|
||||||
|
cache_http: impl CacheHttp,
|
||||||
|
) {
|
||||||
async fn send_to_channel(
|
async fn send_to_channel(
|
||||||
cache_http: impl CacheHttp,
|
cache_http: impl CacheHttp,
|
||||||
reminder: &Reminder,
|
reminder: &Reminder,
|
||||||
@ -521,10 +531,10 @@ UPDATE `channels` SET paused = 0, paused_until = NULL WHERE `channel` = ?
|
|||||||
",
|
",
|
||||||
self.channel_id
|
self.channel_id
|
||||||
)
|
)
|
||||||
.execute(&pool.clone())
|
.execute(pool)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let embed = Embed::from_id(&pool.clone(), self.id).await.map(|e| e.into());
|
let embed = Embed::from_id(pool, self.id).await.map(|e| e.into());
|
||||||
|
|
||||||
let result = if let (Some(webhook_id), Some(webhook_token)) =
|
let result = if let (Some(webhook_id), Some(webhook_token)) =
|
||||||
(self.webhook_id, &self.webhook_token)
|
(self.webhook_id, &self.webhook_token)
|
||||||
@ -537,7 +547,7 @@ UPDATE `channels` SET paused = 0, paused_until = NULL WHERE `channel` = ?
|
|||||||
} else {
|
} else {
|
||||||
warn!("Webhook vanished: {:?}", webhook_res);
|
warn!("Webhook vanished: {:?}", webhook_res);
|
||||||
|
|
||||||
self.reset_webhook(&pool.clone()).await;
|
self.reset_webhook(pool).await;
|
||||||
send_to_channel(cache_http, &self, embed).await
|
send_to_channel(cache_http, &self, embed).await
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -550,20 +560,20 @@ UPDATE `channels` SET paused = 0, paused_until = NULL WHERE `channel` = ?
|
|||||||
if let Error::Http(error) = e {
|
if let Error::Http(error) = e {
|
||||||
if error.status_code() == Some(StatusCode::from_u16(404).unwrap()) {
|
if error.status_code() == Some(StatusCode::from_u16(404).unwrap()) {
|
||||||
error!("Seeing channel is deleted. Removing reminder");
|
error!("Seeing channel is deleted. Removing reminder");
|
||||||
self.force_delete(&pool).await;
|
self.force_delete(pool).await;
|
||||||
} else {
|
} else {
|
||||||
self.refresh(&pool).await;
|
self.refresh(pool).await;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.refresh(&pool).await;
|
self.refresh(pool).await;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.refresh(&pool).await;
|
self.refresh(pool).await;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
info!("Reminder {} is paused", self.id);
|
info!("Reminder {} is paused", self.id);
|
||||||
|
|
||||||
self.refresh(&pool).await;
|
self.refresh(pool).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -323,7 +323,7 @@ async fn look(ctx: &Context, invoke: &mut CommandInvoke, args: CommandOptions) {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|reminder| reminder.display(&flags, &timezone))
|
.map(|reminder| reminder.display(&flags, &timezone))
|
||||||
.fold(0, |t, r| t + r.len())
|
.fold(0, |t, r| t + r.len())
|
||||||
.div_ceil(EMBED_DESCRIPTION_MAX_LENGTH);
|
.div_ceil(&EMBED_DESCRIPTION_MAX_LENGTH);
|
||||||
|
|
||||||
let pager = LookPager::new(flags, timezone);
|
let pager = LookPager::new(flags, timezone);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ pub(crate) mod pager;
|
|||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use chrono_tz::Tz;
|
use chrono_tz::Tz;
|
||||||
|
use num_integer::Integer;
|
||||||
use rmp_serde::Serializer;
|
use rmp_serde::Serializer;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serenity::{
|
use serenity::{
|
||||||
@ -78,7 +79,7 @@ impl ComponentDataModel {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|reminder| reminder.display(&flags, &pager.timezone))
|
.map(|reminder| reminder.display(&flags, &pager.timezone))
|
||||||
.fold(0, |t, r| t + r.len())
|
.fold(0, |t, r| t + r.len())
|
||||||
.div_ceil(EMBED_DESCRIPTION_MAX_LENGTH);
|
.div_ceil(&EMBED_DESCRIPTION_MAX_LENGTH);
|
||||||
|
|
||||||
let channel_name =
|
let channel_name =
|
||||||
if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx) {
|
if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx) {
|
||||||
|
@ -14,11 +14,6 @@ use regex::Regex;
|
|||||||
use serenity::model::prelude::AttachmentType;
|
use serenity::model::prelude::AttachmentType;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref REMIND_INTERVAL: u64 = env::var("REMIND_INTERVAL")
|
|
||||||
.map(|inner| inner.parse::<u64>().ok())
|
|
||||||
.ok()
|
|
||||||
.flatten()
|
|
||||||
.unwrap_or(10);
|
|
||||||
pub static ref DEFAULT_AVATAR: AttachmentType<'static> = (
|
pub static ref DEFAULT_AVATAR: AttachmentType<'static> = (
|
||||||
include_bytes!(concat!(
|
include_bytes!(concat!(
|
||||||
env!("CARGO_MANIFEST_DIR"),
|
env!("CARGO_MANIFEST_DIR"),
|
||||||
|
28
src/main.rs
28
src/main.rs
@ -1,4 +1,3 @@
|
|||||||
#![feature(int_roundings)]
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
@ -9,7 +8,6 @@ mod framework;
|
|||||||
mod hooks;
|
mod hooks;
|
||||||
mod interval_parser;
|
mod interval_parser;
|
||||||
mod models;
|
mod models;
|
||||||
mod sender;
|
|
||||||
mod time_parser;
|
mod time_parser;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
@ -24,6 +22,7 @@ use std::{
|
|||||||
use chrono_tz::Tz;
|
use chrono_tz::Tz;
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use postman::initialize;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
async_trait,
|
async_trait,
|
||||||
client::Client,
|
client::Client,
|
||||||
@ -39,15 +38,12 @@ use serenity::{
|
|||||||
utils::shard_id,
|
utils::shard_id,
|
||||||
};
|
};
|
||||||
use sqlx::mysql::MySqlPool;
|
use sqlx::mysql::MySqlPool;
|
||||||
use tokio::{
|
use tokio::sync::RwLock;
|
||||||
sync::RwLock,
|
|
||||||
time::{Duration, Instant},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
commands::{info_cmds, moderation_cmds, reminder_cmds, todo_cmds},
|
commands::{info_cmds, moderation_cmds, reminder_cmds, todo_cmds},
|
||||||
component_models::ComponentDataModel,
|
component_models::ComponentDataModel,
|
||||||
consts::{CNC_GUILD, REMIND_INTERVAL, SUBSCRIPTION_ROLES, THEME_COLOR},
|
consts::{CNC_GUILD, SUBSCRIPTION_ROLES, THEME_COLOR},
|
||||||
framework::RegexFramework,
|
framework::RegexFramework,
|
||||||
models::command_macro::CommandMacro,
|
models::command_macro::CommandMacro,
|
||||||
};
|
};
|
||||||
@ -88,24 +84,10 @@ impl EventHandler for Handler {
|
|||||||
|
|
||||||
if !self.is_loop_running.load(Ordering::Relaxed) {
|
if !self.is_loop_running.load(Ordering::Relaxed) {
|
||||||
let ctx = ctx_base.clone();
|
let ctx = ctx_base.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||||
|
|
||||||
loop {
|
tokio::spawn(async move {
|
||||||
let sleep_until = Instant::now() + Duration::from_secs(*REMIND_INTERVAL);
|
initialize(ctx, &pool).await;
|
||||||
let reminders = sender::Reminder::fetch_reminders(&pool).await;
|
|
||||||
|
|
||||||
if reminders.len() > 0 {
|
|
||||||
info!("Preparing to send {} reminders.", reminders.len());
|
|
||||||
|
|
||||||
for reminder in reminders {
|
|
||||||
reminder.send(pool.clone(), ctx.clone()).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tokio::time::sleep_until(sleep_until).await;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
self.is_loop_running.swap(true, Ordering::Relaxed);
|
self.is_loop_running.swap(true, Ordering::Relaxed);
|
||||||
|
8
web/Cargo.toml
Normal file
8
web/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "web"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
8
web/src/lib.rs
Normal file
8
web/src/lib.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = 2 + 2;
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user