diff --git a/src/bot.rs b/src/bot.rs index f8fe71d..7916920 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -1,15 +1,12 @@ -use crate::config::{Config, PostBody, SeriesConfig}; +use crate::{config::{Config, PostBody, SeriesConfig}, fetchers::{jnovel}, lemmy}; use crate::fetchers::jnovel::JPostInfo; use crate::lemmy::{Lemmy, PostInfo}; use crate::post_history::SeriesHistory; -use crate::{fetchers::{jnovel}, lemmy, write_error, write_info, write_warn, SharedData}; -use chrono::{DateTime, Duration, Utc}; +use chrono::{DateTime, Duration, Timelike, Utc}; use lemmy_api_common::post::CreatePost; use lemmy_db_schema::newtypes::{CommunityId, LanguageId}; use lemmy_db_schema::PostFeatureType; use std::collections::HashMap; -use std::sync::Arc; -use tokio::sync::RwLock; use tokio::time::sleep; use crate::fetchers::Fetcher; use systemd_journal_logger::connected_to_journal; @@ -40,115 +37,91 @@ macro_rules! error { } }; } + +pub(crate) async fn run() { let mut last_reload: DateTime; let mut lemmy: Lemmy; let mut login_error: bool; - let mut communities; - { - let mut write = data.write().await; + let mut communities: HashMap; + let mut post_history: SeriesHistory; + let mut start: DateTime; + let mut config: Config = Config::load(); + last_reload = Utc::now(); - // Errors during bot init are likely unrecoverable and therefore should panic the bot - // Does not really matter since the bot will get restarted anyway but this way the uptime url logs a downtime - write.config = Config::load(); - last_reload = Utc::now(); - } + lemmy = match lemmy::login(&config).await { + Ok(data) => data, + Err(_) => panic!(), + }; + login_error = false; - { - let read = data.read().await; - lemmy = match lemmy::login(&read.config).await { - Ok(data) => data, - Err(_) => panic!(), - }; - login_error = false; + communities = match lemmy.get_communities().await { + Ok(data) => data, + Err(_) => panic!(), + }; - communities = match lemmy.get_communities().await { - Ok(data) => data, - Err(_) => panic!(), - }; - } - - { - let mut write = data.write().await; - write.start = Utc::now(); - } + start = Utc::now(); let info_msg = "Bot init successful, starting normal operations".to_owned(); info!(info_msg); loop { - idle(&data).await; + idle(&start, &config).await; + start = Utc::now(); - { - let mut write = data.write().await; - - write.start = Utc::now(); + // replace with watcher + if start - last_reload >= Duration::seconds(config.config_reload_seconds as i64) { + config = Config::load(); let message = "Config reloaded".to_owned(); info!(message); - write.config = Config::load(); - let message = "Config reloaded".to_owned(); - write_info(message); - } } - { + if login_error { let info_msg = "Login invalid, refreshing session"; info!(info_msg); lemmy = match lemmy::login(&config).await { - Ok(data) => data, - Err(_) => continue, - }; - login_error = false; - } + Ok(data) => data, + Err(_) => continue, + }; + login_error = false; } - { - let read = data.read().await; - if read.start - last_reload >= Duration::seconds(read.config.config_reload_seconds as i64) { - communities = match lemmy.get_communities().await { - Ok(data) => data, - Err(_) => { - login_error = true; - continue; + if start - last_reload >= Duration::seconds(config.config_reload_seconds as i64) { + communities = match lemmy.get_communities().await { + Ok(data) => data, + Err(_) => { + login_error = true; + continue; + } + }; let message = "Communities reloaded".to_owned(); info!(message); last_reload = Utc::now(); - write_info(message); - last_reload = Utc::now(); - } } - { - let mut write = data.write().await; - write.post_history = SeriesHistory::load_history(); + post_history = SeriesHistory::load_history(); + + let series = config.series.clone(); + for series in series { + if handle_series(&series, &communities, &lemmy, &config, &mut post_history) + .await + .is_err() + { + login_error = true; + continue; + }; } - { - let read = data.read().await; - let series = read.config.series.clone(); - drop(read); - for series in series { - if handle_series(&series, &communities, &lemmy, &data) - .await - .is_err() - { - login_error = true; - continue; - }; - } - } - - idle(&data).await; + idle(&start, &config).await; } } -async fn idle(data: &Arc>) { - let read = data.read().await; +async fn idle(start: &DateTime, config: &Config) { let mut sleep_duration = Duration::seconds(30); - if Utc::now() - read.start > sleep_duration { + if Utc::now() - start > sleep_duration { sleep_duration = Duration::seconds(60); } - if let Some(status_url) = read.config.status_post_url.clone() { + if let Some(status_url) = config.status_post_url.clone() { match reqwest::get(status_url).await { Ok(_) => {} Err(e) => { @@ -158,12 +131,12 @@ async fn idle(data: &Arc>) { } }; - while Utc::now() - read.start < sleep_duration { + while Utc::now() - start < sleep_duration { sleep(Duration::milliseconds(100).to_std().unwrap()).await; } } -async fn handle_series(series: &SeriesConfig, communities: &HashMap, lemmy: &Lemmy, data: &Arc>) -> Result<(), ()> { +async fn handle_series(series: &SeriesConfig, communities: &HashMap, lemmy: &Lemmy, config: &Config, post_history: &mut SeriesHistory ) -> Result<(), ()> { let jnc = jnovel::JFetcherOptions::new(series.slug.clone(), series.parted); let post_list = match jnc.check_feed().await { Ok(data) => data, @@ -176,19 +149,15 @@ async fn handle_series(series: &SeriesConfig, communities: &HashMap part_history.chapter = post_info.get_info().title, @@ -295,11 +255,9 @@ async fn handle_series(series: &SeriesConfig, communities: &HashMap error!("[ERROR] {err_msg}"), - false => println!("[ERROR] {err_msg}"), - } -} - -pub(crate) fn write_warn(warn_msg: String) { - match connected_to_journal() { - true => warn!("[WARN] {warn_msg}"), - false => println!("[WARN] {warn_msg}"), - } -} - -pub(crate) fn write_info(info_msg: String) { - match connected_to_journal() { - true => info!("[INFO] {info_msg}"), - false => println!("[INFO] {info_msg}"), - } -} - pub static HTTP_CLIENT: Lazy = Lazy::new(|| { Client::builder() .timeout(Duration::seconds(30).to_std().unwrap()) @@ -46,25 +19,6 @@ pub static HTTP_CLIENT: Lazy = Lazy::new(|| { .expect("build client") }); -#[derive(Clone, Debug)] -pub(crate) struct SharedData { - config: Config, - post_history: SeriesHistory, - start: DateTime, -} - -impl SharedData { - pub(crate) fn new() -> Self { - SharedData { - config: Config::default(), - post_history: SeriesHistory { - series: HashMap::new(), - }, - start: Utc::now(), - } - } -} - #[tokio::main] async fn main() { JournalLog::new() @@ -72,33 +26,5 @@ async fn main() { .install() .expect("Systemd-Logger crate error"); log::set_max_level(LevelFilter::Info); - - let mut data = SharedData::new(); - - loop { - let write_data = Arc::new(RwLock::new(data.clone())); - //let read_data = write_data.clone(); - let persistent_data = write_data.clone(); - - let bot_thread = tokio::spawn(async move { bot::run(write_data).await }); - - let _ = bot_thread.await; - - data = persistent_data.read().await.clone(); - - { - let err_msg = "Bot crashed due to unknown Error, restarting thread after wait..."; - match connected_to_journal() { - true => error!("[ERROR] {err_msg}"), - false => println!("[ERROR] {err_msg}"), - } - } - - sleep( - Duration::seconds(5) - .to_std() - .expect("Conversion should always work since static"), - ) - .await; - } + bot::run().await; }