From 79e1a5956e98ed2e33ca8ca291ddcacfe6f17e87 Mon Sep 17 00:00:00 2001 From: Mahesh Asolkar Date: Sat, 7 Jun 2025 21:19:02 -0700 Subject: [PATCH] Clear data before new bar display iteration This makes sure that data displayed is always fresh --- src/bar_modules/bar_module_cpu.rs | 6 +++ src/bar_modules/bar_module_date.rs | 6 ++- src/bar_modules/bar_module_memory.rs | 6 ++- src/bar_modules/bar_module_music.rs | 23 ++++++--- src/bar_modules/bar_module_network.rs | 71 ++++++++++++++++----------- src/bar_modules/bar_module_power.rs | 5 ++ src/bar_modules/bar_module_time.rs | 6 ++- src/bar_modules/bar_module_weather.rs | 5 ++ src/bar_modules/mod.rs | 3 ++ src/main.rs | 4 +- 10 files changed, 93 insertions(+), 42 deletions(-) diff --git a/src/bar_modules/bar_module_cpu.rs b/src/bar_modules/bar_module_cpu.rs index 9987121..6c49366 100644 --- a/src/bar_modules/bar_module_cpu.rs +++ b/src/bar_modules/bar_module_cpu.rs @@ -116,6 +116,12 @@ impl UnibarModuleCpu { impl bar_modules::BarModuleActions for UnibarModuleCpu { + // -------------------- + fn clear(&mut self) { + self.cpu_times_sample_1 = CpuTimes::new(); + self.cpu_times_sample_2 = CpuTimes::new(); + } + // -------------------- fn generate_data(&mut self) { self.cpu_times_sample_1 = self.read_cpu_times().expect("Trouble getting CPU times sample 1"); diff --git a/src/bar_modules/bar_module_date.rs b/src/bar_modules/bar_module_date.rs index ebe8c20..bfd4f88 100644 --- a/src/bar_modules/bar_module_date.rs +++ b/src/bar_modules/bar_module_date.rs @@ -21,8 +21,12 @@ impl UnibarModuleDate { impl bar_modules::BarModuleActions for UnibarModuleDate { // -------------------- - fn generate_data(&mut self) { + fn clear(&mut self) { self.date_time = Local::now(); + } + + // -------------------- + fn generate_data(&mut self) { if self.opts.debug { println!("-----> Date dump {:#?}", self.date_time); } diff --git a/src/bar_modules/bar_module_memory.rs b/src/bar_modules/bar_module_memory.rs index a2d4227..6b998ba 100644 --- a/src/bar_modules/bar_module_memory.rs +++ b/src/bar_modules/bar_module_memory.rs @@ -25,6 +25,11 @@ impl UnibarModuleMemory { impl bar_modules::BarModuleActions for UnibarModuleMemory { + // -------------------- + fn clear(&mut self) { + self.meminfo_str = "".to_string(); + } + // -------------------- fn generate_data(&mut self) { let path = Path::new("/proc/meminfo"); @@ -42,7 +47,6 @@ impl bar_modules::BarModuleActions for UnibarModuleMemory { }, }; self.meminfo_str.pop(); - } // -------------------- diff --git a/src/bar_modules/bar_module_music.rs b/src/bar_modules/bar_module_music.rs index 72317a6..3a1c406 100644 --- a/src/bar_modules/bar_module_music.rs +++ b/src/bar_modules/bar_module_music.rs @@ -5,26 +5,33 @@ use crate::bar_modules; #[derive(Clone)] pub struct UnibarModuleMusic { - opts: common::AppOptions, - current_stdout :String, - progress_stdout :String, - state_stdout: String, + opts: common::AppOptions, + current_stdout: String, + progress_stdout: String, + state_stdout: String, } impl UnibarModuleMusic { // -------------------- pub fn new(o :common::AppOptions) -> Self { UnibarModuleMusic { - opts: o, - current_stdout: "".to_string(), - progress_stdout: "".to_string(), - state_stdout: "stopped".to_string(), + opts: o, + current_stdout: "".to_string(), + progress_stdout: "".to_string(), + state_stdout: "stopped".to_string(), } } } impl bar_modules::BarModuleActions for UnibarModuleMusic { + // -------------------- + fn clear(&mut self) { + self.current_stdout = "".to_string(); + self.progress_stdout = "".to_string(); + self.state_stdout = "stopped".to_string(); + } + // -------------------- fn generate_data(&mut self) { // MPD format options here: diff --git a/src/bar_modules/bar_module_network.rs b/src/bar_modules/bar_module_network.rs index 296bfea..36242ad 100644 --- a/src/bar_modules/bar_module_network.rs +++ b/src/bar_modules/bar_module_network.rs @@ -26,43 +26,54 @@ impl UnibarModuleNetwork { impl bar_modules::BarModuleActions for UnibarModuleNetwork { + // -------------------- + fn clear(&mut self) { + self.network_info = json!(serde_json::Value::Null); + } + // -------------------- fn generate_data(&mut self) { // Output of 'ip -j address' command has network information - let ip_addr_output = Command::new("ip") - .arg("-j") // Output in json format - .arg("address") - .stdout(Stdio::piped()) - .output() - .unwrap(); - self.ip_addr_stdout = String::from_utf8(ip_addr_output.stdout).unwrap(); - self.ip_addr_stdout.pop(); - - let network_data: Value = serde_json::from_str::(self.ip_addr_stdout.as_str()).unwrap(); - - if let Some(interfaces) = network_data.as_array() { - if self.opts.debug { - println!("-----> network_data - {:#?}", network_data); + match Command::new("ip") + .arg("-j") // Output in json format + .arg("address") + .stdout(Stdio::piped()) + .output() { + Err(e) => { + eprintln!("Error getting network information {e}"); + self.network_info = json!(serde_json::Value::Null); } - // Get all interfaces that are up - let mut up_intf :Vec<_> = interfaces.iter() - .filter(|el| el["operstate"].as_str().unwrap().contains("UP")) - .cloned().collect(); + Ok(ip_addr_output) => { + self.ip_addr_stdout = String::from_utf8(ip_addr_output.stdout).unwrap(); + self.ip_addr_stdout.pop(); - // Sort by 'ifname'. This is an unreliable way to proiritize ethernet over wifi. - // Ethenet network interface names normally start with 'e' and wifi interface names - // start with 'w' - up_intf.sort_by(|a, b| a["ifname"].as_str().unwrap().cmp(b["ifname"].as_str().unwrap())); - if up_intf.len() > 0 { - let inet_addr :Vec<_> = up_intf[0]["addr_info"].as_array().unwrap().iter() - .filter(|ai| ai["scope"].as_str().unwrap().contains("global")) - .cloned().collect(); - if inet_addr.len() > 0 { + let network_data: Value = serde_json::from_str::(self.ip_addr_stdout.as_str()).unwrap(); + + if let Some(interfaces) = network_data.as_array() { if self.opts.debug { - println!("-----> Inet Addr - {:#?}", inet_addr); + println!("-----> network_data - {:#?}", network_data); + } + // Get all interfaces that are up + let mut up_intf :Vec<_> = interfaces.iter() + .filter(|el| el["operstate"].as_str().unwrap().contains("UP")) + .cloned().collect(); + + // Sort by 'ifname'. This is an unreliable way to proiritize ethernet over wifi. + // Ethenet network interface names normally start with 'e' and wifi interface names + // start with 'w' + up_intf.sort_by(|a, b| a["ifname"].as_str().unwrap().cmp(b["ifname"].as_str().unwrap())); + if up_intf.len() > 0 { + let inet_addr :Vec<_> = up_intf[0]["addr_info"].as_array().unwrap().iter() + .filter(|ai| ai["scope"].as_str().unwrap().contains("global")) + .cloned().collect(); + if inet_addr.len() > 0 { + if self.opts.debug { + println!("-----> Inet Addr - {:#?}", inet_addr); + } + self.network_info = inet_addr[0].clone(); + self.network_info["ifname"] = up_intf[0]["ifname"].clone(); + } } - self.network_info = inet_addr[0].clone(); - self.network_info["ifname"] = up_intf[0]["ifname"].clone(); } } } diff --git a/src/bar_modules/bar_module_power.rs b/src/bar_modules/bar_module_power.rs index 9bd7999..d9b2be2 100644 --- a/src/bar_modules/bar_module_power.rs +++ b/src/bar_modules/bar_module_power.rs @@ -38,6 +38,11 @@ impl UnibarModulePower { impl bar_modules::BarModuleActions for UnibarModulePower { + // -------------------- + fn clear(&mut self) { + self.power_info = PowerData::new(); + } + // -------------------- fn generate_data(&mut self) { // Following command is used to get power data: diff --git a/src/bar_modules/bar_module_time.rs b/src/bar_modules/bar_module_time.rs index 38f680e..12d5c90 100644 --- a/src/bar_modules/bar_module_time.rs +++ b/src/bar_modules/bar_module_time.rs @@ -21,8 +21,12 @@ impl UnibarModuleTime { impl bar_modules::BarModuleActions for UnibarModuleTime { // -------------------- - fn generate_data(&mut self) { + fn clear(&mut self) { self.date_time = Local::now(); + } + + // -------------------- + fn generate_data(&mut self) { if self.opts.debug { println!("-----> Time dump {:#?}", self.date_time); } diff --git a/src/bar_modules/bar_module_weather.rs b/src/bar_modules/bar_module_weather.rs index a24d8e7..e56ebc6 100644 --- a/src/bar_modules/bar_module_weather.rs +++ b/src/bar_modules/bar_module_weather.rs @@ -150,6 +150,11 @@ impl UnibarModuleWeather { impl bar_modules::BarModuleActions for UnibarModuleWeather { + // -------------------- + fn clear(&mut self) { + self.weather_info = json!(serde_json::Value::Null); + } + // -------------------- fn generate_data(&mut self) { // Print a web page onto stdout diff --git a/src/bar_modules/mod.rs b/src/bar_modules/mod.rs index 5da2397..a128b80 100644 --- a/src/bar_modules/mod.rs +++ b/src/bar_modules/mod.rs @@ -1,6 +1,9 @@ // -------------------- /// All Bar modules must implement the actions pub trait BarModuleActions { + /// Do necessary clean up before starting new fetch + fn clear(&mut self); + /// Do necessary processing to generate data for this bar module fn generate_data(&mut self); diff --git a/src/main.rs b/src/main.rs index 01dc06e..2ad53ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,13 +86,15 @@ impl Unibar { for md in &mut self.bar_modules_enabled { let mut mod_parts = Vec::new(); - // Each bar module implements following 3 steps: + // Each bar module implements following 4 steps: + // * Clear data from previous iteration // * Generate raw data with pertinent information // * Return a unicode icon to be displayed // * Return a String content to be displayed after the icon // // Following generates ICON+CONTENT string for a module to be displayed // in the bar + md.clear(); md.generate_data(); mod_parts.push(md.get_icon()); mod_parts.push(md.get_content());