manifold/src/lib.rs

139 lines
4.7 KiB
Rust
Raw Normal View History

2021-11-12 12:05:26 +00:00
#[macro_use] extern crate log;
2021-11-12 13:56:05 +00:00
#[macro_use] extern crate serde;
2021-11-12 12:05:26 +00:00
use std::env;
use std::ops::Deref;
use std::path::PathBuf;
use std::sync::Arc;
2023-08-23 17:37:42 +00:00
2021-11-12 12:05:26 +00:00
use clap::ArgMatches;
2023-08-23 17:37:42 +00:00
use diesel::r2d2::ConnectionManager;
use diesel::sqlite::Sqlite;
2021-11-12 12:05:26 +00:00
use diesel::SqliteConnection;
2023-08-23 17:37:42 +00:00
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use poise::framework::FrameworkBuilder;
use poise::serenity_prelude::*;
2022-07-17 23:25:59 +00:00
2023-08-23 17:37:42 +00:00
use crate::config::ManifoldConfig;
use crate::error::{ManifoldError, ManifoldResult};
use crate::events::Handler;
use crate::models::user::{ManifoldUserInfo, UserInfo};
2021-11-12 12:05:26 +00:00
use crate::responses::Responses;
pub mod config;
pub mod error;
pub mod events;
2023-08-23 17:37:42 +00:00
pub mod responses;
pub mod commands;
pub mod models;
pub mod schema;
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");
2021-11-12 13:23:14 +00:00
// Retrieve build info from output file
pub mod built_info {
include!(concat!(env!("OUT_DIR"), "/built.rs"));
}
2023-08-23 17:37:42 +00:00
pub type ManifoldDatabasePool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
2021-11-12 12:05:26 +00:00
pub struct Db {
2021-11-12 22:28:51 +00:00
pub pool: ManifoldDatabasePool,
2021-11-12 12:05:26 +00:00
}
impl Deref for Db {
2021-11-12 22:22:20 +00:00
type Target = ManifoldDatabasePool;
2021-11-12 12:05:26 +00:00
fn deref(&self) -> &Self::Target { &self.pool }
}
2021-11-12 22:22:20 +00:00
pub struct ManifoldDatabase;
2021-11-12 12:05:26 +00:00
2023-08-23 17:37:42 +00:00
pub struct ManifoldData(pub Arc<ManifoldDataInner>);
impl Deref for ManifoldData {
type Target = ManifoldDataInner;
2021-11-12 12:05:26 +00:00
2023-08-23 17:37:42 +00:00
fn deref(&self) -> &Self::Target {
&self.0
}
2021-11-12 12:05:26 +00:00
}
2023-08-23 17:37:42 +00:00
pub struct ManifoldDataInner {
bot_config: ManifoldConfig,
database: Db,
responses: Responses,
user_info: Mutex<ManifoldUserInfo>,
2021-11-12 12:05:26 +00:00
}
2023-08-23 17:37:42 +00:00
pub type ManifoldContext<'a> = poise::Context<'a, ManifoldData, ManifoldError>;
pub type ManifoldCommand = poise::Command<ManifoldData, ManifoldError>;
2021-11-12 12:15:59 +00:00
2023-08-23 17:37:42 +00:00
pub async fn prepare_client(arguments: ArgMatches, intents: GatewayIntents, injected_commands: Vec<ManifoldCommand>) -> ManifoldResult<FrameworkBuilder<ManifoldData, ManifoldError>> {
let bot_environment = arguments.get_one("environment").unwrap();
let config_file = format!("config/{}", arguments.get_one::<String>("config-file").unwrap());
2021-11-12 12:05:26 +00:00
info!("Reading configuration...");
debug!("Configuration file path: {}", &config_file);
2023-08-23 17:37:42 +00:00
let config = ManifoldConfig::load_config(&config_file, bot_environment).expect(&*format!("Could not read configuration file {}", &config_file));
2021-11-12 12:05:26 +00:00
2022-07-17 23:25:59 +00:00
let prefix = config.get_value(&"BotPrefix".to_string()).expect("Could not read bot_prefix from config.");
2021-11-12 12:05:26 +00:00
let manager = ConnectionManager::<SqliteConnection>::new("manifold.db");
let pool = r2d2::Pool::builder()
.max_size(1)
.build(manager)
.expect("Database setup error!");
let mut responses = Responses::new();
2022-07-17 23:25:59 +00:00
responses.reload(&PathBuf::from(config.get_value(&"ResponsesFilePath".to_string()).unwrap_or("txt/responses.txt".to_string()))).expect("Could not load responses file!");
2021-11-12 12:05:26 +00:00
let token = env::var("DISCORD_TOKEN").expect(
"Could not find an environment variable called DISCORD_TOKEN",
);
2023-08-23 17:37:42 +00:00
let framework = poise::Framework::builder()
.options(poise::FrameworkOptions {
event_handler: |ctx, e, fctx, _| Box::pin(async move {
Handler::listen(ctx, fctx, e).await
}),
pre_command: |ctx: ManifoldContext<'_>| Box::pin(async move {
info!("Received command {} from {}", ctx.command().name, ctx.author().name);
let config = &ctx.data().bot_config;
let log_channel = config.get_channel(&"Log".to_string()).unwrap();
let _ = log_channel.say(ctx, format!("Received command {} from {}", ctx.command().name, ctx.author().name)).await;
}),
commands: commands::collect_commands(injected_commands),
prefix_options: poise::PrefixFrameworkOptions {
prefix: Some(prefix),
..Default::default()
},
..Default::default()
})
.token(token)
.intents(intents)
.setup(|ctx, _ready, framework| {
Box::pin(async move {
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
ctx.set_activity(Activity::watching("you")).await;
let db = Db { pool };
apply_migrations(&mut db.get()?);
let user_info = UserInfo::load(&db).expect("Could not load user info, rejecting");
Ok(ManifoldData(Arc::new(ManifoldDataInner {
bot_config: config,
database: db,
responses,
user_info: Mutex::new(user_info),
})))
})
});
Ok(framework)
2021-11-12 12:05:26 +00:00
}
2023-08-23 17:37:42 +00:00
fn apply_migrations(conn: &mut impl MigrationHarness<Sqlite>) {
2021-11-12 12:05:26 +00:00
2023-08-23 17:37:42 +00:00
conn.run_pending_migrations(MIGRATIONS)
.expect("An error occurred applying migrations.");
2021-11-12 12:05:26 +00:00
}