From 296d8fca0210d6159bdb06069baed4170b25d675 Mon Sep 17 00:00:00 2001 From: AeEn123 <63899598+AeEn123@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:54:59 +0000 Subject: [PATCH] Rework logging system --- Cargo.toml | 1 + src/gui.rs | 12 ++++---- src/gui/welcome.rs | 10 +++---- src/log.rs | 29 +++++++++++++++++++ src/logic.rs | 70 ++++++++++++++++++++++++---------------------- src/main.rs | 1 + src/updater.rs | 28 +++++++++---------- src/updater/gui.rs | 10 +++---- 8 files changed, 97 insertions(+), 64 deletions(-) create mode 100644 src/log.rs diff --git a/Cargo.toml b/Cargo.toml index 5f7d288..87dd5df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.4" edition = "2021" [dependencies] +chrono = "0.4.39" clap = { version = "4.5.23", features = ["derive"] } eframe = { features = ["glow"], default-features = false, version = "0.29" } egui = "0.29" diff --git a/src/gui.rs b/src/gui.rs index 61385cc..4497a83 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -6,7 +6,7 @@ use fluent_bundle::{FluentBundle, FluentResource}; use std::sync::Arc; use std::collections::HashMap; // Used for input -use crate::{logic, updater}; // Used for functionality +use crate::{log, logic, updater}; // Used for functionality mod welcome; mod settings; @@ -472,12 +472,12 @@ fn detect_japanese_font() -> Option { match std::fs::metadata(&resolved_font) { Ok(metadata) => { if metadata.is_file() { - println!("{}: valid", resolved_font); + log::info(&format!("{}: valid", resolved_font)); return Some(resolved_font); } } Err(e) => { - println!("{}: invalid - {}", resolved_font, e) + log::warn(&format!("{}: invalid - {}", resolved_font, e)) } } @@ -504,12 +504,12 @@ impl MyApp { cc.egui_ctx.set_fonts(font); } Err(e) => { - println!("Error loading Japanese fonts: {e}") + log::warn(&format!("Error loading Japanese fonts: {e}")) } } } None => { - println!("No Japanese fonts detected, Japanese characters will not render.") + log::warn("No Japanese fonts detected, Japanese characters will not render.") } } @@ -597,7 +597,7 @@ pub fn run_gui() { ); if result.is_err() { - eprintln!("GUI failed: {}", result.unwrap_err()) + log::error(&format!("GUI failed: {}", result.unwrap_err())) } } diff --git a/src/gui/welcome.rs b/src/gui/welcome.rs index 0986874..f449879 100644 --- a/src/gui/welcome.rs +++ b/src/gui/welcome.rs @@ -1,5 +1,5 @@ use eframe::egui; -use crate::gui::settings; +use crate::{gui::settings, log}; use crate::logic; use fluent_bundle::{FluentBundle, FluentResource}; use std::sync::Arc; @@ -20,12 +20,12 @@ fn detect_japanese_font() -> Option { match std::fs::metadata(&resolved_font) { Ok(metadata) => { if metadata.is_file() { - println!("{}: valid", resolved_font); + log::info(&format!("{}: valid", resolved_font)); return Some(resolved_font); } } Err(e) => { - println!("{}: invalid - {}", resolved_font, e) + log::warn(&format!("{}: invalid - {}", resolved_font, e)) } } @@ -52,12 +52,12 @@ impl MyApp { cc.egui_ctx.set_fonts(font); } Err(e) => { - println!("Error loading Japanese fonts: {e}") + log::error(&format!("Error loading Japanese fonts: {e}")) } } } None => { - println!("No Japanese fonts detected, Japanese characters will not render.") + log::warn("No Japanese fonts detected, Japanese characters will not render.") } } Default::default() diff --git a/src/log.rs b/src/log.rs new file mode 100644 index 0000000..65eedec --- /dev/null +++ b/src/log.rs @@ -0,0 +1,29 @@ +use std::sync::Mutex; +use lazy_static::lazy_static; + +lazy_static! { + static ref LOG: Mutex = Mutex::new(String::new()); +} + +fn log(log_type: &str, message: &str) { + let now = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S").to_string(); + let log_message = format!("{} {}{}", now, log_type, message); + + println!("{}", log_message); + + let mut log = LOG.lock().unwrap(); + + log.push_str(&log_message); +} + +pub fn info(message: &str) { + log("INFO: ", message) +} + +pub fn warn(message: &str) { + log("WARN: ", message) +} + +pub fn error(message: &str) { + log("ERROR: ", message) +} \ No newline at end of file diff --git a/src/logic.rs b/src/logic.rs index 8720a22..dec981f 100644 --- a/src/logic.rs +++ b/src/logic.rs @@ -8,6 +8,8 @@ use unic_langid::LanguageIdentifier; use lazy_static::lazy_static; use serde_json::{json, Value}; +use crate::log; + include!(concat!(env!("OUT_DIR"), "/locale_data.rs")); // defines get_locale_resources and LANGUAGE_LIST // Define mutable static values @@ -98,7 +100,7 @@ fn read_config_file() -> Value { match serde_json::from_slice(&bytes) { Ok(v) => return v, Err(e) => { - eprintln!("Failed to parse config file! {}", e); + log::warn(&format!("Failed to parse config file! {}", e)); return json!({}); // Blank config by default } } @@ -124,7 +126,7 @@ fn read_system_config() -> Value { match serde_json::from_slice(&bytes) { Ok(v) => return v, Err(e) => { - eprintln!("Failed to parse config file! {}", e); + log::warn(&format!("Failed to parse config file! {}", e)); return json!({}); // Blank config by default } } @@ -245,7 +247,7 @@ fn extract_bytes(header: String, bytes: Vec) -> Vec { // Return all the bytes after the found header index return bytes[index..].to_vec() } - println!("WARN: Failed to extract a file!"); + log::warn("Failed to extract a file!"); // Return bytes instead if this fails return bytes } @@ -257,8 +259,8 @@ fn save_install_script() -> String { if temp_dir != "" { match fs::write(&path, include_str!("installer/installer.sh")) { - Ok(_) => println!("File written to {}", path), - Err(e) => println!("Failed to write to {}: {}", path, e) + Ok(_) => log::info(&format!("File written to {}", path)), + Err(e) => log::error(&format!("Failed to write to {}: {}", path, e)) } return path; @@ -274,8 +276,8 @@ fn save_install_script() -> String { if temp_dir != "" { match fs::write(&path, include_str!("installer/installer.bat")) { - Ok(_) => println!("File written to {}", path), - Err(e) => println!("Failed to write to {}: {}", path, e) + Ok(_) => log::info(&format!("File written to {}", path)), + Err(e) => log::error(&format!("Failed to write to {}: {}", path, e)) } return path; @@ -484,7 +486,7 @@ pub fn delete_all_directory_contents(dir: String) { // If it's an error, log it and show on GUI Err(e) => { - println!("ERROR: Failed to delete file: {}: {}", count, e); + log::error(&format!("Failed to delete file: {}: {}", count, e)); update_status(get_message(&locale, "failed-deleting-file", Some(&args))); } } @@ -495,7 +497,7 @@ pub fn delete_all_directory_contents(dir: String) { // If it's an error, log it and show on GUI Err(e) => { - println!("ERROR: Failed to delete file: {}: {}", count, e); + log::error(&format!("Failed to delete file: {}: {}", count, e)); update_status(get_message(&locale, "failed-deleting-file", Some(&args))); } } @@ -516,11 +518,11 @@ pub fn delete_all_directory_contents(dir: String) { // Error handling just so the program doesn't crash for seemingly no reason } else { update_status(get_message(&get_locale(None), "error-check-logs", None)); - println!("ERROR: Directory detection failed.") + log::error("ERROR: Directory detection failed.") } } Err(e) => { - println!("WARN: '{}' {}", dir, e); + log::warn(&format!("WARN: '{}' {}", dir, e)); update_status(get_message(&get_locale(None), "idling", None)); } } @@ -604,7 +606,7 @@ pub fn refresh(dir: String, mode: String, cli_list_mode: bool, yield_for_thread: if let Some(filename) = path.file_name() { match &mut fs::File::open(&path) { Err(why) => { - println!("ERROR: couldn't open {}: {}", display, why); + log::error(&format!("Couldn't open {}: {}", display, why)); args.set("error", why.to_string()); update_status(get_message(&locale, "failed-opening-file", Some(&args))); }, @@ -613,7 +615,7 @@ pub fn refresh(dir: String, mode: String, cli_list_mode: bool, yield_for_thread: let mut buffer = vec![0; 2048]; match file.read(&mut buffer) { Err(why) => { - println!("ERROR: couldn't open {}: {}", display, why); + log::error(&format!("Couldn't open {}: {}", display, why)); update_status(get_message(&locale, "failed-opening-file", Some(&args))); }, Ok(bytes_read) => { @@ -675,11 +677,11 @@ pub fn refresh(dir: String, mode: String, cli_list_mode: bool, yield_for_thread: } else { let mut status = STATUS.lock().unwrap(); *status = format!("Error: check logs for more details."); - println!("ERROR: Directory detection failed.") + log::error(&format!("ERROR: Directory detection failed.")) } } Err(e) => { - println!("WARN: '{}' {}", dir, e); + log::warn(&format!("'{}' {}", dir, e)); clear_file_list(); update_file_list("No files to list.".to_owned(), cli_list_mode); update_status(get_message(&get_locale(None), "idling", None)); @@ -717,14 +719,14 @@ pub fn extract_file(file: String, mode: String, destination: String, add_extenti match fs::write(new_destination.clone(), extracted_bytes) { Ok(_) => (), - Err(e) => eprintln!("Error writing file: {}", e), + Err(e) => log::error(&format!("Error writing file: {}", e)), } if let Ok(sys_modified_time) = metadata.modified() { let modified_time = filetime::FileTime::from_system_time(sys_modified_time); match filetime::set_file_times(&new_destination, modified_time, modified_time) { Ok(_) => (), - Err(e) => eprintln!("Failed to write file modification time {}", e) + Err(e) => log::error(&format!("Failed to write file modification time {}", e)) } } @@ -734,7 +736,7 @@ pub fn extract_file(file: String, mode: String, destination: String, add_extenti } Err(e) => { update_status(get_message(&get_locale(None), "failed-opening-file", None)); - println!("ERROR: Failed to open file: {}", e); + log::error(&format!("Failed to open file: {}", e)); return "None".to_string(); } } @@ -745,7 +747,7 @@ pub fn extract_file(file: String, mode: String, destination: String, add_extenti args.set("file", &file); update_status(get_message(&get_locale(None), "failed-not-file", Some(&args))); - println!("ERROR: '{}' Not a file.", file); + log::error(&format!(" '{}' Not a file.", file)); return "None".to_string(); } } @@ -754,7 +756,7 @@ pub fn extract_file(file: String, mode: String, destination: String, add_extenti let mut args = FluentArgs::new(); args.set("error", e.to_string()); - println!("Error extracting file: '{}' {}", file, e); + log::error(&format!("Error extracting file: '{}' {}", file, e)); update_status(get_message(&get_locale(None), "idling", Some(&args))); return "None".to_string(); } @@ -765,7 +767,7 @@ pub fn extract_dir(dir: String, destination: String, mode: String, file_list: Ve // Create directory if it doesn't exist match fs::create_dir(destination.clone()) { Ok(_) => (), - Err(e) => eprintln!("Error creating directory: {}", e) + Err(e) => log::error(&format!("Error creating directory: {}", e)) }; // Bunch of error checking to check if it's a valid directory match fs::metadata(dir.clone()) { @@ -832,11 +834,11 @@ pub fn extract_dir(dir: String, destination: String, mode: String, file_list: Ve // Error handling just so the program doesn't crash for seemingly no reason } else { update_status(get_message(&get_locale(None), "error-check-logs", None)); - println!("ERROR: Directory detection failed.") + log::error(&format!(" Directory detection failed.")) } } Err(e) => { - println!("WARN: '{}' {}", dir, e); + log::warn(&format!("'{}' {}", dir, e)); update_status(get_message(&get_locale(None), "idling", None)); } } @@ -943,7 +945,7 @@ pub fn extract_all(destination: String, yield_for_thread: bool, use_alias: bool) if let Some(filename) = path.file_name() { match &mut fs::File::open(&path) { Err(why) => { - println!("ERROR: couldn't open file: {}", why); + log::error(&format!("Couldn't open file: {}", why)); update_status(get_message(&locale, "failed-opening-file", Some(&args))); }, Ok(file) => { @@ -951,7 +953,7 @@ pub fn extract_all(destination: String, yield_for_thread: bool, use_alias: bool) let mut buffer = vec![0; 2048]; match file.read(&mut buffer) { Err(why) => { - println!("ERROR: couldn't open file: {}", why); + log::error(&format!("Couldn't open file: {}", why)); update_status(get_message(&locale, "failed-opening-file", Some(&args))); }, Ok(bytes_read) => { @@ -1043,7 +1045,7 @@ pub fn swap_assets(dir: &str, asset_a: &str, asset_b: &str) { args.set("error", e.to_string()); update_status(get_message(&locale, "failed-opening-file", Some(&args))); - println!("Error opening file '{}': {}", asset_a_path, e); + log::error(&format!("Error opening file '{}': {}", asset_a_path, e)); return } }; @@ -1057,7 +1059,7 @@ pub fn swap_assets(dir: &str, asset_a: &str, asset_b: &str) { args.set("error", e.to_string()); update_status(get_message(&locale, "failed-opening-file", Some(&args))); - println!("Error opening file '{}': {}", asset_b_path, e); + log::error(&format!("Error opening file '{}': {}", asset_b_path, e)); return } }; @@ -1069,7 +1071,7 @@ pub fn swap_assets(dir: &str, asset_a: &str, asset_b: &str) { args.set("error", e.to_string()); update_status(get_message(&locale, "failed-opening-file", Some(&args))); - println!("Error opening file '{}': {}", asset_a_path, e); + log::error(&format!("Error opening file '{}': {}", asset_a_path, e)); } }; @@ -1080,7 +1082,7 @@ pub fn swap_assets(dir: &str, asset_a: &str, asset_b: &str) { args.set("error", e.to_string()); update_status(get_message(&locale, "failed-opening-file", Some(&args))); - println!("Error opening file '{}': {}", asset_b_path, e); + log::error(&format!("Error opening file '{}': {}", asset_b_path, e)); } }; @@ -1180,11 +1182,11 @@ pub fn set_config(value: Value) { Ok(data) => { let result = fs::write(CONFIG_FILE.lock().unwrap().clone(), data); if result.is_err() { - println!("Failed to write config file: {}", result.unwrap_err()) + log::error(&format!("Failed to write config file: {}", result.unwrap_err())) } }, Err(e) => { - println!("Failed to write config file: {}", e); + log::error(&format!("Failed to write config file: {}", e)); } } @@ -1252,12 +1254,12 @@ pub fn set_update_file(file: String) { pub fn run_install_script(run_afterwards: bool) -> bool { if let Some(update_file) = {UPDATE_FILE.lock().unwrap().clone()} { - println!("Installing from {}", update_file); + log::info(&format!("Installing from {}", update_file)); if get_system_config_bool("prefer-installers").unwrap_or(false) { // Just run the installer match open::that(update_file) { Ok(_) => (), - Err(e) => eprintln!("Installer failed to launch {} ", e) + Err(e) => log::error(&format!("Installer failed to launch {} ", e)) } std::process::exit(0); @@ -1303,7 +1305,7 @@ pub fn clean_up() { let temp_dir = get_temp_dir(false); // Just in case if it somehow resolves to "/" if temp_dir != "" && temp_dir != "/" { - println!("Cleaning up {}", temp_dir); + log::info(&format!("Cleaning up {}", temp_dir)); let _ = fs::remove_dir_all(temp_dir); // Not too important, ignore value, and the last thing the program will run } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index a20cc53..fb093f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +mod log; mod gui; mod logic; mod updater; diff --git a/src/updater.rs b/src/updater.rs index eba3d4c..03f2855 100644 --- a/src/updater.rs +++ b/src/updater.rs @@ -3,7 +3,7 @@ use std::fs; use reqwest::blocking::Client; use serde::Deserialize; -use crate::logic; +use crate::{log, logic}; mod gui; @@ -45,13 +45,13 @@ fn detect_download_binary(assets: &Vec) -> &Asset { } } - eprintln!("Failed to find asset, going for first asset listed."); + log::warn("Failed to find asset, going for first asset listed."); return &assets[0]; } pub fn download_update(url: &str) { if !logic::get_system_config_bool("allow-updates").unwrap_or(true) { - println!("Updating has been disabled by the system."); + log::warn("Updating has been disabled by the system."); return } let client = Client::new(); @@ -73,13 +73,13 @@ pub fn download_update(url: &str) { let path = format!("{}/{}", temp_dir, filename); match fs::write(path.clone(), bytes) { Ok(_) => logic::set_update_file(path), - Err(e) => eprintln!("Failed to write file: {}", e) + Err(e) => log::error(&format!("Failed to write file: {}", e)) } } - Err(e) => eprintln!("Failed to parse: {}", e) + Err(e) => log::error(&format!("Failed to parse: {}", e)) } } - Err(e) => eprintln!("Failed to download: {}", e), + Err(e) => log::error(&format!("Failed to download: {}", e)), } } @@ -99,9 +99,9 @@ pub fn check_for_updates(run_gui: bool, auto_download_update: bool) { let clean_tag_name = clean_version_number(&json.tag_name); let clean_version = clean_version_number(env!("CARGO_PKG_VERSION")); if clean_tag_name != clean_version { - println!("An update is available."); - println!("{}", json.name); - println!("{}", json.body); + log::info("An update is available."); + log::info(&json.name); + log::info(&json.body); let correct_asset = detect_download_binary(&json.assets); @@ -109,17 +109,17 @@ pub fn check_for_updates(run_gui: bool, auto_download_update: bool) { download_update(&correct_asset.browser_download_url); } else if run_gui { match gui::run_gui(json.body, json.name, correct_asset.browser_download_url.clone()) { - Ok(_) => println!("User exited GUI"), - Err(e) => println!("GUI failed: {}",e) + Ok(_) => log::info("User exited GUI"), + Err(e) => log::error(&format!("GUI failed: {}",e)) } } } else { - println!("No updates are available.") + log::info("No updates are available.") } } - Err(e) => eprintln!("Failed to parse json: {}", e) + Err(e) => log::error(&format!("Failed to parse json: {}", e)) } } - Err(e) => eprintln!("Failed to check for update: {}", e), + Err(e) => log::error(&format!("Failed to check for update: {}", e)), } } diff --git a/src/updater/gui.rs b/src/updater/gui.rs index 7e652a9..4b78c94 100644 --- a/src/updater/gui.rs +++ b/src/updater/gui.rs @@ -1,5 +1,5 @@ use eframe::egui; -use crate::logic; +use crate::{log, logic}; use crate::logic::get_config_string; use crate::updater; use egui_commonmark::*; @@ -22,12 +22,12 @@ fn detect_japanese_font() -> Option { match std::fs::metadata(&resolved_font) { Ok(metadata) => { if metadata.is_file() { - println!("{}: valid", resolved_font); + log::info(&format!("{}: valid", resolved_font)); return Some(resolved_font); } } Err(e) => { - println!("{}: invalid - {}", resolved_font, e) + log::warn(&format!("{}: invalid - {}", resolved_font, e)) } } @@ -54,12 +54,12 @@ impl App { cc.egui_ctx.set_fonts(font); } Err(e) => { - println!("Error loading Japanese fonts: {e}") + log::error(&format!("Error loading Japanese fonts: {e}")) } } } None => { - println!("No Japanese fonts detected, Japanese characters will not render.") + log::warn("No Japanese fonts detected, Japanese characters will not render.") } }