Add AllNetworkSpeedWidget to show any usage on enp devices

This commit is contained in:
Bill Thiede 2023-07-30 13:31:12 -07:00
parent fefc331dbc
commit 44c0c21018

View File

@ -1,16 +1,18 @@
use i3monkit::Block; use std::{
use i3monkit::{Widget, WidgetUpdate}; collections::vec_deque::VecDeque,
fs::File,
io::{BufRead, BufReader, Error, ErrorKind, Result},
path::PathBuf,
time::SystemTime,
};
use std::collections::vec_deque::VecDeque; use i3monkit::{Block, Widget, WidgetUpdate};
use std::fs::File;
use std::io::{BufRead, BufReader, Error, ErrorKind, Result};
use std::path::PathBuf;
use std::time::SystemTime;
use crate::spark; use crate::spark;
const NETWORK_PATH_PREFIX: &str = "/sys/class/net"; const NETWORK_PATH_PREFIX: &str = "/sys/class/net";
const NETWORK_STAT_SUFFIX: &str = "statistics/dummy"; const NETWORK_STAT_SUFFIX: &str = "statistics/dummy";
const DEVICE_PREFIX: &str = "enp";
struct TransferStat { struct TransferStat {
rx: u64, rx: u64,
@ -94,6 +96,12 @@ impl NetworkSpeedWidget {
} }
} }
fn is_active(&self) -> bool {
self.last_stat.rx > 0
|| self.last_stat.tx > 0
|| (self.rx_history.iter().sum::<f32>() + self.tx_history.iter().sum::<f32>()) > 0.
}
fn format_rate(rate: f64) -> String { fn format_rate(rate: f64) -> String {
if rate.is_nan() { if rate.is_nan() {
return "N/A".to_string(); return "N/A".to_string();
@ -129,12 +137,9 @@ impl NetworkSpeedWidget {
Ok((Self::format_rate(rx_rate), Self::format_rate(tx_rate))) Ok((Self::format_rate(rx_rate), Self::format_rate(tx_rate)))
} }
}
impl Widget for NetworkSpeedWidget { fn render(&mut self) -> Option<String> {
fn update(&mut self) -> Option<WidgetUpdate> {
if let Ok((rx, tx)) = self.get_human_readable_stat() { if let Ok((rx, tx)) = self.get_human_readable_stat() {
let mut data = Block::new();
let (rx_history, tx_history) = if self.rx_history.len() > 1 { let (rx_history, tx_history) = if self.rx_history.len() > 1 {
let g = spark::Graph { let g = spark::Graph {
min: None, min: None,
@ -147,11 +152,21 @@ impl Widget for NetworkSpeedWidget {
} else { } else {
("".to_string(), "".to_string()) ("".to_string(), "".to_string())
}; };
data.use_pango(); return Some(format!(
data.append_full_text(&format!(
"Rx:<tt>{} {}</tt> Tx:<tt>{} {}</tt>", "Rx:<tt>{} {}</tt> Tx:<tt>{} {}</tt>",
rx, rx_history, tx, tx_history rx, rx_history, tx, tx_history
)); ));
}
None
}
}
impl Widget for NetworkSpeedWidget {
fn update(&mut self) -> Option<WidgetUpdate> {
if let Some(text) = self.render() {
let mut data = Block::new();
data.use_pango();
data.append_full_text(&text);
return Some(WidgetUpdate { return Some(WidgetUpdate {
refresh_interval: std::time::Duration::new(1, 0), refresh_interval: std::time::Duration::new(1, 0),
data: Some(data), data: Some(data),
@ -160,3 +175,56 @@ impl Widget for NetworkSpeedWidget {
None None
} }
} }
pub struct AllNetworkSpeedWidget {
num_samples: usize,
nics: Vec<NetworkSpeedWidget>,
}
impl AllNetworkSpeedWidget {
pub fn new(num_samples: usize) -> Self {
let nics = std::fs::read_dir(NETWORK_PATH_PREFIX)
.expect(&format!("couldn't list {NETWORK_PATH_PREFIX}"))
.filter_map(|dir| {
let d = dir.unwrap();
let p = d.file_name();
let p = p.to_string_lossy();
if p.starts_with(DEVICE_PREFIX) {
Some(NetworkSpeedWidget::new(&p, num_samples))
} else {
None
}
})
.collect();
AllNetworkSpeedWidget { num_samples, nics }
}
}
impl Widget for AllNetworkSpeedWidget {
fn update(&mut self) -> Option<WidgetUpdate> {
let nics: Vec<_> = self
.nics
.iter_mut()
.filter_map(|nic| {
if !nic.is_active() {
return None;
}
if let Some(text) = nic.render() {
Some(format!("{}: {}", nic.interface, text))
} else {
None
}
})
.collect();
let mut data = Block::new();
data.use_pango();
nics.iter().for_each(|n| {
data.append_full_text(n);
});
Some(WidgetUpdate {
refresh_interval: std::time::Duration::new(1, 0),
data: Some(data),
})
}
}