FrenBot/src/config.rs
2024-05-28 20:53:05 -06:00

145 lines
3.4 KiB
Rust

use crate::album_manager::AlbumManager;
use crate::error::Error;
use crate::migrations::{CURRENT_DB_VERSION, do_migration};
use crate::rass::RaaSHandler;
use config::{Config, File};
use j_db::database::Database;
use reqwest::Url;
use serde::{Deserialize, Serialize};
use serenity::model::id::ChannelId;
use serenity::model::prelude::{GuildId, UserId};
use serenity::prelude::TypeMapKey;
use std::net::SocketAddr;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use j_db::metadata::DBMetadata;
use structopt::StructOpt;
use tokio::sync::mpsc::{channel, Receiver, Sender};
use tokio::sync::Mutex;
#[derive(Debug, StructOpt)]
#[structopt(name = "fren", about = "Friend Bot")]
pub struct Args {
pub cfg_path: PathBuf,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PicOxConfig {
api_base_url: Url,
token: String,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct BotConfig {
pub bot_token: String,
pub img_path: PathBuf,
pub base_url: Url,
pub story_path: PathBuf,
pub voice_path: PathBuf,
pub nft_path: PathBuf,
pub db_path: PathBuf,
pub admins: Vec<UserId>,
pub guild_id: GuildId,
pub api_addr: SocketAddr,
pub announcement_channel: ChannelId,
pub toys: Vec<String>,
pub effect_role_duration: i64,
pub picox: PicOxConfig,
}
impl BotConfig {
pub fn new(config_path: &Path) -> Result<Self, config::ConfigError> {
let cfg = Config::builder()
.add_source(File::from(config_path))
.build()?;
cfg.try_deserialize()
}
}
#[derive(Debug)]
pub struct BotState {
pub accepted_nsfw: Option<UserId>,
pub bad_apple_running: bool,
pub speak_lock: Mutex<()>,
pub raas_handler: Option<RaaSHandler>,
}
impl BotState {
pub async fn new() -> Result<Self, Error> {
Ok(Self {
accepted_nsfw: None,
bad_apple_running: false,
speak_lock: Mutex::new(()),
raas_handler: None,
})
}
}
pub struct GlobalData {
pub args: Args,
pub cfg: BotConfig,
pub bot_state: BotState,
pub db: Database,
pub picox: AlbumManager,
}
impl GlobalData {
pub async fn new(args: Args, cfg: BotConfig) -> Result<Self, Error> {
let db = Database::new(&cfg.db_path)?;
let version = db.version()?;
if version == 0 {
db.insert::<j_db::metadata::DBMetadata>( DBMetadata {
id: None,
version: CURRENT_DB_VERSION,
}).unwrap();
}
do_migration(&db);
Ok(Self {
args,
bot_state: BotState::new().await?,
db,
cfg: cfg.clone(),
picox: AlbumManager::new(cfg.picox.api_base_url, &cfg.picox.token),
})
}
pub async fn reload(&mut self) -> Result<(), Error> {
let cfg = BotConfig::new(&self.args.cfg_path)?;
self.cfg = cfg;
self.bot_state = BotState::new().await?;
Ok(())
}
}
impl TypeMapKey for GlobalData {
type Value = GlobalData;
}
#[derive(Debug, Clone)]
pub struct Channel<T> {
pub recv: Arc<Mutex<Receiver<T>>>,
pub send: Arc<Mutex<Sender<T>>>,
}
impl<T> Channel<T> {
pub fn new() -> Self {
let (send, recv) = channel::<T>(10);
Self {
recv: Arc::new(Mutex::new(recv)),
send: Arc::new(Mutex::new(send)),
}
}
}
impl<T: 'static + Send + Sync> TypeMapKey for Channel<T> {
type Value = Channel<T>;
}