summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClement Tsang <34804052+ClementTsang@users.noreply.github.com>2021-01-01 18:09:28 -0500
committerGitHub <noreply@github.com>2021-01-01 18:09:28 -0500
commit90be9730a62e2a935ccf01cdd6e320c65624722a (patch)
treeb22a66210a2af97f0ced92dc27d89a6ad2137f63
parentd8d72d060d4bd4473bfe769673a2227bda948c97 (diff)
feature: Add network interface filtering (#381)
Adds a new option in the config file to filter out network interfaces. Also add the option to filter by whole words. Interface follows that of the existing ones: ```toml [net_filter] is_list_ignored = false list = ["virbr0.*"] regex = true case_sensitive = false whole_word = false ```
-rw-r--r--.vscode/settings.json2
-rw-r--r--CHANGELOG.md2
-rw-r--r--README.md20
-rw-r--r--assets/temp_filter_post3.pngbin0 -> 85155 bytes
-rw-r--r--sample_configs/demo_config.toml16
-rw-r--r--src/app.rs4
-rw-r--r--src/app/data_harvester.rs23
-rw-r--r--src/app/data_harvester/disks.rs113
-rw-r--r--src/app/data_harvester/network.rs44
-rw-r--r--src/app/data_harvester/temperature.rs116
-rw-r--r--src/bin/main.rs4
-rw-r--r--src/constants.rs9
-rw-r--r--src/data_conversion.rs67
-rw-r--r--src/lib.rs5
-rw-r--r--src/options.rs16
15 files changed, 257 insertions, 184 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 6002bb85..9a10ba3f 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -65,6 +65,7 @@
"hjkl",
"htop",
"indexmap",
+ "iwlwifi",
"keybinds",
"le",
"libc",
@@ -112,6 +113,7 @@
"use",
"use curr usage",
"utime",
+ "virbr",
"virt",
"vsize",
"whitespaces",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5db3e343..de00824c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#379](https://github.com/ClementTsang/bottom/pull/379): Adds `--process_command` flag and corresponding config option to default to showing a process' command.
+- [#381](https://github.com/ClementTsang/bottom/pull/381): Adds a filter in the config file for network interfaces.
+
## Changes
- [#372](https://github.com/ClementTsang/bottom/pull/372): Hides the SWAP graph and legend in normal mode if SWAP is 0.
diff --git a/README.md b/README.md
index 943a001e..8adbc580 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ A cross-platform graphical process/system monitor with a customizable interface
- [Config flags](#config-flags)
- [Theming](#theming)
- [Layout](#layout)
- - [Disk and temperature filtering](#disk-and-temperature-filtering)
+ - [Disk and temperature filtering](#disk-temperature-and-network-filtering)
- [Battery](#battery)
- [Compatibility](#compatibility)
- [FAQ](#faq)
@@ -670,9 +670,9 @@ Furthermore, you can have duplicate widgets. This means you could do something l
and get the following CPU donut:
![CPU donut](./assets/cpu_layout.png)
-#### Disk and temperature filtering
+#### Disk, temperature, and network filtering
-You can hide specific disks and temperature sensors by name in the config file via `disk_filter` and `temp_filter` respectively. Regex (`regex = true`) and case-sensitivity (`case_sensitive = true`) are supported, but are off by default.
+You can hide specific disks, temperature sensors, and networks by name in the config file via `disk_filter`, `temp_filter`, and `net_filter` respectively. Regex (`regex = true`), case-sensitivity (`case_sensitive = true`), and matching only the entire word (`whole_word = true`) are supported, but are off by default.
For example, let's say , given this disk list:
@@ -712,6 +712,20 @@ Now, flipping to `case_sensitive = false` would instead show:
![Temp filter after with case sensitivity off](./assets/temp_filter_post2.png)
+Lastly, let's say I want to filter out _exactly_ "iwlwifi_1" from my results. I could do:
+
+```toml
+[temp_filter]
+is_list_ignored = true
+list = ["iwlwifi_1"]
+case_sensitive = true
+whole_word = true
+```
+
+This will match the entire word, "iwlwifi_1", and ignore any result that exactly matches it:
+
+![Temp filter after with whole_word](./assets/temp_filter_post3.png)
+
### Battery
You can get battery statistics (charge, time to fill/discharge, consumption in watts, and battery health) via the battery widget.
diff --git a/assets/temp_filter_post3.png b/assets/temp_filter_post3.png
new file mode 100644
index 00000000..f84886d1
--- /dev/null
+++ b/assets/temp_filter_post3.png
Binary files differ
diff --git a/sample_configs/demo_config.toml b/sample_configs/demo_config.toml
index f7fcb6b0..e6c5cf71 100644
--- a/sample_configs/demo_config.toml
+++ b/sample_configs/demo_config.toml
@@ -13,19 +13,3 @@ whole_word = false
regex = true
default_widget_type = "cpu"
default_widget_count = 1
-
-[colors]
-# Based on gruvbox: https://github.com/morhetz/gruvbox
-table_header_color="#458588"
-widget_title_color="#cc241d"
-cpu_core_colors=["#cc241d", "#98971a", "#d79921", "#458588", "#b16286", "#689d6a", "#fb4934", "#b8bb26", "#fabd2f", "#83a598"]
-ram_color="#fb4934"
-swap_color="#fabd2f"
-rx_color="#458588"
-tx_color="#689d6a"
-border_color="#ebdbb2"
-highlighted_border_color="#fe8019"
-text_color="#ebdbb2"
-graph_color="#ebdbb2"
-selected_text_color="#282828"
-selected_bg_color="#458588"
diff --git a/src/app.rs b/src/app.rs
index 7fae7cf0..5b2dbe90 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -57,12 +57,14 @@ pub struct AppConfigFields {
}
/// For filtering out information
+#[derive(Debug, Clone)]
pub struct DataFilters {
pub disk_filter: Option<Filter>,
pub temp_filter: Option<Filter>,
+ pub net_filter: Option<Filter>,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct Filter {
pub is_list_ignored: bool,
pub list: Vec<regex::Regex>,
diff --git a/src/app/data_harvester.rs b/src/app/data_harvester.rs
index 63d9a07c..0fc8c6a5 100644
--- a/src/app/data_harvester.rs
+++ b/src/app/data_harvester.rs
@@ -14,6 +14,8 @@ use crate::app::layout_manager::UsedWidgets;
use futures::join;
+use super::DataFilters;
+
pub mod batteries;
pub mod cpu;
pub mod disks;
@@ -96,15 +98,15 @@ pub struct DataCollector {
battery_list: Option<Vec<Battery>>,
#[cfg(target_os = "linux")]
page_file_size_kb: u64,
+ filters: DataFilters,
}
-impl Default for DataCollector {
- fn default() -> Self {
- // trace!("Creating default data collector...");
+impl DataCollector {
+ pub fn new(filters: DataFilters) -> Self {
DataCollector {
data: Data::default(),
#[cfg(not(target_os = "linux"))]
- sys: System::new_with_specifics(sysinfo::RefreshKind::new()), // FIXME: Make this run on only macOS and Windows.
+ sys: System::new_with_specifics(sysinfo::RefreshKind::new()),
#[cfg(target_os = "linux")]
previous_cpu_times: vec![],
#[cfg(target_os = "linux")]
@@ -132,11 +134,10 @@ impl Default for DataCollector {
// page_file_size_kb
libc::sysconf(libc::_SC_PAGESIZE) as u64 / 1024
},
+ filters,
}
}
-}
-impl DataCollector {
pub fn init(&mut self) {
#[cfg(target_os = "linux")]
{
@@ -147,6 +148,7 @@ impl DataCollector {
self.sys.refresh_memory();
self.mem_total_kb = self.sys.get_total_memory();
+ // TODO: Would be good to get this and network list running on a timer instead...?
// Refresh components list once...
if self.widgets_to_harvest.use_temp {
self.sys.refresh_components_list();
@@ -295,6 +297,7 @@ impl DataCollector {
&mut self.total_tx,
current_instant,
self.widgets_to_harvest.use_net,
+ &self.filters.net_filter,
)
}
#[cfg(not(target_os = "windows"))]
@@ -305,12 +308,14 @@ impl DataCollector {
&mut self.total_tx,
current_instant,
self.widgets_to_harvest.use_net,
+ &self.filters.net_filter,
)
}
};
let mem_data_fut = mem::get_mem_data(self.widgets_to_harvest.use_mem);
- let disk_data_fut = disks::get_disk_usage(self.widgets_to_harvest.use_disk);
- let disk_io_usage_fut = disks::get_io_usage(false, self.widgets_to_harvest.use_disk);
+ let disk_data_fut =
+ disks::get_disk_usage(self.widgets_to_harvest.use_disk, &self.filters.disk_filter);
+ let disk_io_usage_fut = disks::get_io_usage(self.widgets_to_harvest.use_disk);
let temp_data_fut = {
#[cfg(not(target_os = "linux"))]
{
@@ -318,6 +323,7 @@ impl DataCollector {
&self.sys,
&self.temperature_type,
self.widgets_to_harvest.use_temp,
+ &self.filters.temp_filter,
)
}
@@ -326,6 +332,7 @@ impl DataCollector {
temperature::get_temperature_data(
&self.temperature_type,
self.widgets_to_harvest.use_temp,
+ &self.filters.temp_filter,
)
}
};
diff --git a/src/app/data_harvester/disks.rs b/src/app/data_harvester/disks.rs
index 8c447a46..5a67a909 100644
--- a/src/app/data_harvester/disks.rs
+++ b/src/app/data_harvester/disks.rs
@@ -1,3 +1,5 @@
+use crate::app::Filter;
+
#[derive(Debug, Clone, Default)]
pub struct DiskHarvest {
pub name: String,
@@ -15,9 +17,7 @@ pub struct IOData {
pub type IOHarvest = std::collections::HashMap<String, Option<IOData>>;
-pub async fn get_io_usage(
- get_physical: bool, actually_get: bool,
-) -> crate::utils::error::Result<Option<IOHarvest>> {
+pub async fn get_io_usage(actually_get: bool) -> crate::utils::error::Result<Option<IOHarvest>> {
if !actually_get {
return Ok(None);
}
@@ -26,37 +26,23 @@ pub async fn get_io_usage(
let mut io_hash: std::collections::HashMap<String, Option<IOData>> =
std::collections::HashMap::new();
- if get_physical {
- let physical_counter_stream = heim::disk::io_counters_physical().await?;
- futures::pin_mut!(physical_counter_stream);
-
- while let Some(io) = physical_counter_stream.next().await {
- if let Ok(io) = io {
- let mount_point = io.device_name().to_str().unwrap_or("Name Unavailable");
- io_hash.insert(
- mount_point.to_string(),
- Some(IOData {
- read_bytes: io.read_bytes().get::<heim::units::information::megabyte>(),
- write_bytes: io.write_bytes().get::<heim::units::information::megabyte>(),
- }),
- );
- }
- }
- } else {
- let counter_stream = heim::disk::io_counters().await?;
- futures::pin_mut!(counter_stream);
-
- while let Some(io) = counter_stream.next().await {
- if let Ok(io) = io {
- let mount_point = io.device_name().to_str().unwrap_or("Name Unavailable");
- io_hash.insert(
- mount_point.to_string(),
- Some(IOData {
- read_bytes: io.read_bytes().get::<heim::units::information::byte>(),
- write_bytes: io.write_bytes().get::<heim::units::information::byte>(),
- }),
- );
- }
+
+ let counter_stream = heim::disk::io_counters().await?;
+ futures::pin_mut!(counter_stream);
+
+ while let Some(io) = counter_stream.next().await {
+ if let Ok(io) = io {
+ let mount_point = io.device_name().to_str().unwrap_or("Name Unavailable");
+
+ // FIXME: [MOUNT POINT] Add the filter here I guess?
+
+ io_hash.insert(
+ mount_point.to_string(),
+ Some(IOData {
+ read_bytes: io.read_bytes().get::<heim::units::information::byte>(),
+ write_bytes: io.write_bytes().get::<heim::units::information::byte>(),
+ }),
+ );
}
}
@@ -64,7 +50,7 @@ pub async fn get_io_usage(
}
pub async fn get_disk_usage(
- actually_get: bool,
+ actually_get: bool, name_filter: &Option<Filter>,
) -> crate::utils::error::Result<Option<Vec<DiskHarvest>>> {
if !actually_get {
return Ok(None);
@@ -77,26 +63,43 @@ pub async fn get_disk_usage(
futures::pin_mut!(partitions_stream);
while let Some(part) = partitions_stream.next().await {
- if let Ok(part) = part {
- let partition = part;
- let usage = heim::disk::usage(partition.mount_point().to_path_buf()).await?;
-
- vec_disks.push(DiskHarvest {
- free_space: usage.free().get::<heim::units::information::byte>(),
- used_space: usage.used().get::<heim::units::information::byte>(),
- total_space: usage.total().get::<heim::units::information::byte>(),
- mount_point: (partition
- .mount_point()
- .to_str()
- .unwrap_or("Name Unavailable"))
- .to_string(),
- name: (partition
- .device()
- .unwrap_or_else(|| std::ffi::OsStr::new("Name Unavailable"))
- .to_str()
- .unwrap_or("Name Unavailable"))
- .to_string(),
- });
+ if let Ok(partition) = part {
+ let name = (partition
+ .device()
+ .unwrap_or_else(|| std::ffi::OsStr::new("Name Unavailable"))
+ .to_str()
+ .unwrap_or("Name Unavailable"))
+ .to_string();
+
+ let mount_point = (partition
+ .mount_point()
+ .to_str()
+ .unwrap_or("Name Unavailable"))
+ .to_string();
+
+ let to_keep = if let Some(filter) = name_filter {
+ let mut ret = filter.is_list_ignored;
+ for r in &filter.list {
+ if r.is_match(&name) {
+ ret = !filter.is_list_ignored;
+ break;
+ }
+ }
+ ret
+ } else {
+ true
+ };
+
+ if to_keep {
+ let usage = heim::disk::usage(partition.mount_point().to_path_buf()).await?;
+ vec_disks.push(DiskHarvest {
+ free_space: usage.free().get::<heim::units::information::byte>(),
+ used_space: usage.used().get::<heim::units::information::byte>(),
+ total_space: usage.total().get::<heim::units::information::byte>(),
+ mount_point,
+ name,
+ });
+ }
}
}
diff --git a/src/app/data_harvester/network.rs b/src/app/data_harvester/network.rs
index dcb496cd..55d757f6 100644
--- a/src/app/data_harvester/network.rs
+++ b/src/app/data_harvester/network.rs
@@ -20,6 +20,7 @@ impl NetworkHarvest {
pub async fn get_network_data(
sys: &sysinfo::System, prev_net_access_time: Instant, prev_net_rx: &mut u64,
prev_net_tx: &mut u64, curr_time: Instant, actually_get: bool,
+ filter: &Option<crate::app::Filter>,
) -> crate::utils::error::Result<Option<NetworkHarvest>> {
use sysinfo::{NetworkExt, SystemExt};
@@ -31,9 +32,24 @@ pub async fn get_network_data(
let mut total_tx: u64 = 0;
let networks = sys.get_networks();
- for (_, network) in networks {
- total_rx += network.get_total_received();
- total_tx += network.get_total_transmitted();
+ for (name, network) in networks {
+ let to_keep = if let Some(filter) = filter {
+ let mut ret = filter.is_list_ignored;
+ for r in &filter.list {
+ if r.is_match(&name) {
+ ret = !filter.is_list_ignored;
+ break;
+ }
+ }
+ ret
+ } else {
+ true
+ };
+
+ if to_keep {
+ total_rx += network.get_total_received();
+ total_tx += network.get_total_transmitted();
+ }
}
let elapsed_time = curr_time.duration_since(prev_net_access_time).as_secs_f64();
@@ -57,10 +73,11 @@ pub async fn get_network_data(
}))
}
+// FIXME: Eventually make it so that this thing also takes individual usage into account, so we can allow for showing per-interface!
#[cfg(not(target_os = "windows"))]
pub async fn get_network_data(
prev_net_access_time: Instant, prev_net_rx: &mut u64, prev_net_tx: &mut u64,
- curr_time: Instant, actually_get: bool,
+ curr_time: Instant, actually_get: bool, filter: &Option<crate::app::Filter>,
) -> crate::utils::error::Result<Option<NetworkHarvest>> {
use futures::StreamExt;
@@ -75,8 +92,23 @@ pub async fn get_network_data(
while let Some(io) = io_data.next().await {
if let Ok(io) = io {
- total_rx += io.bytes_recv().get::<heim::units::information::byte>();
- total_tx += io.bytes_sent().get::<heim::units::information::byte>();
+ let to_keep = if let Some(filter) = filter {
+ let mut ret = filter.is_list_ignored;
+ for r in &filter.list {
+ if r.is_match(&io.interface()) {
+ ret = !filter.is_list_ignored;
+ break;
+ }
+ }
+ ret
+ } else {
+ true
+ };
+
+ if to_keep {
+ total_rx += io.bytes_recv().get::<heim::units::information::byte>();
+ total_tx += io.bytes_sent().get::<heim::units::information::byte>();
+ }
}
}
diff --git a/src/app/data_harvester/temperature.rs b/src/app/data_harvester/temperature.rs
index 512850c9..1c818e31 100644
--- a/src/app/data_harvester/temperature.rs
+++ b/src/app/data_harvester/temperature.rs
@@ -1,9 +1,10 @@
use std::cmp::Ordering;
+use crate::app::Filter;
+
#[derive(Default, Debug, Clone)]
pub struct TempHarvest {
- pub component_name: Option<String>,
- pub component_label: Option<String>,
+ pub name: String,
pub temperature: f32,
}
@@ -22,7 +23,7 @@ impl Default for TemperatureType {
#[cfg(not(target_os = "linux"))]
pub async fn get_temperature_data(
- sys: &sysinfo::System, temp_type: &TemperatureType, actually_get: bool,
+ sys: &sysinfo::System, temp_type: &TemperatureType, actually_get: bool, filter: &Option<Filter>,
) -> crate::utils::error::Result<Option<Vec<TempHarvest>>> {
use sysinfo::{ComponentExt, SystemExt};
@@ -42,17 +43,35 @@ pub async fn get_temperature_data(
let sensor_data = sys.get_components();
for component in sensor_data {
- temperature_vec.push(TempHarvest {
- component_name: None,
- component_label: Some(component.get_label().to_string()),
- temperature: match temp_type {
- TemperatureType::Celsius => component.get_temperature(),
- TemperatureType::Kelvin => convert_celsius_to_kelvin(component.get_temperature()),
- TemperatureType::Fahrenheit => {
- convert_celsius_to_fahrenheit(component.get_temperature())
+ let name = component.get_label().to_string();
+
+ let to_keep = if let Some(filter) = filter {
+ let mut ret = filter.is_list_ignored;
+ for r in &filter.list {
+ if r.is_match(&name) {
+ ret = !filter.is_list_ignored;
+ break;
}
- },
- });
+ }
+ ret
+ } else {
+ true
+ };
+
+ if to_keep {
+ temperature_vec.push(TempHarvest {
+ name,
+ temperature: match temp_type {
+ TemperatureType::Celsius => component.get_temperature(),
+ TemperatureType::Kelvin => {
+ convert_celsius_to_kelvin(component.get_temperature())
+ }
+ TemperatureType::Fahrenheit => {
+ convert_celsius_to_fahrenheit(component.get_temperature())
+ }
+ },
+ });
+ }
}
temp_vec_sort(&mut temperature_vec);
@@ -61,7 +80,7 @@ pub async fn get_temperature_data(
#[cfg(target_os = "linux")]
pub async fn get_temperature_data(
- temp_type: &TemperatureType, actually_get: bool,
+ temp_type: &TemperatureType, actually_get: bool, filter: &Option<Filter>,
) -> crate::utils::error::Result<Option<Vec<TempHarvest>>> {
use futures::StreamExt;
use heim::units::thermodynamic_temperature;
@@ -75,26 +94,51 @@ pub async fn get_temperature_data(
let mut sensor_data = heim::sensors::temperatures().boxed_local();
while let Some(sensor) = sensor_data.next().await {
if let Ok(sensor) = sensor {
- temperature_vec.push(TempHarvest {
- component_name: Some(sensor.unit().to_string()),
- component_label: if let Some(label) = sensor.label() {
- Some(label.to_string())
- } else {
- None
- },
- temperature: match temp_type {
- TemperatureType::Celsius => sensor
- .current()
- .get::<thermodynamic_temperature::degree_celsius>(),
- TemperatureType::Kelvin => {
- sensor.current().get::<thermodynamic_temperature::kelvin>()
+ let component_name = Some(sensor.unit().to_string());
+ let component_label = if let Some(label) = sensor.label() {
+ Some(label.to_string())
+ } else {
+ None
+ };
+
+ let name = match (component_name, component_label) {
+ (Some(name), Some(label)) => format!("{}: {}", name, label),
+ (None, Some(label)) => label.to_string(),
+ (Some(name), None) => name.to_string(),
+ (None, None) => String::default(),
+ };
+
+ let to_keep = if let Some(filter) = filter {
+ let mut ret = filter.is_list_ignored;
+ for r in &filter.list {
+ if r.is_match(&name) {
+ ret = !filter.is_list_ignored;
+ break;
}
- TemperatureType::Fahrenheit => sensor
- .current()
- .get::<thermodynamic_temperature::degree_fahrenheit>(
- ),
- },
- });
+ }
+ ret
+ } else {
+ true
+ };
+
+ if to_keep {
+ temperature_vec.push(TempHarvest {
+ name,
+ temperature: match temp_type {
+ TemperatureType::Celsius => sensor
+ .current()
+ .get::<thermodynamic_temperature::degree_celsius>(
+ ),
+ TemperatureType::Kelvin => {
+ sensor.current().get::<thermodynamic_temperature::kelvin>()
+ }
+ TemperatureType::Fahrenheit => sensor
+ .current()
+ .get::<thermodynamic_temperature::degree_fahrenheit>(
+ ),
+ },
+ });
+ }
}
}
@@ -116,9 +160,5 @@ fn temp_vec_sort(temperature_vec: &mut Vec<TempHarvest>) {
None => Ordering::Equal,
});
- temperature_vec.sort_by(|a, b| {
- a.component_name
- .partial_cmp(&b.component_name)
- .unwrap_or(Ordering::Equal)
- });
+ temperature_vec.sort_by(|a, b| a.name.partial_cmp(&b.name).unwrap_or(Ordering::Equal));
}
diff --git a/src/bin/main.rs b/src/bin/main.rs
index 47572bcf..24aacd2f 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -121,6 +121,7 @@ fn main() -> Result<()> {
thread_termination_lock.clone(),
thread_termination_cvar.clone(),
&app.app_config_fields,
+ app.filters.clone(),
app.used_widgets.clone(),
);
@@ -192,8 +193,7 @@ fn main() -> Result<()> {
// Disk
if app.used_widgets.use_disk {
- app.canvas_data.disk_data =
- convert_disk_row(&app.data_collection, &app.filters.disk_filter);
+ app.canvas_data.disk_data = convert_disk_row(&app.data_collection);
}
// Temperatures
diff --git a/src/constants.rs b/src/constants.rs
index 8f44e427..c50a51d8 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -479,12 +479,21 @@ pub const OLD_CONFIG_TEXT: &str = r##"# This is a default config file for bottom
#list = ["/dev/sda\\d+", "/dev/nvme0n1p2"]
#regex = true
#case_sensitive = false
+#whole_word = false
#[temp_filter]
#is_list_ignored = false
#list = ["cpu", "wifi"]
#regex = false
#case_sensitive = false
+#whole_word = false
+
+#[net_filter]
+#is_list_ignored = false
+#list = ["virbr0.*"]
+#regex = true
+#case_sensitive = false
+#whole_word = false
"##;
pub const CONFIG_TOP_HEAD: &str = r##"# This is bottom's config file.
diff --git a/src/data_conversion.rs b/src/data_conversion.rs
index fb12ba80..c683e62f 100644
--- a/src/data_conversion.rs
+++ b/src/data_conversion.rs
@@ -2,7 +2,7 @@
//! can actually handle.
use crate::Pid;
use crate::{
- app::{data_farmer, data_harvester, App, Filter, ProcWidgetState},
+ app::{data_farmer, data_harvester, App, ProcWidgetState},
utils::{self, gen_util::*},
};
use data_harvester::processes::ProcessSorting;
@@ -84,45 +84,20 @@ pub struct ConvertedCpuData {
pub fn convert_temp_row(app: &App) -> Vec<Vec<String>> {
let current_data = &app.data_collection;
let temp_type = &app.app_config_fields.temperature_type;
- let temp_filter = &app.filters.temp_filter;
let mut sensor_vector: Vec<Vec<String>> = current_data
.temp_harvest
.iter()
- .filter_map(|temp_harvest| {
- let name = match (&temp_harvest.component_name, &temp_harvest.component_label) {
- (Some(name), Some(label)) => format!("{}: {}", name, label),
- (None, Some(label)) => label.to_string(),
- (Some(name), None) => name.to_string(),
- (None, None) => String::default(),
- };
-
- let to_keep = if let Some(temp_filter) = temp_filter {
- let mut ret = temp_filter.is_list_ignored;
- for r in &temp_filter.list {
- if r.is_match(&name) {
- ret = !temp_filter.is_list_ignored;
- break;
- }
- }
- ret
- } else {
- true
- };
-
- if to_keep {
- Some(vec![
- name,
- (temp_harvest.temperature.ceil() as u64).to_string()
- + match temp_type {
- data_harvester::temperature::TemperatureType::Celsius => "C",
- data_harvester::temperature::TemperatureType::Kelvin => "K",
- data_harvester::temperature::TemperatureType::Fahrenheit => "F",
- },
- ])
- } else {
- None
- }
+ .map(|temp_harvest| {
+ vec![
+ temp_harvest.name.clone(),
+ (temp_harvest.temperature.ceil() as u64).to_string()
+ + match temp_type {
+ data_harvester::temperature::TemperatureType::Celsius => "C",
+ data_harvester::temperature::TemperatureType::Kelvin => "K",
+ data_harvester::temperature::TemperatureType::Fahrenheit => "F",
+ },
+ ]
})
.collect();
@@ -133,26 +108,12 @@ pub fn convert_temp_row(app: &App) -> Vec<Vec<String>> {
sensor_vector
}
-pub fn convert_disk_row(
- current_data: &data_farmer::DataCollection, disk_filter: &Option<Filter>,
-) -> Vec<Vec<String>> {
+pub fn convert_disk_row(current_data: &data_farmer::DataCollection) -> Vec<Vec<String>> {
let mut disk_vector: Vec<Vec<String>> = Vec::new();
current_data
.disk_harvest
.iter()
- .filter(|disk_harvest| {
- if let Some(disk_filter) = disk_filter {
- for r in &disk_filter.list {
- if r.is_match(&disk_harvest.name) {
- return !disk_filter.is_list_ignored;
- }
- }
- disk_filter.is_list_ignored
- } else {
- true
- }
- })
.zip(&current_data.io_labels)
.for_each(|(disk, (io_read, io_write))| {
let converted_free_space = get_simple_byte_values(disk.free_space, false);
@@ -174,6 +135,10 @@ pub fn convert_disk_row(
]);
});
+ if disk_vector.is_empty() {
+ disk_vector.push(vec!["No Disks Found".to_string(), "".to_string()]);
+ }
+
disk_vector
}
diff --git a/src/lib.rs b/src/lib.rs
index 1f10990e..120c1c10 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -620,7 +620,8 @@ pub fn create_collection_thread(
>,
control_receiver: std::sync::mpsc::Receiver<ThreadControlEvent>,
termination_ctrl_lock: Arc<Mutex<bool>>, termination_ctrl_cvar: Arc<Condvar>,
- app_config_fields: &app::AppConfigFields, used_widget_set: UsedWidgets,
+ app_config_fields: &app::AppConfigFields, filters: app::DataFilters,
+ used_widget_set: UsedWidgets,
) -> std::thread::JoinHandle<()> {
// trace!("Creating collection thread.");
let temp_type = app_config_fields.temperature_type.clone();
@@ -630,7 +631,7 @@ pub fn create_collection_thread(
thread::spawn(move || {
// trace!("Spawned collection thread.");
- let mut data_state = data_harvester::DataCollector::default();
+ let mut data_state = data_harvester::DataCollector::new(filters);
// trace!("Created default data state.");
data_state.set_collected_data(used_widget_set);
data_state.set_temperature_type(temp_type);
diff --git a/src/options.rs b/src/options.rs
index 8301094a..999a8cf1 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -30,6 +30,7 @@ pub struct Config {
pub row: Option<Vec<Row>>,
pub disk_filter: Option<IgnoreList>,
pub temp_filter: Option<IgnoreList>,
+ pub net_filter: Option<IgnoreList>,
}
impl Config {
@@ -216,6 +217,7 @@ pub struct IgnoreList {
pub list: Vec<String>,
pub regex: Option<bool>,
pub case_sensitive: Option<bool>,
+ pub whole_word: Option<bool>,
}
pub fn build_app(
@@ -413,6 +415,8 @@ pub fn build_app(
get_ignore_list(&config.disk_filter).context("Update 'disk_filter' in your config file")?;
let temp_filter =
get_ignore_list(&config.temp_filter).context("Update 'temp_filter' in your config file")?;
+ let net_filter =
+ get_ignore_list(&config.net_filter).context("Update 'net_filter' in your config file")?;
// One more thing - we have to update the search settings of our proc_state_map, and create the hashmaps if needed!
// Note that if you change your layout, this might not actually match properly... not sure if/where we should deal with that...
@@ -472,6 +476,7 @@ pub fn build_app(
.filters(DataFilters {
disk_filter,
temp_filter,
+ net_filter,<