Compare commits
2 commits
5976bd59a7
...
ebbfdcea63
Author | SHA1 | Date | |
---|---|---|---|
ebbfdcea63 | |||
ff0360ac07 |
5 changed files with 123 additions and 51 deletions
77
src/bot.rs
77
src/bot.rs
|
@ -12,9 +12,10 @@ use crate::settings::{BotSettings, SeriesSettings};
|
|||
|
||||
pub(crate) struct Bot {
|
||||
settings: BotSettings,
|
||||
settings_id: u16,
|
||||
health_signal: Arc<AtomicHealthSignal>,
|
||||
history: SeriesHistory,
|
||||
login_time: Option<DateTime<Utc>>
|
||||
login_time: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
enum Wait {
|
||||
|
@ -23,16 +24,26 @@ enum Wait {
|
|||
}
|
||||
|
||||
impl Bot {
|
||||
pub(crate) fn new(health_signal: Arc<AtomicHealthSignal>, settings: BotSettings) -> Self {
|
||||
pub(crate) fn new(health_signal: Arc<AtomicHealthSignal>, settings_id: u16, settings: BotSettings) -> Self {
|
||||
let history: SeriesHistory = SeriesHistory::load_history();
|
||||
|
||||
Bot { health_signal, settings, history, login_time: None }
|
||||
|
||||
|
||||
Bot { health_signal, settings_id, settings, history, login_time: None }
|
||||
}
|
||||
pub(crate) fn run(&mut self, series_settings: Arc<RwLock<HashMap<u16, SeriesSettings>>>, update_pending: Arc<AtomicBool>) {
|
||||
pub(crate) fn run(
|
||||
&mut self,
|
||||
series_settings: Arc<RwLock<HashMap<u16, SeriesSettings>>>,
|
||||
bot_settings: Arc<RwLock<HashMap<u16, BotSettings>>>,
|
||||
update_pending: Arc<AtomicBool>
|
||||
) {
|
||||
let mut last_ping = Utc::now();
|
||||
if let Some(interval) = self.settings.status_post_interval() {
|
||||
last_ping -= interval
|
||||
}
|
||||
loop {
|
||||
match self.health_signal.load(Ordering::SeqCst) {
|
||||
HealthSignal::RequestAlive => {
|
||||
//self.health_signal.store(HealthSignal::ConfirmAlive, Ordering::SeqCst);
|
||||
self.health_signal.store(HealthSignal::ConfirmAlive, Ordering::SeqCst);
|
||||
}
|
||||
HealthSignal::RequestStop => {
|
||||
break;
|
||||
|
@ -40,53 +51,64 @@ impl Bot {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
while update_pending.load(Ordering::SeqCst) {
|
||||
if update_pending.load(Ordering::SeqCst) {
|
||||
Logging::debug("Awaiting Config Update");
|
||||
sleep(Duration::milliseconds(100).to_std().unwrap());
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
self.settings = bot_settings.read().get(&self.settings_id).unwrap().clone();
|
||||
|
||||
// perform status ping
|
||||
if let Some(interval) = self.settings.status_post_interval() {
|
||||
if Utc::now() + Duration::seconds(1) >= last_ping + interval {
|
||||
if self.ping_status() {
|
||||
last_ping = Utc::now();
|
||||
}
|
||||
else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(login_time) = self.login_time {
|
||||
if Utc::now() - login_time >= Duration::minutes(60) {
|
||||
self.logout();
|
||||
//self.logout();
|
||||
continue
|
||||
}
|
||||
}
|
||||
else {
|
||||
self.login();
|
||||
//self.login();
|
||||
}
|
||||
|
||||
self.history = SeriesHistory::load_history();
|
||||
|
||||
let run_start_time = Utc::now();
|
||||
self.ping_status();
|
||||
|
||||
series_settings.read().iter().for_each(|(id, series)| {
|
||||
let new_entries = series.check();
|
||||
//let new_entries = series.check();
|
||||
});
|
||||
for series in series_settings.read().iter() {
|
||||
//series.update(&mut self.history, &lemmy, &self.settings).await;
|
||||
Logging::debug("Done Updating Series");
|
||||
self.wait(1, Wait::Absolute);
|
||||
}
|
||||
Logging::debug("Awaiting Timeout");
|
||||
self.wait(30, Wait::Buffer(run_start_time));
|
||||
Logging::debug("Pinging Server");
|
||||
self.ping_status();
|
||||
Logging::debug("Awaiting Timeout 2");
|
||||
self.wait(30, Wait::Absolute);
|
||||
}
|
||||
self.health_signal.store(HealthSignal::ConfirmStop, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
fn ping_status(&self) {
|
||||
fn ping_status(&self) -> bool {
|
||||
if let Some(status_url) = &self.settings.status_post_url() {
|
||||
match HTTP_CLIENT.get(status_url).send() {
|
||||
Ok(_) => {},
|
||||
return match HTTP_CLIENT.get(status_url).send() {
|
||||
Ok(_) => {
|
||||
true
|
||||
},
|
||||
Err(e) => {
|
||||
let err_msg = format!("While pinging status URL: {e}");
|
||||
Logging::error(err_msg.as_str());
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn wait(&self, seconds: i64, start_time: Wait) {
|
||||
|
@ -99,15 +121,14 @@ impl Bot {
|
|||
sleep(Duration::milliseconds(100).to_std().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn login(&mut self) {
|
||||
//
|
||||
todo!();
|
||||
self.login_time = Some(Utc::now());
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
||||
fn logout(&mut self) {
|
||||
self.login_time = None;
|
||||
todo!()
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,52 @@
|
|||
use std::collections::VecDeque;
|
||||
use chrono::{DateTime, Utc};
|
||||
use log::Level;
|
||||
use parking_lot::Mutex;
|
||||
use systemd_journal_logger::connected_to_journal;
|
||||
|
||||
fn mem_log(msg: Option<String>) -> VecDeque<LogEvent> {
|
||||
static MEM_LOG: Mutex<VecDeque<LogEvent>> = Mutex::new(VecDeque::new());
|
||||
fn mem_log(level: Level, msg: Option<String>) -> VecDeque<LogEvent> {
|
||||
static MEM_LOG_DEBUG: Mutex<VecDeque<LogEvent>> = Mutex::new(VecDeque::new());
|
||||
static MEM_LOG_INFO: Mutex<VecDeque<LogEvent>> = Mutex::new(VecDeque::new());
|
||||
static MEM_LOG_WARN: Mutex<VecDeque<LogEvent>> = Mutex::new(VecDeque::new());
|
||||
static MEM_LOG_ERROR: Mutex<VecDeque<LogEvent>> = Mutex::new(VecDeque::new());
|
||||
|
||||
let max_len: i8;
|
||||
|
||||
let mut list = match level {
|
||||
Level::Debug => {
|
||||
max_len = 10;
|
||||
MEM_LOG_DEBUG.lock()
|
||||
},
|
||||
Level::Info => {
|
||||
max_len = 20;
|
||||
MEM_LOG_INFO.lock()
|
||||
},
|
||||
Level::Warn => {
|
||||
max_len = 40;
|
||||
MEM_LOG_WARN.lock()
|
||||
},
|
||||
Level::Error => {
|
||||
max_len = -1;
|
||||
MEM_LOG_ERROR.lock()
|
||||
},
|
||||
Level::Trace => {
|
||||
max_len = 10;
|
||||
MEM_LOG_DEBUG.lock()
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(msg) = msg {
|
||||
let now = Utc::now();
|
||||
let log_event = LogEvent::new(now, msg);
|
||||
let mut lock = MEM_LOG.lock();
|
||||
lock.push_back(log_event);
|
||||
while lock.len() > 10 {
|
||||
lock.pop_front();
|
||||
list.push_back(log_event);
|
||||
if max_len != -1 {
|
||||
while list.len() > max_len as usize {
|
||||
list.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MEM_LOG.lock().clone();
|
||||
list.clone()
|
||||
}
|
||||
|
||||
pub struct Logging {
|
||||
|
@ -29,7 +59,7 @@ impl Logging {
|
|||
true => log::debug!("{msg}"),
|
||||
false => println!("{msg}"),
|
||||
}
|
||||
mem_log(Some(msg));
|
||||
mem_log(Level::Debug, Some(msg));
|
||||
}
|
||||
|
||||
pub fn info(msg: &str) {
|
||||
|
@ -38,7 +68,7 @@ impl Logging {
|
|||
true => log::info!("{msg}"),
|
||||
false => println!("{msg}"),
|
||||
}
|
||||
mem_log(Some(msg));
|
||||
mem_log(Level::Info, Some(msg));
|
||||
}
|
||||
|
||||
pub fn warn(msg: &str) {
|
||||
|
@ -47,7 +77,7 @@ impl Logging {
|
|||
true => log::warn!("{msg}"),
|
||||
false => println!("{msg}"),
|
||||
}
|
||||
mem_log(Some(msg));
|
||||
mem_log(Level::Warn, Some(msg));
|
||||
}
|
||||
|
||||
pub fn error(msg: &str) {
|
||||
|
@ -56,11 +86,11 @@ impl Logging {
|
|||
true => log::error!("{msg}"),
|
||||
false => eprintln!("{msg}"),
|
||||
}
|
||||
mem_log(Some(msg));
|
||||
mem_log(Level::Error, Some(msg));
|
||||
}
|
||||
|
||||
pub fn get_mem_log() -> VecDeque<LogEvent> {
|
||||
mem_log(None)
|
||||
pub fn get_mem_log(level: Level) -> VecDeque<LogEvent> {
|
||||
mem_log(level, None)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -59,18 +59,19 @@ fn main() {
|
|||
|
||||
let mut health_signals: Vec<Arc<AtomicHealthSignal>> = vec![];
|
||||
let mut update_pending: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
|
||||
|
||||
let series_settings = settings.read().series_settings().clone();
|
||||
|
||||
settings.read().bot_settings().read().iter().for_each(|(id, bot_settings)| {
|
||||
let health_signal = Arc::new(AtomicHealthSignal::new(HealthSignal::RequestAlive));
|
||||
health_signals.push(health_signal.clone());
|
||||
|
||||
let bot_settings = bot_settings.clone();
|
||||
let series_settings = series_settings.clone();
|
||||
let bot_id = *id;
|
||||
let series_settings = settings.read().series_settings().clone();
|
||||
let bot_settings_map = settings.read().bot_settings().clone();
|
||||
let update_pending = update_pending.clone();
|
||||
spawn(move || {
|
||||
let mut bot = Bot::new(health_signal, bot_settings);
|
||||
bot.run(series_settings, update_pending);
|
||||
let mut bot = Bot::new(health_signal, bot_id, bot_settings);
|
||||
bot.run(series_settings, bot_settings_map, update_pending);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -69,6 +69,12 @@ impl ApplicationSettings {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct StatusPostSettings {
|
||||
url: String,
|
||||
interval: Duration,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BotSettings {
|
||||
id: u16,
|
||||
|
@ -76,7 +82,7 @@ pub struct BotSettings {
|
|||
instance: String,
|
||||
username: SensitiveString,
|
||||
password: SensitiveString,
|
||||
status_post_url: Option<String>,
|
||||
status_post_settings: Option<StatusPostSettings>,
|
||||
}
|
||||
impl BotSettings {
|
||||
pub fn instance(&self) -> String {
|
||||
|
@ -90,7 +96,17 @@ impl BotSettings {
|
|||
}
|
||||
|
||||
pub fn status_post_url(&self) -> Option<String> {
|
||||
self.status_post_url.clone()
|
||||
match &self.status_post_settings {
|
||||
Some(settings) => Some(settings.url.clone()),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn status_post_interval(&self) -> Option<Duration> {
|
||||
match &self.status_post_settings {
|
||||
Some(settings) => Some(settings.interval),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::config::SeriesConfig;
|
|||
use crate::fetchers::{Fetcher, FetcherTrait};
|
||||
use crate::fetchers::jnovel::JNovelFetcher;
|
||||
use crate::lemmy::PostType;
|
||||
use crate::settings::{BotSettings, PostSettings, SeriesSettings, SettingsSource};
|
||||
use crate::settings::{BotSettings, PostSettings, SeriesSettings, SettingsSource, StatusPostSettings};
|
||||
use crate::settings::toml::TomlSettings;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
|
@ -16,9 +16,10 @@ pub struct SingleBotTomlSettings {
|
|||
username: SensitiveString,
|
||||
password: SensitiveString,
|
||||
status_post_url: Option<String>,
|
||||
status_post_interval: Option<u32>,
|
||||
pub protected_communities: Vec<String>,
|
||||
series: Vec<SeriesConfig>,
|
||||
fetch_interval: usize,
|
||||
fetch_interval: u32,
|
||||
}
|
||||
|
||||
impl SettingsSource for SingleBotTomlSettings {
|
||||
|
@ -41,7 +42,10 @@ impl SettingsSource for SingleBotTomlSettings {
|
|||
instance: self.instance.clone(),
|
||||
username: self.username.clone(),
|
||||
password: self.password.clone(),
|
||||
status_post_url: self.status_post_url.clone(),
|
||||
status_post_settings: Some(StatusPostSettings {
|
||||
url: self.status_post_url.clone().unwrap(),
|
||||
interval: Duration::from_secs(self.status_post_interval.clone().unwrap() as u64)
|
||||
}),
|
||||
});
|
||||
map
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue