[[package]]
name = "swaybar_info"
-version = "0.1.4"
+version = "0.1.5"
dependencies = [
"chrono",
"regex",
[package]
name = "swaybar_info"
-version = "0.1.4"
+version = "0.1.5"
edition = "2021"
description = "Provides swaybar with info to be displayed"
license = "MIT"
## Upcoming Changes
+## 0.1.5
+
+Implemented `--netdev_width=<width>` which sets the minimum width of the netdev
+byte/KiB/MiB text displays.
+
+Implemented `--netgraph_max_bytes=<bytes>` which displays a graph in text using
+Unicode "Block Elements" symbols. The `<bytes>` 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 `<bytes>` 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<String>` instead of an `Option<u16>`
+for `min_width`.
+
## 0.1.4
Implemented advanced usage of `--regex-cmd=...` such that output text and output
## Help Text
Usage:
- -h | --help Prints help
- --netdev=<device_name> Check network traffic on specified device
- --interval-sec=<seconds> Output at intervals of <seconds> (default 5)
- --acpi-builtin Use "acpi -b" built-in fetching (battery info, with color)
- --regex-cmd=<cmd>[SPLIT]<args...>[SPLIT]<regex> Use an output of a command as a metric
- --time-format=<date format string> Set the format string for the date
+ -h | --help Prints help
+ --netdev=<device_name> Check network traffic on specified device
+ --netdev_width=<width> Sets the min-width of the netdev output (default 10)
+ --netgraph_max_bytes=<bytes> Enable "graph" output when polling network traffic
+ --interval-sec=<seconds> Output at intervals of <seconds> (default 5)
+ --acpi-builtin Use "acpi -b" built-in fetching (battery info, with color)
+ --regex-cmd=<cmd>[SPLIT]<args...>[SPLIT]<regex> Use an output of a command as a metric
+ --time-format=<date format string> Set the format string for the date
## Usage
} 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());
stderr_handle
.write_all(b" --netdev=<device_name>\t\t\t\tCheck network traffic on specified device\n")
.ok();
+ stderr_handle
+ .write_all(b" --netdev_width=<width>\t\t\t\tSets the min-width of the netdev output (default 10)\n")
+ .ok();
+ stderr_handle
+ .write_all(b" --netgraph_max_bytes=<bytes>\t\t\t\tEnable \"graph\" output when polling network traffic\n")
+ .ok();
stderr_handle
.write_all(
b" --interval-sec=<seconds>\t\t\t\tOutput at intervals of <seconds> (default 5)\n",
.ok();
stderr_handle
.write_all(
- b" --date-format=<date format string>\t\t\tSet the format string for the date\n",
+ b" --time-format=<date format string>\t\t\tSet the format string for the date\n",
)
.ok();
}
}
let mut net_obj: Option<proc::NetInfo> = None;
+ let mut net_width: Option<u16> = Some(10);
+ let mut net_graph_max: Option<f64> = 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<u16, _> = 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<f64, _> = 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<i64, _> = args_result.map.get("interval-sec").unwrap().parse();
if let Ok(seconds_value) = seconds {
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<f64>| {
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);
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());
let handle_net = |is_empty: bool,
net: &mut proc::NetInfo,
- array: &mut SwaybarArray|
+ array: &mut SwaybarArray,
+ graph_opt: &Option<f64>,
+ width: &Option<u16>|
-> 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<String> = 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);
}
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]));
// 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);
}
}
pub struct NetInfo {
dev_name: String,
+ graph: String,
down: u64,
prev_down: u64,
up: u64,
pub fn new(dev_name: String) -> Self {
Self {
dev_name,
+ graph: String::from(" "),
down: 0,
prev_down: 0,
up: 0,
Ok(())
}
- pub fn get_netstring(&mut self) -> Result<String, Error> {
+ pub fn get_netstring(&mut self, graph_max: Option<f64>) -> 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;
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()))
}
}
#[serde(skip_serializing_if = "Option::is_none")]
pub border_right: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
- pub min_width: Option<u16>,
+ pub min_width: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub align: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]