Initial draft

This commit is contained in:
Dennis Nemec
2025-09-26 16:41:42 +02:00
commit 3f57ddefb7
10 changed files with 502 additions and 0 deletions

55
src/app.rs Normal file
View File

@ -0,0 +1,55 @@
use std::fs;
use std::path::Path;
use std::thread::sleep;
use std::time::Duration;
use crate::config::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() {
}
pub fn watch_files(config: Config) -> Result<(), Box<dyn std::error::Error>> {
loop {
let mut has_found = false;
for file in fs::read_dir(Path::new(&config.watch_path))? {
if file.is_ok() {
let filename = file.unwrap().file_name().into_string().unwrap();
if filename.starts_with(&config.watch_file_prefix) {
info!("Found file: {}. Moving file.", filename);
move_file_to_dir(&config.watch_path, &filename, &config.dir)?;
has_found = true;
}
}
}
if has_found {
info!("Restarting server");
restart_server();
}
sleep(Duration::from_secs(config.period as u64));
}
}

73
src/config.rs Normal file
View File

@ -0,0 +1,73 @@
use std::fs::{read_to_string, File};
use std::io::Write;
use serde::*;
pub const CONFIG_PATH: &str = "config.toml";
#[derive(Serialize, Deserialize)]
pub struct Config {
/// Time period in which file system changes should be observed. In seconds.
pub period: u8,
/// Absolute file paths to be checked periodically for existence.
pub watch_path: String,
/// The programm will look in the watch_path folder for files with the given prefix.
pub watch_file_prefix: String,
/// Directory the file will be moved to if the file exist. Absolute path.
pub dir: String,
/// Size of the files to be watched which is checked to have this value
pub watch_file_size: u64,
/// Name of the service to be restarted after a file has been found
pub service_name: String
}
#[derive(Debug)]
pub enum ConfigErr {
NotExist,
ParsingError(String),
WriteError(String),
}
pub fn load_config(config_file: &str) -> Result<Config, ConfigErr> {
let toml_contents = read_to_string(config_file);
if let Ok(toml_contents) = toml_contents {
let config = toml::from_str::<Config>(&toml_contents);
match config {
Ok(config) => Ok(config),
Err(e) => Err(ConfigErr::ParsingError(format!("{}", e)))
}
} else {
Err(ConfigErr::NotExist)
}
}
pub fn create_default_config(config_path: &str) -> Result<Config, ConfigErr> {
let config: Config = Config {
period: 30,
dir: String::from("SV_FILE_WATCHER"),
watch_path: String::from("<ERPFRAME_DIR>"),
watch_file_prefix: String::from("<ERPFRAME_LOG_FILE_PREFIX>"),
watch_file_size: 0,
service_name: String::from("<ERPFRAME_SERVICE_NAME>")
};
let file = File::create(config_path);
match file {
Ok(mut file) => {
match file.write_all(toml::to_string(&config).unwrap().as_bytes()) {
Ok(_) => Ok(config),
Err(e) => Err(ConfigErr::WriteError(format!("{}", e)))
}
},
Err(e) => Err(ConfigErr::WriteError(format!("{}", e)))
}
}

52
src/main.rs Normal file
View File

@ -0,0 +1,52 @@
#[macro_use] extern crate log;
use std::fs::File;
use simplelog::*;
use crate::app::watch_files;
use crate::config::{create_default_config, load_config, ConfigErr, CONFIG_PATH};
mod config;
mod app;
mod util;
const LOG_FILE: &str = "sv_file_watcher.log";
fn main() -> Result<(), Box<dyn std::error::Error>> {
CombinedLogger::init(
vec![
TermLogger::new(LevelFilter::Info, Config::default(), TerminalMode::Mixed, ColorChoice::Auto),
WriteLogger::new(LevelFilter::Info, Config::default(), File::create(LOG_FILE).unwrap()),
]
).unwrap();
// Step 1: Get or create config file
let mut 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.");
config_res = create_default_config(CONFIG_PATH);
},
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(());
}
}
}
let config = config_res.unwrap();
watch_files(config)?;
Ok(())
}

0
src/util.rs Normal file
View File