feat: handle saving config better
This commit is contained in:
parent
ba8f175e8f
commit
ff0fd083c8
33
src/app.rs
33
src/app.rs
|
@ -9,6 +9,7 @@ pub mod web;
|
|||
|
||||
use anyhow::Result;
|
||||
use cached::{TimedCache, Cached};
|
||||
use chrono::Duration;
|
||||
use futures::{StreamExt, SinkExt};
|
||||
use irc::client::prelude::Client as IrcClient;
|
||||
use rhai::Engine;
|
||||
|
@ -40,13 +41,13 @@ use crate::app::{
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
ops::{Deref, DerefMut},
|
||||
path::Path,
|
||||
sync::{
|
||||
Arc,
|
||||
atomic::AtomicBool,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
},
|
||||
time::Instant,
|
||||
};
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
pub struct State {
|
||||
pub user_config: UserConfig,
|
||||
|
@ -77,15 +78,15 @@ impl State {
|
|||
pub async fn new(runtime: Handle, user_config: UserConfig, mut config: Config) -> Result<Arc<Self>> {
|
||||
let http_client = reqwest::Client::new();
|
||||
|
||||
println!("Verifying bot token");
|
||||
println!("verifying bot token");
|
||||
verify_token(&mut config.bot_token, &user_config, &http_client, vec![
|
||||
// IRC
|
||||
Scope::ChatRead,
|
||||
Scope::ChatEdit,
|
||||
]).await?;
|
||||
println!("Bot token ready");
|
||||
println!("bot token ready");
|
||||
|
||||
println!("Verifying user token");
|
||||
println!("verifying user token");
|
||||
verify_token(&mut config.user_token, &user_config, &http_client, vec![
|
||||
// Channel points redemptions
|
||||
Scope::ChannelReadRedemptions,
|
||||
|
@ -96,7 +97,7 @@ impl State {
|
|||
Scope::ModerationRead,
|
||||
Scope::ModeratorManageAutoMod,
|
||||
]).await?;
|
||||
println!("User token ready");
|
||||
println!("user token ready");
|
||||
|
||||
let config = Arc::new(RwLock::new(config));
|
||||
|
||||
|
@ -104,13 +105,29 @@ impl State {
|
|||
let twitch_config = Arc::clone(&config);
|
||||
let twitch = Arc::new(Twitch::new(twitch_client, twitch_config));
|
||||
|
||||
println!("getting channel name");
|
||||
let user_id = UserId::new(user_config.twitch.channel_id.to_string());
|
||||
let channel_name = twitch.client.helix.get_user_from_id(user_id, &twitch.bot_token().await?)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow::anyhow!("no channel for id {}", user_config.twitch.channel_id))?
|
||||
.login
|
||||
.to_string();
|
||||
println!("configured to run for channel: {}", channel_name);
|
||||
|
||||
println!("starting periodic config save task");
|
||||
let task_config = Arc::clone(&config);
|
||||
tokio::task::spawn(async move {
|
||||
loop {
|
||||
println!("saving config");
|
||||
if let Err(e) = crate::save_config(Path::new("data.json"), &*task_config.read().await).await {
|
||||
eprintln!("could not save config: {:?}", e);
|
||||
}
|
||||
|
||||
tokio::time::sleep(Duration::minutes(5).to_std().unwrap()).await;
|
||||
}
|
||||
});
|
||||
|
||||
println!("connecting to irc");
|
||||
let mut irc = self::twitch_irc::connect(&twitch).await?;
|
||||
let mut irc_stream = irc.stream()?;
|
||||
|
||||
|
@ -182,6 +199,7 @@ impl State {
|
|||
)?;
|
||||
let task_state = Arc::clone(&state);
|
||||
tokio::task::spawn(async move {
|
||||
println!("starting pubsub listener");
|
||||
let res: Result<()> = try {
|
||||
let (ws, _) = tokio_tungstenite::connect_async("wss://pubsub-edge.twitch.tv").await?;
|
||||
let (mut write, mut read) = ws.split();
|
||||
|
@ -213,6 +231,7 @@ impl State {
|
|||
// start irc task
|
||||
let task_state = Arc::clone(&state);
|
||||
tokio::task::spawn(async move {
|
||||
println!("listening for irc events");
|
||||
loop {
|
||||
while let Some(event) = irc_stream.next().await.transpose().unwrap_or_default() {
|
||||
let task_state = Arc::clone(&task_state);
|
||||
|
@ -259,6 +278,8 @@ impl State {
|
|||
let task_state = Arc::clone(&state);
|
||||
self::task::stream_status::start_task(task_state).await;
|
||||
|
||||
println!("initialised");
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ use std::{
|
|||
};
|
||||
|
||||
pub async fn start_web(state: Arc<State>) {
|
||||
println!("starting web server");
|
||||
let cookie_state = Arc::clone(&state);
|
||||
let authed = warp::cookie("access_token")
|
||||
.or(warp::header("x-api-key"))
|
||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -13,10 +13,7 @@ use crate::app::{
|
|||
config::Config,
|
||||
user_config::UserConfig,
|
||||
};
|
||||
use std::{
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
};
|
||||
use std::path::Path;
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let runtime = Builder::new_multi_thread()
|
||||
|
@ -28,10 +25,12 @@ fn main() -> anyhow::Result<()> {
|
|||
}
|
||||
|
||||
async fn inner(runtime: Handle) -> anyhow::Result<()> {
|
||||
println!("reading config");
|
||||
let mut uc_toml = String::new();
|
||||
tokio::fs::File::open("config.toml").await?.read_to_string(&mut uc_toml).await?;
|
||||
let user_config: UserConfig = toml::from_str(&uc_toml)?;
|
||||
|
||||
println!("reading data");
|
||||
let c_path = Path::new("data.json");
|
||||
let config: Config = if c_path.exists() {
|
||||
let mut c_json = String::new();
|
||||
|
@ -41,23 +40,31 @@ async fn inner(runtime: Handle) -> anyhow::Result<()> {
|
|||
Config::default()
|
||||
};
|
||||
|
||||
println!("starting bot");
|
||||
let state = State::new(runtime, user_config, config).await?;
|
||||
save_config(c_path, Arc::clone(&state)).await?;
|
||||
save_config(c_path, &*state.config.read().await).await?;
|
||||
|
||||
tokio::signal::ctrl_c()
|
||||
.then(|_| save_config(c_path, Arc::clone(&state)))
|
||||
.then(|_| async {
|
||||
println!("received ctrl-c");
|
||||
println!("saving config");
|
||||
save_config(c_path, &*state.config.read().await).await?;
|
||||
Result::<(), anyhow::Error>::Ok(())
|
||||
})
|
||||
.await?;
|
||||
|
||||
println!("exiting");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn save_config(path: &Path, state: Arc<State>) -> anyhow::Result<()> {
|
||||
pub async fn save_config(path: &Path, config: &Config) -> anyhow::Result<()> {
|
||||
let mut config_file = OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.open(path)
|
||||
.await?;
|
||||
config_file.write_all(&serde_json::to_vec(&*state.config.read().await)?).await?;
|
||||
config_file.write_all(&serde_json::to_vec(config)?).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue