Move datetime to widgets subdir and import i3monkit network.
This commit is contained in:
parent
1a2ad57826
commit
f09145eccd
2
src/widgets/mod.rs
Normal file
2
src/widgets/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod datetime;
|
||||
pub mod network;
|
||||
138
src/widgets/network.rs
Normal file
138
src/widgets/network.rs
Normal file
@ -0,0 +1,138 @@
|
||||
use i3monkit::Block;
|
||||
use i3monkit::{Widget, WidgetUpdate};
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, Error, ErrorKind, Result};
|
||||
use std::time::SystemTime;
|
||||
|
||||
const NETWORK_PATH_PREFIX: &'static str = "/sys/class/net";
|
||||
const NETWORK_STAT_SUFFIX: &'static str = "statistics/dummy";
|
||||
|
||||
struct TransferStat {
|
||||
rx: u64,
|
||||
tx: u64,
|
||||
ts: SystemTime,
|
||||
}
|
||||
|
||||
impl TransferStat {
|
||||
fn read_stat(interface: &str) -> Result<Self> {
|
||||
let mut path = PathBuf::new();
|
||||
path.push(format!(
|
||||
"{}/{}/{}",
|
||||
NETWORK_PATH_PREFIX, interface, NETWORK_STAT_SUFFIX
|
||||
));
|
||||
|
||||
let mut read_stat_file = move |what: &str| {
|
||||
path.set_file_name(what);
|
||||
|
||||
let reader = BufReader::new(File::open(path.as_path())?);
|
||||
|
||||
if let Some(line) = reader.lines().next() {
|
||||
return line;
|
||||
}
|
||||
|
||||
return Err(Error::new(ErrorKind::Other, "Empty file"));
|
||||
};
|
||||
|
||||
let rx = u64::from_str_radix(&(read_stat_file("rx_bytes")?), 10).unwrap();
|
||||
let tx = u64::from_str_radix(&(read_stat_file("tx_bytes")?), 10).unwrap();
|
||||
let ts = SystemTime::now();
|
||||
|
||||
return Ok(Self { rx, tx, ts });
|
||||
}
|
||||
|
||||
fn duration(&self, earlier: &Self) -> f64 {
|
||||
let duration = self.ts.duration_since(earlier.ts).unwrap();
|
||||
let secs = duration.as_secs() as f64 + duration.subsec_nanos() as f64 / 1_000_000_000.0;
|
||||
return secs;
|
||||
}
|
||||
|
||||
fn rx_rate(&self, earlier: &Self) -> f64 {
|
||||
let duration = self.duration(earlier);
|
||||
if duration < 1e-5 {
|
||||
return std::f64::NAN;
|
||||
}
|
||||
|
||||
return (self.rx - earlier.rx) as f64 / duration;
|
||||
}
|
||||
|
||||
fn tx_rate(&self, earlier: &Self) -> f64 {
|
||||
let duration = self.duration(earlier);
|
||||
if duration < 1e-5 {
|
||||
return std::f64::NAN;
|
||||
}
|
||||
|
||||
return (self.tx - earlier.tx) as f64 / duration;
|
||||
}
|
||||
}
|
||||
|
||||
/// A widget that shows the network speed realtimely
|
||||
pub struct NetworkSpeedWidget {
|
||||
interface: String,
|
||||
last_stat: TransferStat,
|
||||
}
|
||||
|
||||
impl NetworkSpeedWidget {
|
||||
/// Create the widget, for given interface.
|
||||
///
|
||||
/// **interface** The interface to monitor
|
||||
pub fn new(interface: &str) -> Self {
|
||||
let last_stat = TransferStat::read_stat(interface).unwrap();
|
||||
let interface = interface.to_string();
|
||||
Self {
|
||||
last_stat,
|
||||
interface,
|
||||
}
|
||||
}
|
||||
|
||||
fn format_rate(rate: f64) -> String {
|
||||
if rate.is_nan() {
|
||||
return "N/A".to_string();
|
||||
}
|
||||
|
||||
const UNIT_NAME: [&'static str; 6] = [" B/s", "KB/s", "MB/s", "GB/s", "TB/s", "PB/s"];
|
||||
|
||||
let mut best_unit = UNIT_NAME[0];
|
||||
let mut best_multiplier = 1.0;
|
||||
|
||||
for unit in UNIT_NAME[1..].iter() {
|
||||
if best_multiplier > rate / 1024.0 {
|
||||
break;
|
||||
}
|
||||
best_unit = unit;
|
||||
best_multiplier *= 1024.0
|
||||
}
|
||||
|
||||
let ret = format!("{:6.1}{}", rate / best_multiplier, best_unit);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn get_human_readable_stat(&mut self) -> Result<(String, String)> {
|
||||
let cur_stat = TransferStat::read_stat(&self.interface)?;
|
||||
|
||||
let rx_rate = cur_stat.rx_rate(&self.last_stat);
|
||||
let tx_rate = cur_stat.tx_rate(&self.last_stat);
|
||||
|
||||
self.last_stat = cur_stat;
|
||||
|
||||
return Ok((Self::format_rate(rx_rate), Self::format_rate(tx_rate)));
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for NetworkSpeedWidget {
|
||||
fn update(&mut self) -> Option<WidgetUpdate> {
|
||||
if let Ok((rx, tx)) = self.get_human_readable_stat() {
|
||||
let mut data = Block::new();
|
||||
data.use_pango();
|
||||
data.append_full_text(&format!("Rx:<tt>{}</tt> Tx:<tt>{}</tt>", rx, tx));
|
||||
return Some(WidgetUpdate {
|
||||
refresh_interval: std::time::Duration::new(1, 0),
|
||||
data: Some(data),
|
||||
});
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user