diff --git a/Cargo.lock b/Cargo.lock index 77a996b..412cfc0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,7 +141,7 @@ dependencies = [ [[package]] name = "swaybar_info" -version = "0.1.4" +version = "0.1.5" dependencies = [ "chrono", "regex", diff --git a/Cargo.toml b/Cargo.toml index b957779..94a8a1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "swaybar_info" -version = "0.1.4" +version = "0.1.5" edition = "2021" description = "Provides swaybar with info to be displayed" license = "MIT" diff --git a/Changelog.md b/Changelog.md index 819fc99..9d25a55 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,23 @@ ## Upcoming Changes +## 0.1.5 + +Implemented `--netdev_width=` which sets the minimum width of the netdev +byte/KiB/MiB text displays. + +Implemented `--netgraph_max_bytes=` which displays a graph in text using +Unicode "Block Elements" symbols. The `` argument determines the maximum +amount of bytes that will determine which block-character is printed on the +interval. The graph is always 10 characters wide, and the right side is the +most-recent side. Note that this always checks against the maximum of either +download or upload rates. For example, if `` is set to 1024, and 128 +bytes were downloaded and 512 bytes were uploaded in an interval, the "Lower +Half Block" Unicode symbol will be emitted (exactly half). + +SwaybarObject was changed to use an `Option` instead of an `Option` +for `min_width`. + ## 0.1.4 Implemented advanced usage of `--regex-cmd=...` such that output text and output diff --git a/README.md b/README.md index 8a2af85..9e76d67 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,14 @@ tiling Wayland compositor](https://swaywm.org). ## Help Text Usage: - -h | --help Prints help - --netdev= Check network traffic on specified device - --interval-sec= Output at intervals of (default 5) - --acpi-builtin Use "acpi -b" built-in fetching (battery info, with color) - --regex-cmd=[SPLIT][SPLIT] Use an output of a command as a metric - --time-format= Set the format string for the date + -h | --help Prints help + --netdev= Check network traffic on specified device + --netdev_width= Sets the min-width of the netdev output (default 10) + --netgraph_max_bytes= Enable "graph" output when polling network traffic + --interval-sec= Output at intervals of (default 5) + --acpi-builtin Use "acpi -b" built-in fetching (battery info, with color) + --regex-cmd=[SPLIT][SPLIT] Use an output of a command as a metric + --time-format= Set the format string for the date ## Usage diff --git a/src/args.rs b/src/args.rs index 352e684..2c548e2 100644 --- a/src/args.rs +++ b/src/args.rs @@ -19,6 +19,12 @@ pub fn get_args() -> ArgsResult { } else if arg.starts_with("--netdev=") { let (_, back) = arg.split_at(9); map.insert("netdev".into(), back.into()); + } else if arg.starts_with("--netdev_width=") { + let (_, back) = arg.split_at(15); + map.insert("netdevwidth".into(), back.into()); + } else if arg.starts_with("--netgraph_max_bytes=") { + let (_, back) = arg.split_at(21); + map.insert("netgraph".into(), back.into()); } else if arg.starts_with("--interval-sec=") { let (_, back) = arg.split_at(15); map.insert("interval-sec".into(), back.into()); @@ -52,6 +58,12 @@ pub fn print_usage() { stderr_handle .write_all(b" --netdev=\t\t\t\tCheck network traffic on specified device\n") .ok(); + stderr_handle + .write_all(b" --netdev_width=\t\t\t\tSets the min-width of the netdev output (default 10)\n") + .ok(); + stderr_handle + .write_all(b" --netgraph_max_bytes=\t\t\t\tEnable \"graph\" output when polling network traffic\n") + .ok(); stderr_handle .write_all( b" --interval-sec=\t\t\t\tOutput at intervals of (default 5)\n", @@ -69,7 +81,7 @@ pub fn print_usage() { .ok(); stderr_handle .write_all( - b" --date-format=\t\t\tSet the format string for the date\n", + b" --time-format=\t\t\tSet the format string for the date\n", ) .ok(); } diff --git a/src/main.rs b/src/main.rs index d858b08..23baf73 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,12 +44,44 @@ fn main() { } let mut net_obj: Option = None; + let mut net_width: Option = Some(10); + let mut net_graph_max: Option = None; let mut interval: Duration = Duration::from_secs(5); if args_result.map.contains_key("netdev") { net_obj = Some(proc::NetInfo::new( args_result.map.get("netdev").unwrap().to_owned(), )); } + if args_result.map.contains_key("netdevwidth") { + let width_result: Result = args_result.map.get("netdevwidth").unwrap().parse(); + if let Ok(width) = width_result { + net_width = Some(width); + } else { + let mut stderr_handle = io::stderr().lock(); + stderr_handle + .write_all( + format!("WARNING: Invalid value passed to --netdev_width=..., ignoring...\n") + .as_bytes(), + ) + .ok(); + } + } + if args_result.map.contains_key("netgraph") { + let graph_max_result: Result = args_result.map.get("netgraph").unwrap().parse(); + if let Ok(graph_max) = graph_max_result { + net_graph_max = Some(graph_max); + } else { + let mut stderr_handle = io::stderr().lock(); + stderr_handle + .write_all( + format!( + "WARNING: Invalid value passed to --netgraph_max_bytes=..., ignoring...\n" + ) + .as_bytes(), + ) + .ok(); + } + } if args_result.map.contains_key("interval-sec") { let seconds: Result = args_result.map.get("interval-sec").unwrap().parse(); if let Ok(seconds_value) = seconds { @@ -92,8 +124,15 @@ fn main() { println!("["); let mut array = SwaybarArray::new(); - let set_net_error = |is_empty: bool, array: &mut SwaybarArray| { + let set_net_error = |is_empty: bool, array: &mut SwaybarArray, graph_max_opt: &Option| { if is_empty { + if graph_max_opt.is_some() { + array.push_object(SwaybarObject::from_error_string( + "net_graph".to_owned(), + "net ERROR".into(), + )); + } + let down_obj = SwaybarObject::from_error_string("net_down".to_owned(), "Net ERROR".into()); array.push_object(down_obj); @@ -101,6 +140,12 @@ fn main() { let up_obj = SwaybarObject::from_error_string("net_up".to_owned(), "Net ERROR".into()); array.push_object(up_obj); } else { + if graph_max_opt.is_some() { + if let Some(graph_ref) = array.get_by_name_mut("net_graph") { + graph_ref.update_as_error("Net ERROR".to_owned()); + } + } + let down_ref_opt = array.get_by_name_mut("net_down"); if let Some(down_ref) = down_ref_opt { down_ref.update_as_error("Net ERROR".to_owned()); @@ -115,19 +160,39 @@ fn main() { let handle_net = |is_empty: bool, net: &mut proc::NetInfo, - array: &mut SwaybarArray| + array: &mut SwaybarArray, + graph_opt: &Option, + width: &Option| -> Result<(), proc::Error> { net.update()?; - let netinfo_string = net.get_netstring()?; + let (netinfo_string, graph_string) = net.get_netstring(*graph_opt)?; let netinfo_parts: Vec<&str> = netinfo_string.split_whitespace().collect(); if is_empty { + if graph_opt.is_some() { + let mut graph_obj = + SwaybarObject::from_string("net_graph".to_owned(), graph_string); + graph_obj.color = Some("#ffff88".into()); + array.push_object(graph_obj); + } + + let mut width_string: Option = None; + if let Some(width) = *width { + let mut string = String::with_capacity(width.into()); + for _ in 0..width { + string.push('0'); + } + width_string = Some(string); + } + { let mut down_object = SwaybarObject::from_string( "net_down".to_owned(), format!("{} {}", netinfo_parts[0], netinfo_parts[1]), ); down_object.color = Some("#ff8888ff".into()); + down_object.min_width = width_string.clone(); + down_object.align = Some(String::from("right")); array.push_object(down_object); } @@ -137,9 +202,17 @@ fn main() { format!("{} {}", netinfo_parts[2], netinfo_parts[3]), ); up_object.color = Some("#88ff88ff".into()); + up_object.min_width = width_string; + up_object.align = Some(String::from("right")); array.push_object(up_object); } } else { + if graph_opt.is_some() { + if let Some(graph_obj) = array.get_by_name_mut("net_graph") { + graph_obj.full_text = graph_string; + } + } + if let Some(down_object) = array.get_by_name_mut("net_down") { down_object .update_as_net_down(format!("{} {}", netinfo_parts[0], netinfo_parts[1])); @@ -158,11 +231,11 @@ fn main() { // network traffic if let Some(net) = net_obj.as_mut() { - if let Err(e) = handle_net(is_empty, net, &mut array) { + if let Err(e) = handle_net(is_empty, net, &mut array, &net_graph_max, &net_width) { let mut stderr_handle = io::stderr().lock(); stderr_handle.write_all(format!("{}\n", e).as_bytes()).ok(); net_obj = None; - set_net_error(is_empty, &mut array); + set_net_error(is_empty, &mut array, &net_graph_max); } } diff --git a/src/proc.rs b/src/proc.rs index a4ac4a7..b4d9d3a 100644 --- a/src/proc.rs +++ b/src/proc.rs @@ -58,6 +58,7 @@ impl std::error::Error for Error { pub struct NetInfo { dev_name: String, + graph: String, down: u64, prev_down: u64, up: u64, @@ -68,6 +69,7 @@ impl NetInfo { pub fn new(dev_name: String) -> Self { Self { dev_name, + graph: String::from(" "), down: 0, prev_down: 0, up: 0, @@ -109,7 +111,7 @@ impl NetInfo { Ok(()) } - pub fn get_netstring(&mut self) -> Result { + pub fn get_netstring(&mut self, graph_max: Option) -> Result<(String, String), Error> { let down_diff: f64 = (self.down - self.prev_down) as f64; self.prev_down = self.down; let up_diff: f64 = (self.up - self.prev_up) as f64; @@ -132,7 +134,41 @@ impl NetInfo { write!(&mut output, "{:.0} B", up_diff)?; } - Ok(output) + if let Some(graph_max) = graph_max { + let diff_max = if down_diff > up_diff { + down_diff + } else { + up_diff + }; + let graph_value: u8 = if diff_max > graph_max { + 8 + } else { + (diff_max / graph_max * 8.0f64) as u8 + }; + let mut first = true; + let mut new_graph_string = String::with_capacity(10); + for current_char in self.graph.chars() { + if first { + first = false; + continue; + } + new_graph_string.push(current_char); + } + match graph_value { + 0 => new_graph_string.push(' '), + 1 => new_graph_string.push('▁'), + 2 => new_graph_string.push('▂'), + 3 => new_graph_string.push('▃'), + 4 => new_graph_string.push('▄'), + 5 => new_graph_string.push('▅'), + 6 => new_graph_string.push('▆'), + 7 => new_graph_string.push('▇'), + _ => new_graph_string.push('█'), + } + self.graph = new_graph_string; + } + + Ok((output, self.graph.clone())) } } diff --git a/src/swaybar_object.rs b/src/swaybar_object.rs index 4da5e50..c21c57e 100644 --- a/src/swaybar_object.rs +++ b/src/swaybar_object.rs @@ -38,7 +38,7 @@ pub struct SwaybarObject { #[serde(skip_serializing_if = "Option::is_none")] pub border_right: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub min_width: Option, + pub min_width: Option, #[serde(skip_serializing_if = "Option::is_none")] pub align: Option, #[serde(skip_serializing_if = "Option::is_none")]