126 lines
3.7 KiB
Rust
126 lines
3.7 KiB
Rust
use crate::config::Config;
|
|
use crate::util::restart_service;
|
|
use std::path::Path;
|
|
use std::process::exit;
|
|
use std::sync::mpsc;
|
|
use std::thread::sleep;
|
|
use std::time::Duration;
|
|
use std::{fs, sync::mpsc::Receiver};
|
|
|
|
use crate::config::{CONFIG_PATH, ConfigErr, create_default_config, load_config};
|
|
|
|
pub fn move_file_to_dir(
|
|
watch_path_string: &String,
|
|
filename: &String,
|
|
move_path_string: &String,
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
let move_path = Path::new(move_path_string);
|
|
let watch_path = Path::new(watch_path_string);
|
|
let file_path = watch_path.join(Path::new(filename));
|
|
let mut moved_file_path = move_path.join(filename);
|
|
|
|
if !fs::exists(move_path)? {
|
|
info!("Creating directory {}", move_path_string);
|
|
fs::create_dir(move_path)?;
|
|
}
|
|
|
|
if fs::exists(&moved_file_path)? {
|
|
moved_file_path.set_file_name(format!("{}.2", filename));
|
|
}
|
|
|
|
fs::copy(&file_path, &moved_file_path)?;
|
|
fs::remove_file(&file_path)?;
|
|
|
|
info!("Moved file to {}", &moved_file_path.display());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn restart_server(service_name: String) {
|
|
restart_service(service_name);
|
|
}
|
|
|
|
pub fn watch_files(
|
|
config: Config,
|
|
shutdown_rx: Receiver<()>,
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
loop {
|
|
// Poll shutdown event.
|
|
match shutdown_rx.recv_timeout(Duration::from_secs(1)) {
|
|
// Break the loop either upon stop or channel disconnect
|
|
Ok(_) | Err(mpsc::RecvTimeoutError::Disconnected) => {
|
|
info!("Received shutdown event. Shutting down...");
|
|
break
|
|
},
|
|
|
|
// Continue work if no events were received within the timeout
|
|
Err(mpsc::RecvTimeoutError::Timeout) => (),
|
|
};
|
|
|
|
let mut has_found = false;
|
|
for file in fs::read_dir(Path::new(&config.watch_path))? {
|
|
if file.is_ok() {
|
|
let file_obj = file.unwrap();
|
|
let filename = file_obj.file_name().into_string().unwrap();
|
|
if filename.starts_with(&config.watch_file_prefix)
|
|
&& file_obj.metadata().unwrap().len() == config.watch_file_size
|
|
{
|
|
info!("Found file: {}. Moving file.", filename);
|
|
move_file_to_dir(&config.watch_path, &filename, &config.dir)?;
|
|
has_found = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if has_found {
|
|
info!("Restarting target service");
|
|
restart_server(config.service_name.clone());
|
|
}
|
|
|
|
sleep(Duration::from_secs(config.period as u64));
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn run(shutdown_rx: Receiver<()>) -> Result<(), Box<dyn std::error::Error>> {
|
|
// Step 1: Get or create config file
|
|
let config_res = load_config(CONFIG_PATH);
|
|
|
|
if let Err(err) = &config_res {
|
|
match err {
|
|
ConfigErr::NotExist => {
|
|
error!("Failed to find existing config file. Create one.");
|
|
match create_default_config(CONFIG_PATH) {
|
|
Ok(_) => (),
|
|
Err(_) => error!("Failed to create config file."),
|
|
}
|
|
|
|
exit(0);
|
|
}
|
|
|
|
ConfigErr::WriteError(e) => {
|
|
error!("Failed to write config file.");
|
|
error!("Message: {e}");
|
|
return Ok(());
|
|
}
|
|
|
|
ConfigErr::ParsingError(e) => {
|
|
error!("Failed to parse config file");
|
|
error!("Message: {e}");
|
|
return Ok(());
|
|
}
|
|
|
|
ConfigErr::Unknown(e) => {
|
|
error!("Unknown error");
|
|
error!("Message: {e}");
|
|
return Ok(());
|
|
}
|
|
}
|
|
}
|
|
|
|
watch_files(config_res.unwrap(), shutdown_rx)?;
|
|
|
|
Ok(())
|
|
}
|