Skip to content

Commit

Permalink
added env module
Browse files Browse the repository at this point in the history
  • Loading branch information
maxwai committed Dec 29, 2023
1 parent 312fd4c commit 867de07
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 126 deletions.
25 changes: 4 additions & 21 deletions src/bot/checks.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,8 @@
use once_cell::sync::Lazy;
use poise::serenity_prelude::{ChannelId, Permissions, RoleId};
use sqlx::{MySql, Pool};
use std::env;
use tracing::error;

use crate::bot::Context;
use crate::mysql_lib;

static MAIN_GUILD_ID: Lazy<Option<u64>> = Lazy::new(|| match env::var("MAIN_GUILD_ID") {
Ok(val) => match val.parse() {
Ok(val) => Some(val),
Err(err) => {
error!(error = err.to_string(), "Failed to parse int");
None
}
},
Err(_) => {
error!("No Main Guild ID given");
None
}
});
use crate::{env, mysql_lib};

/// Checks if the author has any of the specified roles
///
Expand Down Expand Up @@ -89,13 +72,13 @@ pub async fn is_owner(ctx: Context<'_>) -> bool {
///
/// Will return false when:
/// - guild is not main guild
/// - guild id env variable is not set
/// - guild id env variable can't be parsed to u64
/// - message was not sent in guild
#[allow(dead_code)]
pub async fn sent_in_main_guild(ctx: Context<'_>) -> bool {
if let Some(guild) = ctx.guild() {
return MAIN_GUILD_ID.map_or(false, |main_guild_id| guild.id.0 == main_guild_id);
return env::MAIN_GUILD_ID
.get()
.map_or(false, |&main_guild_id| guild.id.0 == main_guild_id);
}
false
}
Expand Down
32 changes: 13 additions & 19 deletions src/bot/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@

use std::env;
use std::time::Duration;

use poise::serenity_prelude as serenity;
use redis::Client;
use sqlx::{MySql, Pool};
use tracing::{error, info};
use tracing::info;

use crate::logging;
use crate::{env, logging};

mod commands;
mod checks;
mod commands;

/// User data, which is stored and accessible in all command invocations
#[derive(Debug)]
Expand All @@ -30,19 +28,9 @@ pub async fn entrypoint(database_pool: Pool<MySql>, redis_client: Client) {
info!("Starting the bot");

let db_clone = database_pool.clone();

let bot_token = match env::var("BOT_TOKEN") {
Ok(val) => val,
Err(_) => {
error!("No Bot Token given");
return;
}
};
let framework = poise::Framework::builder()
.options(poise::FrameworkOptions {
commands: vec![
commands::ping(),
],
commands: vec![commands::ping()],
allowed_mentions: Some({
let mut f = serenity::CreateAllowedMentions::default();
f.empty_parse()
Expand Down Expand Up @@ -70,20 +58,26 @@ pub async fn entrypoint(database_pool: Pool<MySql>, redis_client: Client) {
},
..Default::default()
})
.token(bot_token)
.token(env::BOT_TOKEN.get().unwrap())
.intents(
serenity::GatewayIntents::non_privileged() | serenity::GatewayIntents::MESSAGE_CONTENT,
)
.setup(|_ctx, ready, _framework| {
Box::pin(async move {
info!("Logged in as {}", ready.user.name);
Ok(Data { database_pool, redis_client })
Ok(Data {
database_pool,
redis_client,
})
})
});

let built_framework = framework.build().await.expect("Err building poise client");

logging::setup_discord_logging(built_framework.clone(), db_clone).await;

built_framework.start().await.expect("Err running poise client");
built_framework
.start()
.await
.expect("Err running poise client");
}
39 changes: 39 additions & 0 deletions src/env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::env;
use std::sync::OnceLock;

pub static MAIN_GUILD_ID: OnceLock<u64> = OnceLock::new();
pub static REDIS_PORT: OnceLock<u16> = OnceLock::new();
pub static REDIS_HOST: OnceLock<String> = OnceLock::new();
pub static MYSQL_PORT: OnceLock<u16> = OnceLock::new();
pub static MYSQL_HOST: OnceLock<String> = OnceLock::new();
pub static MYSQL_DATABASE: OnceLock<String> = OnceLock::new();
pub static MYSQL_USER: OnceLock<String> = OnceLock::new();
pub static MYSQL_PASSWORD: OnceLock<String> = OnceLock::new();
pub static BOT_TOKEN: OnceLock<String> = OnceLock::new();

pub fn init() {
MAIN_GUILD_ID.get_or_init(|| {
env::var("MAIN_GUILD_ID")
.expect("No Main Guild ID given")
.parse()
.expect("Failed to parse Main Guild ID to u64")
});
REDIS_PORT.get_or_init(|| {
env::var("REDIS_PORT")
.unwrap_or("6379".to_owned())
.parse()
.expect("Failed to parse Redis Port to u16")
});
REDIS_HOST.get_or_init(|| env::var("REDIS_HOST").unwrap_or("127.0.0.1".to_owned()));
MYSQL_PORT.get_or_init(|| {
env::var("MYSQL_PORT")
.unwrap_or("3306".to_owned())
.parse()
.expect("Failed to parse MySQL Port to u16")
});
MYSQL_HOST.get_or_init(|| env::var("MYSQL_HOST").unwrap_or("127.0.0.1".to_owned()));
MYSQL_DATABASE.get_or_init(|| env::var("MYSQL_DATABASE").expect("No database given"));
MYSQL_USER.get_or_init(|| env::var("MYSQL_USER").expect("No database username given"));
MYSQL_PASSWORD.get_or_init(|| env::var("MYSQL_PASSWORD").expect("No password for user given"));
BOT_TOKEN.get_or_init(|| env::var("BOT_TOKEN").expect("No Bot Token given"));
}
28 changes: 6 additions & 22 deletions src/logging.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,19 @@
use std::collections::HashMap;
use std::env;
use std::fs;
use std::num::NonZeroU64;
use std::sync::Arc;
use std::sync::OnceLock;
use std::sync::{Arc, OnceLock};

use poise::serenity_prelude::futures::executor::block_on;
use poise::serenity_prelude::{ChannelId, GuildId};
use rolling_file::RollingConditionBasic;
use sqlx::MySql;
use sqlx::Pool;
use tracing::error;
use tracing::info;
use tracing::Level;
use tracing::Subscriber;
use sqlx::{MySql, Pool};
use tracing::{error, info, Level, Subscriber};
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::filter;
use tracing_subscriber::fmt;
use tracing_subscriber::prelude::*;
use tracing_subscriber::reload;
use tracing_subscriber::reload::Handle;
use tracing_subscriber::Registry;
use tracing_subscriber::{filter, fmt, reload, Registry};

use crate::bot;
use crate::mysql_lib;
use crate::{bot, env, mysql_lib};

const LOG_FILE_MAX_SIZE_MB: u64 = 10;
const MAX_AMOUNT_LOG_FILES: usize = 10;
Expand Down Expand Up @@ -75,14 +65,8 @@ pub async fn setup_discord_logging(framework: Arc<bot::Framework>, db: Pool<MySq
let http = &framework.client().cache_and_http.http;

// Setup main logging guild/channel

let main_guild_id: u64 = env::var("MAIN_GUILD_ID")
.expect("No main logging guild id configured")
.parse()
.expect("Could not parse MAIN_GUILD_ID env variable");

let main_guild = http
.get_channels(main_guild_id)
.get_channels(*env::MAIN_GUILD_ID.get().unwrap())
.await
.expect("Could not get main guild");

Expand Down
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ mod bot;
mod mysql_lib;
mod redis_lib;
mod logging;
mod env;

#[tokio::main]
async fn main() {
env::init();
let _log_file_guard = logging::setup_logging().await;

info!("Starting hm-discord-bot");
Expand Down
49 changes: 7 additions & 42 deletions src/mysql_lib/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::env;

use poise::serenity_prelude::{ChannelId, GuildId, MessageId, RoleId, UserId};
use sqlx::migrate::MigrateError;
use sqlx::mysql::{MySqlConnectOptions, MySqlPoolOptions, MySqlRow};
use sqlx::types::time::{PrimitiveDateTime, Time};
use sqlx::{migrate, FromRow, MySql, Pool, Row};
use tracing::error;

use crate::env;

mod test;
pub mod validate;

Expand All @@ -21,50 +21,15 @@ pub mod validate;
/// * MYSQL_USER: the username of the user that has access to the database, needs to be present
/// * MYSQL_PASSWORD: the password of the user specified, needs to be present
pub async fn get_connection(max_concurrent_connections: u32) -> Option<Pool<MySql>> {
let sql_port = env::var("MYSQL_PORT").unwrap_or("3306".to_owned());
let sql_port = match sql_port.parse() {
Ok(val) => val,
Err(_) => {
error!("Could not parse MYSQL_PORT");
return None;
}
};

let sql_hostname = env::var("MYSQL_HOST").unwrap_or("127.0.0.1".to_owned());

let sql_database = match env::var("MYSQL_DATABASE") {
Ok(val) => val,
Err(_) => {
error!("No database given");
return None;
}
};

let sql_username = match env::var("MYSQL_USER") {
Ok(val) => val,
Err(_) => {
error!("No database username given");
return None;
}
};

let sql_password = match env::var("MYSQL_PASSWORD") {
Ok(val) => val,
Err(_) => {
error!("No password for user given");
return None;
}
};

match MySqlPoolOptions::new()
.max_connections(max_concurrent_connections)
.connect_with(
MySqlConnectOptions::new()
.host(sql_hostname.as_str())
.port(sql_port)
.database(sql_database.as_str())
.username(sql_username.as_str())
.password(sql_password.as_str()),
.host(env::MYSQL_HOST.get().unwrap().as_str())
.port(*env::MYSQL_PORT.get().unwrap())
.database(env::MYSQL_DATABASE.get().unwrap().as_str())
.username(env::MYSQL_USER.get().unwrap().as_str())
.password(env::MYSQL_PASSWORD.get().unwrap().as_str()),
)
.await
{
Expand Down
33 changes: 11 additions & 22 deletions src/redis_lib/mod.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,21 @@
use std::env;

use redis::{aio::Connection, AsyncCommands, Client};
use sha1::Digest;
use tracing::error;

use crate::env;

/// Tries to establish a connection with the given env variables and return the Redis client if
/// successful.
///
/// # Env Variables
///
/// * REDIS_PORT: the port of redis, defaults to 6379
/// * REDIS_HOST: the host of redis, ip or hostname or domain, defaults to 127.0.0.1
pub async fn get_connection() -> Option<Client> {
let redis_port: u16 = match env::var("REDIS_PORT").unwrap_or("6379".to_owned()).parse() {
Ok(val) => val,
Err(err) => {
error!(error = err.to_string(), "Failed to parse int");
return None;
}
};

let redis_hostname = env::var("REDIS_HOST").unwrap_or("127.0.0.1".to_owned());

let client = Client::open(format!("redis://{redis_hostname}:{redis_port}"))
.map_err(|e| {
error!(error = e.to_string(), "Problem creating redis client");
})
.ok()?;
let client = Client::open(format!(
"redis://{}:{}",
env::REDIS_HOST.get().unwrap(),
env::REDIS_PORT.get().unwrap()
))
.map_err(|e| {
error!(error = e.to_string(), "Problem creating redis client");
})
.ok()?;

match client.get_async_connection().await {
Err(err) => {
Expand Down

0 comments on commit 867de07

Please sign in to comment.