Compare commits

...

2 Commits

Author SHA1 Message Date
7245914da8 Added mechanism to skip updates in a module
* This is useful in modules where HTTP API calls are made. Updating them
  every second is expensive, network intensive and can cause rate limits
  to be hit
* Added get_name() function to modules for easier debug statements
2025-06-14 17:33:24 -07:00
e8ab11eff9 More null handling in weather API responses 2025-06-14 16:55:26 -07:00
11 changed files with 98 additions and 4 deletions

View File

@@ -116,6 +116,11 @@ impl UnibarModuleCpu {
impl bar_modules::BarModuleActions for UnibarModuleCpu { impl bar_modules::BarModuleActions for UnibarModuleCpu {
// --------------------
fn get_name(&self) -> String {
return "UnibarModuleCpu".to_string();
}
// -------------------- // --------------------
fn clear(&mut self) { fn clear(&mut self) {
self.cpu_times_sample_1 = CpuTimes::new(); self.cpu_times_sample_1 = CpuTimes::new();

View File

@@ -20,6 +20,11 @@ impl UnibarModuleDate {
impl bar_modules::BarModuleActions for UnibarModuleDate { impl bar_modules::BarModuleActions for UnibarModuleDate {
// --------------------
fn get_name(&self) -> String {
return "UnibarModuleDate".to_string();
}
// -------------------- // --------------------
fn clear(&mut self) { fn clear(&mut self) {
self.date_time = Local::now(); self.date_time = Local::now();

View File

@@ -25,6 +25,11 @@ impl UnibarModuleMemory {
impl bar_modules::BarModuleActions for UnibarModuleMemory { impl bar_modules::BarModuleActions for UnibarModuleMemory {
// --------------------
fn get_name(&self) -> String {
return "UnibarModuleMemory".to_string();
}
// -------------------- // --------------------
fn clear(&mut self) { fn clear(&mut self) {
self.meminfo_str = "".to_string(); self.meminfo_str = "".to_string();

View File

@@ -25,6 +25,11 @@ impl UnibarModuleMusic {
impl bar_modules::BarModuleActions for UnibarModuleMusic { impl bar_modules::BarModuleActions for UnibarModuleMusic {
// --------------------
fn get_name(&self) -> String {
return "UnibarModuleMusic".to_string();
}
// -------------------- // --------------------
fn clear(&mut self) { fn clear(&mut self) {
self.current_stdout = "".to_string(); self.current_stdout = "".to_string();

View File

@@ -26,6 +26,11 @@ impl UnibarModuleNetwork {
impl bar_modules::BarModuleActions for UnibarModuleNetwork { impl bar_modules::BarModuleActions for UnibarModuleNetwork {
// --------------------
fn get_name(&self) -> String {
return "UnibarModuleNetwork".to_string();
}
// -------------------- // --------------------
fn clear(&mut self) { fn clear(&mut self) {
self.network_info = json!(serde_json::Value::Null); self.network_info = json!(serde_json::Value::Null);

View File

@@ -38,6 +38,11 @@ impl UnibarModulePower {
impl bar_modules::BarModuleActions for UnibarModulePower { impl bar_modules::BarModuleActions for UnibarModulePower {
// --------------------
fn get_name(&self) -> String {
return "UnibarModulePower".to_string();
}
// -------------------- // --------------------
fn clear(&mut self) { fn clear(&mut self) {
self.power_info = PowerData::new(); self.power_info = PowerData::new();

View File

@@ -23,6 +23,11 @@ impl UnibarModuleTime {
impl bar_modules::BarModuleActions for UnibarModuleTime { impl bar_modules::BarModuleActions for UnibarModuleTime {
// --------------------
fn get_name(&self) -> String {
return "UnibarModuleTime".to_string();
}
// -------------------- // --------------------
fn clear(&mut self) { fn clear(&mut self) {
self.date_time = Local::now(); self.date_time = Local::now();

View File

@@ -5,12 +5,14 @@ use serde_json::Value;
use regex::Regex; use regex::Regex;
use crate::common; use crate::common;
use crate::common::UpdateResult;
use crate::bar_modules; use crate::bar_modules;
#[derive(Clone)] #[derive(Clone)]
pub struct UnibarModuleWeather { pub struct UnibarModuleWeather {
opts: common::AppOptions, opts: common::AppOptions,
weather_info: Value, weather_info: Value,
update_cnt: u32,
} }
impl UnibarModuleWeather { impl UnibarModuleWeather {
@@ -20,6 +22,7 @@ impl UnibarModuleWeather {
UnibarModuleWeather { UnibarModuleWeather {
opts: o, opts: o,
weather_info: json!(serde_json::Value::Null), weather_info: json!(serde_json::Value::Null),
update_cnt: 0,
} }
} }
@@ -36,6 +39,7 @@ impl UnibarModuleWeather {
.to_string().parse().unwrap(); .to_string().parse().unwrap();
} }
} }
match self.opts.weather_units { match self.opts.weather_units {
common::TemperatureUnits::Metric => return deg_c, common::TemperatureUnits::Metric => return deg_c,
common::TemperatureUnits::Imperial => return (deg_c * 9.0 / 5.0) + 32.0, common::TemperatureUnits::Imperial => return (deg_c * 9.0 / 5.0) + 32.0,
@@ -158,6 +162,23 @@ impl UnibarModuleWeather {
impl bar_modules::BarModuleActions for UnibarModuleWeather { impl bar_modules::BarModuleActions for UnibarModuleWeather {
// --------------------
fn get_name(&self) -> String {
return "UnibarModuleWeather".to_string();
}
// --------------------
// Weather update every 60 cycles
fn should_update(&mut self) -> UpdateResult {
if self.update_cnt == 0 {
self.update_cnt = 300;
return UpdateResult::Update;
} else {
self.update_cnt -= 1;
return UpdateResult::Skip;
}
}
// -------------------- // --------------------
fn clear(&mut self) { fn clear(&mut self) {
self.weather_info = json!(serde_json::Value::Null); self.weather_info = json!(serde_json::Value::Null);
@@ -203,6 +224,10 @@ impl bar_modules::BarModuleActions for UnibarModuleWeather {
"".to_string() "".to_string()
}); });
self.weather_info = serde_json::from_str(curl_reg_str.as_str()).unwrap(); self.weather_info = serde_json::from_str(curl_reg_str.as_str()).unwrap();
if self.weather_info["features"][0]["properties"]["temperature"]["value"] == serde_json::Value::Null {
self.weather_info = serde_json::Value::Null;
}
} }
} }

View File

@@ -1,6 +1,11 @@
use crate::common::UpdateResult;
// -------------------- // --------------------
/// All Bar modules must implement the actions /// All Bar modules must implement the actions
pub trait BarModuleActions { pub trait BarModuleActions {
/// Return String with name of the module
fn get_name(&self) -> String;
/// Do necessary clean up before starting new fetch /// Do necessary clean up before starting new fetch
fn clear(&mut self); fn clear(&mut self);
@@ -13,6 +18,12 @@ pub trait BarModuleActions {
/// Return a Unicode icon to display before content in the bar. /// Return a Unicode icon to display before content in the bar.
/// This icon may differ based on content of the data /// This icon may differ based on content of the data
fn get_icon(&self) -> String; fn get_icon(&self) -> String;
/// Returns UpdateResult depending on whether the module
/// should be updated during the current update cycle
fn should_update(&mut self) -> UpdateResult {
return UpdateResult::Update;
}
} }
pub trait BarModuleDebug { pub trait BarModuleDebug {

View File

@@ -18,6 +18,12 @@ impl fmt::Display for TemperatureUnits {
} }
} }
#[derive(Debug,PartialEq,Eq,Copy,Clone)]
pub enum UpdateResult {
Update,
Skip
}
// -------------------- // --------------------
// Application options // Application options
// -------------------- // --------------------
@@ -29,4 +35,5 @@ pub struct AppOptions {
pub music_progress: bool, pub music_progress: bool,
pub debug: bool, pub debug: bool,
pub debug_modules: bool, pub debug_modules: bool,
pub debug_update: bool,
} }

View File

@@ -2,6 +2,7 @@ use std::str;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use clap::Parser; use clap::Parser;
use crate::common::UpdateResult;
// Common utilities/types // Common utilities/types
mod common; mod common;
@@ -17,7 +18,7 @@ mod bar_modules;
suitable to use in a status bar")] suitable to use in a status bar")]
struct CommandlineArgs { struct CommandlineArgs {
/// Update interval in seconds /// Update interval in seconds
#[arg(short = 'i', long, default_value = "5")] #[arg(short = 'i', long, default_value = "1")]
interval: u64, interval: u64,
/// Name of the weather station /// Name of the weather station
@@ -40,6 +41,11 @@ struct CommandlineArgs {
/// but before output is printed /// but before output is printed
#[arg(short = 'M', long)] #[arg(short = 'M', long)]
debug_modules: bool, debug_modules: bool,
/// Show module debug information after all modules are evaluated
/// but before output is printed
#[arg(short = 'U', long)]
debug_update: bool,
} }
// //
@@ -95,8 +101,17 @@ impl Unibar {
// //
// Following generates ICON+CONTENT string for a module to be displayed // Following generates ICON+CONTENT string for a module to be displayed
// in the bar // in the bar
match md.should_update() {
UpdateResult::Update => {
md.clear(); md.clear();
md.generate_data(); md.generate_data();
}
UpdateResult::Skip => {
if self.opts.debug_update {
println!("Skipping module {}", md.get_name());
}
}
}
mod_parts.push(md.get_icon()); mod_parts.push(md.get_icon());
mod_parts.push(md.get_content()); mod_parts.push(md.get_content());
@@ -162,6 +177,7 @@ fn main() {
music_progress: cmd_args.music_progress, music_progress: cmd_args.music_progress,
debug: cmd_args.debug, debug: cmd_args.debug,
debug_modules: cmd_args.debug_modules, debug_modules: cmd_args.debug_modules,
debug_update: cmd_args.debug_update,
}, },
bar_modules_enabled: Vec::new(), bar_modules_enabled: Vec::new(),
debug_modules_done: false, debug_modules_done: false,