Public Access
improve calculator, improve logging, fix auto role
This commit is contained in:
1 parent
24205326bf
commit
afa64fd55b
6 files changed
+94
-23
No files matched your search
@@ -14,6 +14,7 @@ dotenv = "0.15.0"
|
|||||||
exmex = "0.21.0"
|
exmex = "0.21.0"
|
||||||
f128 = "0.2.9"
|
f128 = "0.2.9"
|
||||||
f256 = "0.11.2"
|
f256 = "0.11.2"
|
||||||
|
num-bigint = "0.5.1"
|
||||||
num-traits = "0.2.19"
|
num-traits = "0.2.19"
|
||||||
poise = "0.6.2"
|
poise = "0.6.2"
|
||||||
regex = "1.12.4"
|
regex = "1.12.4"
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE auto_roles ADD CONSTRAINT auto_roles_guild_id_key UNIQUE (guild_id);
|
||||||
+85
-17
@@ -1,12 +1,12 @@
|
|||||||
use crate::{Context, Error};
|
use crate::{Context, Error};
|
||||||
use tracing::{debug, trace, info};
|
use tracing::{debug, trace, warn};
|
||||||
use crate::shared_functions::trace_message;
|
use crate::shared_functions::trace_message;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use f128::f128;
|
use f128::f128;
|
||||||
use exmex::{Express, FlatEx, MakeOperators, Operator, BinOp};
|
use exmex::{Express, MakeOperators, Operator, BinOp};
|
||||||
use num_traits::float::Float;
|
use num_traits::float::Float;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@@ -142,22 +142,27 @@ pub async fn calc(ctx: Context<'_>,
|
|||||||
let response_message = ctx.say(msg).await?;
|
let response_message = ctx.say(msg).await?;
|
||||||
let start_time = std::time::Instant::now();
|
let start_time = std::time::Instant::now();
|
||||||
trace!("Saving start time: {:?}", start_time);
|
trace!("Saving start time: {:?}", start_time);
|
||||||
let processed_expr = FIND_SCI_NOTATION_RE.replace_all(&expression, "($1 * 10^($2))");
|
if expression.contains('=') {
|
||||||
|
let error_msg = format!("Invalid expression: {}\nYou are not allowed to have an equal sign in the expression.", expression);
|
||||||
|
debug!("Invalid expression detected: {}", expression);
|
||||||
|
trace_message(error_msg.clone(), ctx.channel_id().to_string(), ctx.guild_id().unwrap().to_string()).await;
|
||||||
|
edit_response_message(&response_message, ctx, error_msg, false).await?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let processed_expr : String = FIND_SCI_NOTATION_RE.replace_all(&expression, "$1 * 10^($2)").to_string();
|
||||||
trace!("Processed expression: {}", processed_expr);
|
trace!("Processed expression: {}", processed_expr);
|
||||||
|
|
||||||
let value = match precision {
|
let value = match evaluate_expression(processed_expr, &precision) {
|
||||||
Some(Precision::Bits32) => exmex::eval_str::<f32>(&processed_expr).map_err(|err| err.to_string())?.to_string(),
|
Ok(v) => v,
|
||||||
Some(Precision::Bits64) => exmex::eval_str::<f64>(&processed_expr).map_err(|err| err.to_string())?.to_string(),
|
Err(err_msg) => {
|
||||||
Some(Precision::Bits128) => {
|
let error_msg = format!("Failed to parse or evaluate expression: `{}`", err_msg);
|
||||||
let expr = exmex::FlatEx::<F128, F128OpsFactory>::parse(&processed_expr).map_err(|err| err.to_string())?;
|
warn!("Failed to parse or evaluate expression: `{}` in guild {} channel {} by {}", err_msg, ctx.guild_id().unwrap().get(), ctx.channel_id().get(), ctx.author().name);
|
||||||
expr.eval(&[]).map_err(|err| err.to_string())?.to_string()
|
trace_message(error_msg.clone(), ctx.channel_id().to_string(), ctx.guild_id().unwrap().to_string()).await;
|
||||||
},
|
edit_response_message(&response_message, ctx, error_msg, false).await?;
|
||||||
Some(Precision::Bits256) => {
|
return Ok(());
|
||||||
let expr = exmex::FlatEx::<f256::f256, F256OpsFactory>::parse(&processed_expr).map_err(|err| err.to_string())?;
|
}
|
||||||
expr.eval(&[]).map_err(|err| err.to_string())?.to_string()
|
|
||||||
},
|
|
||||||
None => exmex::eval_str::<f64>(&processed_expr).map_err(|err| err.to_string())?.to_string(),
|
|
||||||
};
|
};
|
||||||
|
trace!("Result: {}", value);
|
||||||
let end_time = std::time::Instant::now();
|
let end_time = std::time::Instant::now();
|
||||||
trace!("Saving end time: {:?}", end_time);
|
trace!("Saving end time: {:?}", end_time);
|
||||||
let duration = end_time - start_time;
|
let duration = end_time - start_time;
|
||||||
@@ -169,10 +174,17 @@ pub async fn calc(ctx: Context<'_>,
|
|||||||
Some(Precision::Bits256) => "256-bit".to_string(),
|
Some(Precision::Bits256) => "256-bit".to_string(),
|
||||||
None => "64-bit".to_string(),
|
None => "64-bit".to_string(),
|
||||||
};
|
};
|
||||||
let msg = format!("{} = {} \n-# Precision: {} Compute time : {:?}", expression, value, precision_str, duration);
|
// Turn to scientifc notation if number has more than 30 digits
|
||||||
|
let value_string = if value.len() > 30 {
|
||||||
|
to_scientific_notation(value)
|
||||||
|
} else {
|
||||||
|
value
|
||||||
|
};
|
||||||
|
|
||||||
|
let msg = format!("{} = {} \n-# Precision: {} Compute time : {:?}", expression, value_string, precision_str, duration);
|
||||||
trace_message(msg.clone(), ctx.channel_id().to_string(), ctx.guild_id().unwrap().to_string()).await;
|
trace_message(msg.clone(), ctx.channel_id().to_string(), ctx.guild_id().unwrap().to_string()).await;
|
||||||
edit_response_message(&response_message, ctx, msg, false).await?;
|
edit_response_message(&response_message, ctx, msg, false).await?;
|
||||||
debug!("Calculation perfomed for {} with result {} in {:?} by {}", expression, value, duration, ctx.author().name);
|
debug!("Calculation perfomed for {} with result {} in {:?} by {}", expression, value_string, duration, ctx.author().name);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,3 +196,59 @@ async fn edit_response_message<'a>(response_message: &poise::ReplyHandle<'a>, ct
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_scientific_notation(value: String) -> String {
|
||||||
|
trace!("Converting {} to scientific notation", value);
|
||||||
|
if value.contains('e') || value.contains('E') {
|
||||||
|
trace!("Already in scientific notation");
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut is_negative = false;
|
||||||
|
let mut val_str = value.as_str();
|
||||||
|
if val_str.starts_with('-') {
|
||||||
|
is_negative = true;
|
||||||
|
val_str = &val_str[1..];
|
||||||
|
}
|
||||||
|
|
||||||
|
let parts: Vec<&str> = val_str.split('.').collect();
|
||||||
|
let integer_part = parts[0];
|
||||||
|
let fractional_part = if parts.len() > 1 { parts[1] } else { "" };
|
||||||
|
|
||||||
|
if integer_part.len() <= 1 {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
let first_digit = &integer_part[0..1];
|
||||||
|
let rest_integer = &integer_part[1..];
|
||||||
|
let exponent = integer_part.len() - 1;
|
||||||
|
|
||||||
|
let mut fractional_combined = format!("{}{}", rest_integer, fractional_part);
|
||||||
|
fractional_combined = fractional_combined.trim_end_matches('0').to_string();
|
||||||
|
|
||||||
|
let sign = if is_negative { "-" } else { "" };
|
||||||
|
|
||||||
|
if fractional_combined.is_empty() {
|
||||||
|
format!("{}{}e{}", sign, first_digit, exponent)
|
||||||
|
} else {
|
||||||
|
format!("{}{}.{}e{}", sign, first_digit, fractional_combined, exponent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn evaluate_expression(expr: String, precision: &Option<Precision>) -> Result<String, String> {
|
||||||
|
let value = match precision {
|
||||||
|
Some(Precision::Bits32) => exmex::eval_str::<f32>(&expr).map_err(|err| err.to_string())?.to_string(),
|
||||||
|
Some(Precision::Bits64) => exmex::eval_str::<f64>(&expr).map_err(|err| err.to_string())?.to_string(),
|
||||||
|
Some(Precision::Bits128) => {
|
||||||
|
let parsed_expr = exmex::FlatEx::<F128, F128OpsFactory>::parse(&expr).map_err(|err| err.to_string())?;
|
||||||
|
parsed_expr.eval(&[]).map_err(|err| err.to_string())?.to_string()
|
||||||
|
},
|
||||||
|
Some(Precision::Bits256) => {
|
||||||
|
let parsed_expr = exmex::FlatEx::<f256::f256, F256OpsFactory>::parse(&expr).map_err(|err| err.to_string())?;
|
||||||
|
parsed_expr.eval(&[]).map_err(|err| err.to_string())?.to_string()
|
||||||
|
},
|
||||||
|
None => exmex::eval_str::<f64>(&expr).map_err(|err| err.to_string())?.to_string(),
|
||||||
|
};
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::{Context, Error};
|
use crate::{Context, Error};
|
||||||
use crate::shared_functions::get_all_admin_users;
|
use crate::shared_functions::get_all_admin_users;
|
||||||
use poise::serenity_prelude as sere;
|
use poise::serenity_prelude as sere;
|
||||||
use tracing::{error, warn, info, debug, trace};
|
use tracing::{error, info, debug, trace};
|
||||||
|
|
||||||
#[derive(Debug, poise::ChoiceParameter)]
|
#[derive(Debug, poise::ChoiceParameter)]
|
||||||
pub enum AdminOperationType {
|
pub enum AdminOperationType {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::{Context, Error};
|
use crate::{Context, Error};
|
||||||
use crate::shared_functions::get_all_admin_users;
|
use crate::shared_functions::get_all_admin_users;
|
||||||
use poise::serenity_prelude as sere;
|
use poise::serenity_prelude as sere;
|
||||||
use tracing::{error, warn, info, debug, trace};
|
use tracing::{error, info, debug, trace};
|
||||||
|
|
||||||
#[derive(Debug, poise::ChoiceParameter)]
|
#[derive(Debug, poise::ChoiceParameter)]
|
||||||
pub enum AutoRoleOperationType {
|
pub enum AutoRoleOperationType {
|
||||||
@@ -97,7 +97,7 @@ async fn enable_auto_role(ctx: Context<'_>, response_message: &poise::ReplyHandl
|
|||||||
let query = sqlx::query!("UPDATE auto_roles SET enabled = true WHERE guild_id = $1 AND role_id = $2;", ctx.guild_id().unwrap().get() as i64, role.id.get() as i64).execute(&ctx.data().pool).await;
|
let query = sqlx::query!("UPDATE auto_roles SET enabled = true WHERE guild_id = $1 AND role_id = $2;", ctx.guild_id().unwrap().get() as i64, role.id.get() as i64).execute(&ctx.data().pool).await;
|
||||||
match query {
|
match query {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
info!("Enabled auto role {} in guild {}", role.name, ctx.guild_id().unwrap().get());
|
debug!("Enabled auto role {} in guild {}", role.name, ctx.guild_id().unwrap().get());
|
||||||
edit_response_message(response_message, ctx, format!("Enabled auto role: <@&{}>", role.id.get()), false).await?;
|
edit_response_message(response_message, ctx, format!("Enabled auto role: <@&{}>", role.id.get()), false).await?;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -137,7 +137,7 @@ async fn set_auto_role(ctx: Context<'_>, response_message: &poise::ReplyHandle<'
|
|||||||
let query = sqlx::query!("INSERT INTO auto_roles (guild_id, role_id, enabled) VALUES ($1, $2, false) ON CONFLICT (guild_id) DO UPDATE SET role_id = $2;", ctx.guild_id().unwrap().get() as i64, role.id.get() as i64).execute(&ctx.data().pool).await;
|
let query = sqlx::query!("INSERT INTO auto_roles (guild_id, role_id, enabled) VALUES ($1, $2, false) ON CONFLICT (guild_id) DO UPDATE SET role_id = $2;", ctx.guild_id().unwrap().get() as i64, role.id.get() as i64).execute(&ctx.data().pool).await;
|
||||||
match query {
|
match query {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
info!("Set {} as auto role in guild {}", role.name, ctx.guild_id().unwrap().get());
|
debug!("Set {} as auto role in guild {}", role.name, ctx.guild_id().unwrap().get());
|
||||||
edit_response_message(response_message, ctx, format!("Set {} as auto role", role.name), false).await?;
|
edit_response_message(response_message, ctx, format!("Set {} as auto role", role.name), false).await?;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -165,7 +165,7 @@ async fn disable_auto_role(ctx: Context<'_>, response_message: &poise::ReplyHand
|
|||||||
let query = sqlx::query!("UPDATE auto_roles SET enabled = false WHERE guild_id = $1 AND role_id = $2;", ctx.guild_id().unwrap().get() as i64, role.id.get() as i64).execute(&ctx.data().pool).await;
|
let query = sqlx::query!("UPDATE auto_roles SET enabled = false WHERE guild_id = $1 AND role_id = $2;", ctx.guild_id().unwrap().get() as i64, role.id.get() as i64).execute(&ctx.data().pool).await;
|
||||||
match query {
|
match query {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
info!("Disabled auto role {} in guild {}", role.name, ctx.guild_id().unwrap().get());
|
debug!("Disabled auto role {} in guild {}", role.name, ctx.guild_id().unwrap().get());
|
||||||
edit_response_message(response_message, ctx, format!("Disabled auto role: {}", role.name), false).await?;
|
edit_response_message(response_message, ctx, format!("Disabled auto role: {}", role.name), false).await?;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use poise::serenity_prelude as sere;
|
use poise::serenity_prelude as sere;
|
||||||
use tracing::{error, warn, info, debug, trace};
|
use tracing::{error, debug, trace};
|
||||||
|
|
||||||
pub async fn user_join(ctx: &sere::Context, new_member: &sere::Member, pool: &sqlx::PgPool) {
|
pub async fn user_join(ctx: &sere::Context, new_member: &sere::Member, pool: &sqlx::PgPool) {
|
||||||
trace!("User joined event handler called for guild {}", new_member.guild_id);
|
trace!("User joined event handler called for guild {}", new_member.guild_id);
|
||||||
@@ -35,6 +35,7 @@ pub async fn user_join(ctx: &sere::Context, new_member: &sere::Member, pool: &sq
|
|||||||
async fn give_role_to_user(ctx: &sere::Context, member: &sere::Member, role_id: u64) {
|
async fn give_role_to_user(ctx: &sere::Context, member: &sere::Member, role_id: u64) {
|
||||||
if let Err(e) = member.add_role(&ctx.http, sere::RoleId::new(role_id)).await {
|
if let Err(e) = member.add_role(&ctx.http, sere::RoleId::new(role_id)).await {
|
||||||
error!("Error adding role to member: {:?}", e);
|
error!("Error adding role to member: {:?}", e);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
debug!("Role {} added to user {} in guild {}", role_id, member.user.name, member.guild_id);
|
debug!("Role {} added to user {} in guild {}", role_id, member.user.name, member.guild_id);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user