Allow caller-level injections for events and migrations

This commit is contained in:
Xyon 2023-09-24 23:54:16 +01:00
parent ec8447bc58
commit 3d712fdcb3
Signed by: xyon
GPG Key ID: DD18155D6B18078D
5 changed files with 33 additions and 23 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "manifold" name = "manifold"
version = "3.3.1" version = "4.0.0"
authors = ["Lucy Bladen <admin@lbladen.uk>"] authors = ["Lucy Bladen <admin@lbladen.uk>"]
edition = "2021" edition = "2021"

View File

@ -1,6 +1,6 @@
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use poise::{Event, FrameworkContext}; use poise::{async_trait, Event, FrameworkContext};
use poise::serenity_prelude::model::{ use poise::serenity_prelude::model::{
gateway::Ready, gateway::Ready,
}; };
@ -9,20 +9,20 @@ use crate::ManifoldData;
use crate::error::{ManifoldError, ManifoldResult}; use crate::error::{ManifoldError, ManifoldResult};
use crate::models::user::UserInfo; use crate::models::user::UserInfo;
#[async_trait]
pub trait EventHandler {
async fn listen(ctx: &Context, framework_ctx: FrameworkContext<'_, ManifoldData, ManifoldError>, event: &Event<'_>) -> ManifoldResult<()>;
}
pub struct Handler { pub struct Handler {
pub timer_running: AtomicBool, pub timer_running: AtomicBool,
} }
impl Handler { #[async_trait]
pub fn new() -> Self { impl EventHandler for Handler {
Handler { async fn listen(ctx: &Context, framework_ctx: FrameworkContext<'_, ManifoldData, ManifoldError>, event: &Event<'_>) -> ManifoldResult<()> {
timer_running: AtomicBool::from(false)
}
}
pub async fn listen(ctx: &Context, framework_ctx: FrameworkContext<'_, ManifoldData, ManifoldError>, event: &Event<'_>) -> ManifoldResult<()> {
match event { match event {
Event::Ready { data_about_bot} => Handler::standard_startup(&ctx, &framework_ctx, data_about_bot).await, Event::Ready { data_about_bot } => Handler::standard_startup(&ctx, &framework_ctx, data_about_bot).await,
Event::GuildBanAddition { guild_id, banned_user } => Handler::ban_add(&ctx, &framework_ctx, guild_id, banned_user).await, Event::GuildBanAddition { guild_id, banned_user } => Handler::ban_add(&ctx, &framework_ctx, guild_id, banned_user).await,
Event::GuildBanRemoval { guild_id, unbanned_user } => Handler::ban_remove(&ctx, &framework_ctx, guild_id, unbanned_user).await, Event::GuildBanRemoval { guild_id, unbanned_user } => Handler::ban_remove(&ctx, &framework_ctx, guild_id, unbanned_user).await,
Event::GuildMemberAddition { new_member } => Handler::new_member(&ctx, &framework_ctx, &new_member).await, Event::GuildMemberAddition { new_member } => Handler::new_member(&ctx, &framework_ctx, &new_member).await,
@ -37,6 +37,15 @@ impl Handler {
_ => Ok(()) _ => Ok(())
} }
} }
}
impl Handler {
pub fn new() -> Self {
Handler {
timer_running: AtomicBool::from(false)
}
}
pub async fn standard_startup(ctx: &Context, framework_ctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, data_about_bot: &Ready) -> ManifoldResult<()> { pub async fn standard_startup(ctx: &Context, framework_ctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, data_about_bot: &Ready) -> ManifoldResult<()> {
let config = &framework_ctx.user_data().await.bot_config; let config = &framework_ctx.user_data().await.bot_config;

View File

@ -16,7 +16,7 @@ use poise::serenity_prelude::*;
use crate::config::ManifoldConfig; use crate::config::ManifoldConfig;
use crate::error::{ManifoldError, ManifoldResult}; use crate::error::{ManifoldError, ManifoldResult};
use crate::events::Handler; use crate::events::EventHandler;
use crate::models::user::{ManifoldUserInfo, UserInfo}; use crate::models::user::{ManifoldUserInfo, UserInfo};
use crate::responses::Responses; use crate::responses::Responses;
@ -61,17 +61,17 @@ impl Deref for ManifoldData {
} }
pub struct ManifoldDataInner { pub struct ManifoldDataInner {
bot_config: ManifoldConfig, pub bot_config: ManifoldConfig,
database: Db, pub database: Db,
responses: Responses, pub responses: Responses,
user_info: Mutex<ManifoldUserInfo>, pub user_info: Mutex<ManifoldUserInfo>,
version_string: String, pub version_string: String,
} }
pub type ManifoldContext<'a> = poise::Context<'a, ManifoldData, ManifoldError>; pub type ManifoldContext<'a> = poise::Context<'a, ManifoldData, ManifoldError>;
pub type ManifoldCommand = poise::Command<ManifoldData, ManifoldError>; pub type ManifoldCommand = poise::Command<ManifoldData, ManifoldError>;
pub async fn prepare_client(arguments: ArgMatches, intents: GatewayIntents, injected_commands: Vec<ManifoldCommand>, caller_version_string: String) -> ManifoldResult<FrameworkBuilder<ManifoldData, ManifoldError>> { pub async fn prepare_client<T: EventHandler>(arguments: ArgMatches, intents: GatewayIntents, injected_commands: Vec<ManifoldCommand>, caller_version_string: String, caller_database_migrations: EmbeddedMigrations) -> ManifoldResult<FrameworkBuilder<ManifoldData, ManifoldError>> {
let bot_environment = arguments.get_one("environment").unwrap(); let bot_environment = arguments.get_one("environment").unwrap();
let config_file = arguments.get_one::<String>("config-file").unwrap(); let config_file = arguments.get_one::<String>("config-file").unwrap();
@ -95,7 +95,7 @@ pub async fn prepare_client(arguments: ArgMatches, intents: GatewayIntents, inje
let framework = poise::Framework::builder() let framework = poise::Framework::builder()
.options(poise::FrameworkOptions { .options(poise::FrameworkOptions {
event_handler: |ctx, e, fctx, _| Box::pin(async move { event_handler: |ctx, e, fctx, _| Box::pin(async move {
Handler::listen(ctx, fctx, e).await T::listen(ctx, fctx, e).await
}), }),
pre_command: |ctx: ManifoldContext<'_>| Box::pin(async move { pre_command: |ctx: ManifoldContext<'_>| Box::pin(async move {
info!("Received command {} from {}", ctx.command().name, ctx.author().name); info!("Received command {} from {}", ctx.command().name, ctx.author().name);
@ -116,7 +116,7 @@ pub async fn prepare_client(arguments: ArgMatches, intents: GatewayIntents, inje
ctx.set_activity(Activity::watching("you")).await; ctx.set_activity(Activity::watching("you")).await;
ctx.cache.set_max_messages(350); ctx.cache.set_max_messages(350);
let db = Db { pool }; let db = Db { pool };
apply_migrations(&mut db.get()?); apply_migrations(&mut db.get()?, caller_database_migrations);
let user_info = UserInfo::load(&db).expect("Could not load user info, rejecting"); let user_info = UserInfo::load(&db).expect("Could not load user info, rejecting");
let git_info: String = built_info::GIT_VERSION.unwrap_or("unknown").to_string(); let git_info: String = built_info::GIT_VERSION.unwrap_or("unknown").to_string();
@ -133,8 +133,10 @@ pub async fn prepare_client(arguments: ArgMatches, intents: GatewayIntents, inje
Ok(framework) Ok(framework)
} }
fn apply_migrations(conn: &mut impl MigrationHarness<Sqlite>) { fn apply_migrations(conn: &mut impl MigrationHarness<Sqlite>, caller_migrations: EmbeddedMigrations) {
conn.run_pending_migrations(MIGRATIONS) conn.run_pending_migrations(MIGRATIONS)
.expect("An error occurred applying migrations."); .expect("An error occurred applying migrations.");
conn.run_pending_migrations(caller_migrations)
.expect("An error occurred applying caller migrations");
} }

View File

@ -2,7 +2,6 @@ use std::env::temp_dir;
use std::fmt::Debug; use std::fmt::Debug;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use dirs::home_dir;
use std::io::{SeekFrom, Seek}; use std::io::{SeekFrom, Seek};
use reqwest::Client; use reqwest::Client;
use reqwest::header::{ACCEPT, CONTENT_TYPE}; use reqwest::header::{ACCEPT, CONTENT_TYPE};

View File

@ -7,7 +7,7 @@ use crate::schema::userinfo::dsl as userinfo_dsl;
use crate::Db; use crate::Db;
use crate::error::{ManifoldError, ManifoldResult}; use crate::error::{ManifoldError, ManifoldResult};
#[derive(Identifiable, Insertable, AsChangeset, Debug, Queryable, Serialize, Clone)] #[derive(Identifiable, Insertable, AsChangeset, Selectable, Debug, Queryable, Serialize, Clone)]
#[diesel(primary_key(user_id))] #[diesel(primary_key(user_id))]
#[diesel(table_name = userinfo)] #[diesel(table_name = userinfo)]
pub struct UserInfo { pub struct UserInfo {