added cargo feature to cache guild prefixes. dont query language until necessary in framework
This commit is contained in:
parent
1473ac3bcf
commit
c76a456af5
21
Cargo.lock
generated
21
Cargo.lock
generated
@ -213,8 +213,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "command_attr"
|
||||
version = "0.3.3"
|
||||
source = "git+https://github.com/Lakelezz/serenity?branch=remove-indirection#6d955638f356b2dbbf7f69a4123c0bfbe218d601"
|
||||
version = "0.3.4"
|
||||
source = "git+https://github.com/serenity-rs/serenity?branch=next#943cf037c114ddf3513a3c8c3a2301da41c34f9e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -292,6 +292,16 @@ dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "4.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.9.0"
|
||||
@ -1261,11 +1271,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reminder_rs"
|
||||
version = "1.4.9"
|
||||
version = "1.4.10"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"dashmap",
|
||||
"dotenv",
|
||||
"env_logger",
|
||||
"humantime",
|
||||
@ -1483,8 +1494,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serenity"
|
||||
version = "0.10.2"
|
||||
source = "git+https://github.com/Lakelezz/serenity?branch=remove-indirection#6d955638f356b2dbbf7f69a4123c0bfbe218d601"
|
||||
version = "0.10.4"
|
||||
source = "git+https://github.com/serenity-rs/serenity?branch=next#943cf037c114ddf3513a3c8c3a2301da41c34f9e"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"async-tungstenite",
|
||||
|
@ -1,10 +1,11 @@
|
||||
[package]
|
||||
name = "reminder_rs"
|
||||
version = "1.4.9"
|
||||
version = "1.4.10"
|
||||
authors = ["jellywx <judesouthworth@pm.me>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
dashmap = { version = "4.0", optional = true }
|
||||
dotenv = "0.15"
|
||||
humantime = "2.1"
|
||||
tokio = { version = "1", features = ["process", "full"] }
|
||||
@ -22,8 +23,11 @@ rand = "0.7"
|
||||
Inflector = "0.11"
|
||||
levenshtein = "1.0"
|
||||
# serenity = { version = "0.10", features = ["collector"] }
|
||||
serenity = { git = "https://github.com/Lakelezz/serenity", branch = "remove-indirection", features = ["collector"] }
|
||||
serenity = { git = "https://github.com/serenity-rs/serenity", branch = "next", features = ["collector"] }
|
||||
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "macros", "mysql", "bigdecimal", "chrono"]}
|
||||
|
||||
[dependencies.regex_command_attr]
|
||||
path = "./regex_command_attr"
|
||||
|
||||
[features]
|
||||
prefix-cache = ["dashmap"]
|
||||
|
@ -107,7 +107,7 @@ async fn help(ctx: &Context, msg: &Message, args: String) {
|
||||
let (pool, lm) = get_ctx_data(&ctx).await;
|
||||
|
||||
let language = UserData::language_of(&msg.author, &pool);
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool);
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &ctx);
|
||||
|
||||
if !args.is_empty() {
|
||||
let framework = ctx
|
||||
@ -138,7 +138,7 @@ async fn info(ctx: &Context, msg: &Message, _args: String) {
|
||||
let (pool, lm) = get_ctx_data(&ctx).await;
|
||||
|
||||
let language = UserData::language_of(&msg.author, &pool);
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool);
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &ctx);
|
||||
let current_user = ctx.cache.current_user();
|
||||
let footer = footer(ctx).await;
|
||||
|
||||
|
@ -28,6 +28,9 @@ use crate::{
|
||||
FrameworkCtx, PopularTimezones,
|
||||
};
|
||||
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
use crate::PrefixCache;
|
||||
|
||||
use std::{collections::HashMap, iter, time::Duration};
|
||||
|
||||
#[command]
|
||||
@ -174,7 +177,7 @@ async fn timezone(ctx: &Context, msg: &Message, args: String) {
|
||||
} else {
|
||||
let content = lm.get(&user_data.language, "timezone/no_argument").replace(
|
||||
"{prefix}",
|
||||
&GuildData::prefix_from_id(msg.guild_id, &pool).await,
|
||||
&GuildData::prefix_from_id(msg.guild_id, &ctx).await,
|
||||
);
|
||||
|
||||
let popular_timezones = ctx
|
||||
@ -252,7 +255,7 @@ async fn change_meridian(ctx: &Context, msg: &Message, args: String) {
|
||||
})
|
||||
.await;
|
||||
} else {
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool).await;
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &ctx).await;
|
||||
|
||||
command_help(ctx, msg, lm, &prefix, &user_data.language, "meridian").await;
|
||||
}
|
||||
@ -413,6 +416,12 @@ async fn prefix(ctx: &Context, msg: &Message, args: String) {
|
||||
.await;
|
||||
} else {
|
||||
guild_data.prefix = args;
|
||||
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
let prefix_cache = ctx.data.read().await.get::<PrefixCache>().cloned().unwrap();
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
prefix_cache.insert(msg.guild_id.unwrap(), guild_data.prefix.clone());
|
||||
|
||||
guild_data.commit_changes(&pool).await;
|
||||
|
||||
let content =
|
||||
@ -548,7 +557,7 @@ WHERE
|
||||
})
|
||||
.await;
|
||||
} else {
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool).await;
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &ctx).await;
|
||||
|
||||
command_help(ctx, msg, lm, &prefix, &language, "restrict").await;
|
||||
}
|
||||
@ -675,7 +684,7 @@ SELECT command FROM command_aliases WHERE guild_id = (SELECT id FROM guilds WHER
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool).await;
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &ctx).await;
|
||||
|
||||
command_help(ctx, msg, lm, &prefix, &language, "alias").await;
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ async fn offset(ctx: &Context, msg: &Message, args: String) {
|
||||
let user_data = UserData::from_user(&msg.author, &ctx, &pool).await.unwrap();
|
||||
|
||||
if args.is_empty() {
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool).await;
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &ctx).await;
|
||||
|
||||
command_help(ctx, msg, lm, &prefix, &user_data.language, "offset").await;
|
||||
} else {
|
||||
@ -496,10 +496,48 @@ async fn delete(ctx: &Context, msg: &Message, _args: String) {
|
||||
.say(&ctx, lm.get(&user_data.language, "del/listing"))
|
||||
.await;
|
||||
|
||||
let reminders = if let Some(guild_id) = msg.guild_id.map(|f| f.as_u64().to_owned()) {
|
||||
sqlx::query_as_unchecked!(
|
||||
LookReminder,
|
||||
"
|
||||
let reminders = if let Some(guild_id) = msg.guild_id {
|
||||
let guild_opt = guild_id.to_guild_cached(&ctx).await;
|
||||
|
||||
if let Some(guild) = guild_opt {
|
||||
let channels = guild
|
||||
.channels
|
||||
.keys()
|
||||
.into_iter()
|
||||
.map(|k| k.as_u64().to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(",");
|
||||
|
||||
sqlx::query_as_unchecked!(
|
||||
LookReminder,
|
||||
"
|
||||
SELECT
|
||||
reminders.id, reminders.time, channels.channel, messages.content, embeds.description
|
||||
FROM
|
||||
reminders
|
||||
LEFT OUTER JOIN
|
||||
channels
|
||||
ON
|
||||
channels.id = reminders.channel_id
|
||||
INNER JOIN
|
||||
messages
|
||||
ON
|
||||
messages.id = reminders.message_id
|
||||
LEFT JOIN
|
||||
embeds
|
||||
ON
|
||||
embeds.id = messages.embed_id
|
||||
WHERE
|
||||
FIND_IN_SET(channels.channel, ?)
|
||||
",
|
||||
channels
|
||||
)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
} else {
|
||||
sqlx::query_as_unchecked!(
|
||||
LookReminder,
|
||||
"
|
||||
SELECT
|
||||
reminders.id, reminders.time, channels.channel, messages.content, embeds.description
|
||||
FROM
|
||||
@ -518,11 +556,12 @@ ON
|
||||
embeds.id = messages.embed_id
|
||||
WHERE
|
||||
channels.guild_id = (SELECT id FROM guilds WHERE guild = ?)
|
||||
",
|
||||
guild_id
|
||||
)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
",
|
||||
guild_id.as_u64()
|
||||
)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
}
|
||||
} else {
|
||||
sqlx::query_as!(
|
||||
LookReminder,
|
||||
@ -779,7 +818,7 @@ DELETE FROM timers WHERE owner = ? AND name = ?
|
||||
}
|
||||
|
||||
_ => {
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool).await;
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &ctx).await;
|
||||
|
||||
command_help(ctx, msg, lm, &prefix, &language, "timer").await;
|
||||
}
|
||||
@ -1110,7 +1149,7 @@ INSERT INTO reminders (
|
||||
ctx,
|
||||
msg,
|
||||
lm,
|
||||
&GuildData::prefix_from_id(msg.guild_id, &pool).await,
|
||||
&GuildData::prefix_from_id(msg.guild_id, &ctx).await,
|
||||
&language,
|
||||
"countdown",
|
||||
)
|
||||
@ -1123,7 +1162,7 @@ INSERT INTO reminders (
|
||||
&ctx,
|
||||
lm.get(&language, "interval/donor").replace(
|
||||
"{prefix}",
|
||||
&GuildData::prefix_from_id(msg.guild_id, &pool).await,
|
||||
&GuildData::prefix_from_id(msg.guild_id, &ctx).await,
|
||||
),
|
||||
)
|
||||
.await;
|
||||
@ -1195,7 +1234,7 @@ async fn remind_command(ctx: &Context, msg: &Message, args: String, command: Rem
|
||||
&ctx,
|
||||
lm.get(&language, "interval/donor").replace(
|
||||
"{prefix}",
|
||||
&GuildData::prefix_from_id(msg.guild_id, &pool).await,
|
||||
&GuildData::prefix_from_id(msg.guild_id, &ctx).await,
|
||||
),
|
||||
)
|
||||
.await;
|
||||
@ -1347,7 +1386,7 @@ async fn remind_command(ctx: &Context, msg: &Message, args: String, command: Rem
|
||||
}
|
||||
|
||||
None => {
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool).await;
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &ctx).await;
|
||||
|
||||
match command {
|
||||
RemindCommand::Remind => {
|
||||
@ -1572,7 +1611,7 @@ async fn natural(ctx: &Context, msg: &Message, args: String) {
|
||||
ctx,
|
||||
msg,
|
||||
lm,
|
||||
&GuildData::prefix_from_id(msg.guild_id, &pool).await,
|
||||
&GuildData::prefix_from_id(msg.guild_id, &ctx).await,
|
||||
&user_data.language,
|
||||
"natural",
|
||||
)
|
||||
@ -1629,7 +1668,7 @@ async fn create_reminder<'a, U: Into<u64>, T: TryInto<i64>>(
|
||||
match create_webhook(&ctx, guild_channel, "Reminder").await {
|
||||
Ok(webhook) => {
|
||||
channel_data.webhook_id = Some(webhook.id.as_u64().to_owned());
|
||||
channel_data.webhook_token = Some(webhook.token);
|
||||
channel_data.webhook_token = webhook.token;
|
||||
|
||||
channel_data.commit_changes(&pool).await;
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ DELETE FROM todos WHERE user_id = (SELECT id FROM users WHERE user = ?) AND guil
|
||||
let (pool, lm) = get_ctx_data(&ctx).await;
|
||||
|
||||
let user_data = UserData::from_user(&msg.author, &ctx, &pool).await.unwrap();
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool).await;
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &ctx).await;
|
||||
|
||||
match subcommand {
|
||||
SubCommand::View => {
|
||||
@ -426,7 +426,7 @@ async fn show_help(ctx: &Context, msg: &Message, target: Option<TodoTarget>) {
|
||||
let (pool, lm) = get_ctx_data(&ctx).await;
|
||||
|
||||
let language = UserData::language_of(&msg.author, &pool);
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &pool);
|
||||
let prefix = GuildData::prefix_from_id(msg.guild_id, &ctx);
|
||||
|
||||
let command = match target {
|
||||
None => "todo",
|
||||
|
@ -335,15 +335,7 @@ impl Framework for RegexFramework {
|
||||
|
||||
async fn check_prefix(ctx: &Context, guild: &Guild, prefix_opt: Option<Match<'_>>) -> bool {
|
||||
if let Some(prefix) = prefix_opt {
|
||||
let pool = ctx
|
||||
.data
|
||||
.read()
|
||||
.await
|
||||
.get::<SQLPool>()
|
||||
.cloned()
|
||||
.expect("Could not get SQLPool from data");
|
||||
|
||||
let guild_prefix = GuildData::prefix_from_id(Some(guild.id), &pool).await;
|
||||
let guild_prefix = GuildData::prefix_from_id(Some(guild.id), &ctx).await;
|
||||
|
||||
guild_prefix.as_str() == prefix.as_str()
|
||||
} else {
|
||||
@ -369,7 +361,7 @@ impl Framework for RegexFramework {
|
||||
if check_prefix(&ctx, &guild, full_match.name("prefix")).await {
|
||||
let lm = data.get::<LanguageManager>().unwrap();
|
||||
|
||||
let language = UserData::language_of(&msg.author, &pool).await;
|
||||
let language = UserData::language_of(&msg.author, &pool);
|
||||
|
||||
match check_self_permissions(&ctx, &guild, &channel).await {
|
||||
Ok(perms) => match perms {
|
||||
@ -414,18 +406,25 @@ impl Framework for RegexFramework {
|
||||
{
|
||||
let _ = msg
|
||||
.channel_id
|
||||
.say(&ctx, lm.get(&language, "no_perms_restricted"))
|
||||
.say(
|
||||
&ctx,
|
||||
lm.get(&language.await, "no_perms_restricted"),
|
||||
)
|
||||
.await;
|
||||
} else if command.required_perms == PermissionLevel::Managed {
|
||||
let _ = msg
|
||||
.channel_id
|
||||
.say(
|
||||
&ctx,
|
||||
lm.get(&language, "no_perms_managed").replace(
|
||||
"{prefix}",
|
||||
&GuildData::prefix_from_id(msg.guild_id, &pool)
|
||||
lm.get(&language.await, "no_perms_managed")
|
||||
.replace(
|
||||
"{prefix}",
|
||||
&GuildData::prefix_from_id(
|
||||
msg.guild_id,
|
||||
&ctx,
|
||||
)
|
||||
.await,
|
||||
),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
@ -439,7 +438,7 @@ impl Framework for RegexFramework {
|
||||
manage_messages,
|
||||
) => {
|
||||
let response = lm
|
||||
.get(&language, "no_perms_general")
|
||||
.get(&language.await, "no_perms_general")
|
||||
.replace(
|
||||
"{manage_webhooks}",
|
||||
if manage_webhooks { "✅" } else { "❌" },
|
||||
|
18
src/main.rs
18
src/main.rs
@ -44,6 +44,13 @@ use log::info;
|
||||
use crate::models::GuildData;
|
||||
use chrono_tz::Tz;
|
||||
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
struct PrefixCache;
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
impl TypeMapKey for PrefixCache {
|
||||
type Value = Arc<dashmap::DashMap<GuildId, String>>;
|
||||
}
|
||||
|
||||
struct SQLPool;
|
||||
|
||||
impl TypeMapKey for SQLPool {
|
||||
@ -165,6 +172,11 @@ DELETE FROM channels WHERE channel = ?
|
||||
.cloned()
|
||||
.expect("Could not get SQLPool from data");
|
||||
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
let prefix_cache = ctx.data.read().await.get::<PrefixCache>().cloned().unwrap();
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
prefix_cache.remove(&guild.id);
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM guilds WHERE guild = ?
|
||||
@ -262,6 +274,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
.expect("Error occurred creating client");
|
||||
|
||||
{
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
let prefix_cache = dashmap::DashMap::new();
|
||||
|
||||
let pool = MySqlPool::connect(
|
||||
&env::var("DATABASE_URL").expect("Missing DATABASE_URL from environment"),
|
||||
)
|
||||
@ -287,6 +302,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
|
||||
let mut data = client.data.write().await;
|
||||
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
data.insert::<PrefixCache>(Arc::new(prefix_cache));
|
||||
|
||||
data.insert::<SQLPool>(pool);
|
||||
data.insert::<PopularTimezones>(Arc::new(popular_timezones));
|
||||
data.insert::<ReqwestClient>(Arc::new(reqwest::Client::new()));
|
||||
|
@ -17,6 +17,12 @@ use log::error;
|
||||
|
||||
use crate::consts::{DEFAULT_PREFIX, LOCAL_LANGUAGE, LOCAL_TIMEZONE};
|
||||
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
use crate::PrefixCache;
|
||||
use crate::SQLPool;
|
||||
|
||||
use serenity::prelude::Context;
|
||||
|
||||
pub struct GuildData {
|
||||
pub id: u32,
|
||||
pub name: Option<String>,
|
||||
@ -24,10 +30,47 @@ pub struct GuildData {
|
||||
}
|
||||
|
||||
impl GuildData {
|
||||
#[cfg(feature = "prefix-cache")]
|
||||
pub async fn prefix_from_id<T: Into<GuildId>>(
|
||||
guild_id_opt: Option<T>,
|
||||
pool: &MySqlPool,
|
||||
ctx: &Context,
|
||||
) -> String {
|
||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||
let prefix_cache = ctx.data.read().await.get::<PrefixCache>().cloned().unwrap();
|
||||
|
||||
if let Some(guild_id) = guild_id_opt {
|
||||
let guild_id = guild_id.into();
|
||||
|
||||
if let Some(prefix) = prefix_cache.get(&guild_id) {
|
||||
prefix.to_string()
|
||||
} else {
|
||||
let row = sqlx::query!(
|
||||
"
|
||||
SELECT prefix FROM guilds WHERE guild = ?
|
||||
",
|
||||
guild_id.as_u64().to_owned()
|
||||
)
|
||||
.fetch_one(&pool)
|
||||
.await;
|
||||
|
||||
let prefix = row.map_or_else(|_| DEFAULT_PREFIX.clone(), |r| r.prefix);
|
||||
|
||||
prefix_cache.insert(guild_id, prefix.clone());
|
||||
|
||||
prefix
|
||||
}
|
||||
} else {
|
||||
DEFAULT_PREFIX.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "prefix-cache"))]
|
||||
pub async fn prefix_from_id<T: Into<GuildId>>(
|
||||
guild_id_opt: Option<T>,
|
||||
ctx: &Context,
|
||||
) -> String {
|
||||
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
|
||||
|
||||
if let Some(guild_id) = guild_id_opt {
|
||||
let guild_id = guild_id.into().as_u64().to_owned();
|
||||
|
||||
@ -37,7 +80,7 @@ SELECT prefix FROM guilds WHERE guild = ?
|
||||
",
|
||||
guild_id
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.fetch_one(&pool)
|
||||
.await;
|
||||
|
||||
row.map_or_else(|_| DEFAULT_PREFIX.clone(), |r| r.prefix)
|
||||
|
Loading…
Reference in New Issue
Block a user