mirror of
https://github.com/ClementTsang/bottom
synced 2024-11-22 04:03:06 +00:00
feature: add custom retention periods for data (#892)
* feature: add custom retention periods for data * docs: update changelog * docs: update docs
This commit is contained in:
parent
97bf8bf295
commit
50768907ec
11 changed files with 120 additions and 60 deletions
|
@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- [#868](https://github.com/ClementTsang/bottom/pull/868): Make temperature widget sortable.
|
- [#868](https://github.com/ClementTsang/bottom/pull/868): Make temperature widget sortable.
|
||||||
- [#870](https://github.com/ClementTsang/bottom/pull/870): Make disk widget sortable.
|
- [#870](https://github.com/ClementTsang/bottom/pull/870): Make disk widget sortable.
|
||||||
- [#881](https://github.com/ClementTsang/bottom/pull/881): Add pasting to the search bar.
|
- [#881](https://github.com/ClementTsang/bottom/pull/881): Add pasting to the search bar.
|
||||||
|
- [#892](https://github.com/ClementTsang/bottom/pull/892): Add custom retention periods for data.
|
||||||
|
|
||||||
## [0.6.8] - 2022-02-01
|
## [0.6.8] - 2022-02-01
|
||||||
|
|
||||||
|
|
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -224,6 +224,8 @@ dependencies = [
|
||||||
"futures-timer",
|
"futures-timer",
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"heim",
|
"heim",
|
||||||
|
"humantime",
|
||||||
|
"humantime-serde",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itertools",
|
"itertools",
|
||||||
"kstring",
|
"kstring",
|
||||||
|
@ -889,6 +891,22 @@ version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime-serde"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c"
|
||||||
|
dependencies = [
|
||||||
|
"humantime",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
|
|
@ -73,6 +73,8 @@ flume = "0.10.14"
|
||||||
futures = "0.3.21"
|
futures = "0.3.21"
|
||||||
futures-timer = "3.0.2"
|
futures-timer = "3.0.2"
|
||||||
fxhash = "0.2.1"
|
fxhash = "0.2.1"
|
||||||
|
humantime = "2.1.0"
|
||||||
|
humantime-serde = "1.1.1"
|
||||||
indexmap = "1.8.1"
|
indexmap = "1.8.1"
|
||||||
itertools = "0.10.3"
|
itertools = "0.10.3"
|
||||||
kstring = { version = "2.0.0", features = ["arc"] }
|
kstring = { version = "2.0.0", features = ["arc"] }
|
||||||
|
|
|
@ -44,3 +44,4 @@ The following flags can be provided to bottom in the command line to change the
|
||||||
| `-V, --version` | Prints version information. |
|
| `-V, --version` | Prints version information. |
|
||||||
| `-W, --whole_word` | Enables whole-word matching by default. |
|
| `-W, --whole_word` | Enables whole-word matching by default. |
|
||||||
| `--enable_gpu_memory` | Enable collecting and displaying GPU memory usage. |
|
| `--enable_gpu_memory` | Enable collecting and displaying GPU memory usage. |
|
||||||
|
| `--retention` | How much data is stored at once in terms of time. |
|
||||||
|
|
|
@ -37,3 +37,4 @@ Most of the [command line flags](../../command-line-flags) have config file equi
|
||||||
| `network_use_bytes` | Boolean | Displays the network widget using bytes. |
|
| `network_use_bytes` | Boolean | Displays the network widget using bytes. |
|
||||||
| `network_use_log` | Boolean | Displays the network widget with a log scale. |
|
| `network_use_log` | Boolean | Displays the network widget with a log scale. |
|
||||||
| `enable_gpu_memory` | Boolean | Shows the GPU memory widget. |
|
| `enable_gpu_memory` | Boolean | Shows the GPU memory widget. |
|
||||||
|
| `retention` | String (human readable time, such as "10m", "1h", etc.) | How much data is stored at once in terms of time. |
|
||||||
|
|
|
@ -71,6 +71,8 @@
|
||||||
#disable_advanced_kill = false
|
#disable_advanced_kill = false
|
||||||
# Shows GPU(s) memory
|
# Shows GPU(s) memory
|
||||||
#enable_gpu_memory = false
|
#enable_gpu_memory = false
|
||||||
|
# How much data is stored at once in terms of time.
|
||||||
|
#retention = "10m"
|
||||||
|
|
||||||
# These are all the components that support custom theming. Note that colour support
|
# These are all the components that support custom theming. Note that colour support
|
||||||
# will depend on terminal support.
|
# will depend on terminal support.
|
||||||
|
|
19
src/app.rs
19
src/app.rs
|
@ -72,6 +72,7 @@ pub struct AppConfigFields {
|
||||||
pub network_unit_type: DataUnit,
|
pub network_unit_type: DataUnit,
|
||||||
pub network_scale_type: AxisScaling,
|
pub network_scale_type: AxisScaling,
|
||||||
pub network_use_binary_prefix: bool,
|
pub network_use_binary_prefix: bool,
|
||||||
|
pub retention_ms: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For filtering out information
|
/// For filtering out information
|
||||||
|
@ -2186,16 +2187,16 @@ impl App {
|
||||||
{
|
{
|
||||||
let new_time = cpu_widget_state.current_display_time
|
let new_time = cpu_widget_state.current_display_time
|
||||||
+ self.app_config_fields.time_interval;
|
+ self.app_config_fields.time_interval;
|
||||||
if new_time <= constants::STALE_MAX_MILLISECONDS {
|
if new_time <= self.app_config_fields.retention_ms {
|
||||||
cpu_widget_state.current_display_time = new_time;
|
cpu_widget_state.current_display_time = new_time;
|
||||||
self.cpu_state.force_update = Some(self.current_widget.widget_id);
|
self.cpu_state.force_update = Some(self.current_widget.widget_id);
|
||||||
if self.app_config_fields.autohide_time {
|
if self.app_config_fields.autohide_time {
|
||||||
cpu_widget_state.autohide_timer = Some(Instant::now());
|
cpu_widget_state.autohide_timer = Some(Instant::now());
|
||||||
}
|
}
|
||||||
} else if cpu_widget_state.current_display_time
|
} else if cpu_widget_state.current_display_time
|
||||||
!= constants::STALE_MAX_MILLISECONDS
|
!= self.app_config_fields.retention_ms
|
||||||
{
|
{
|
||||||
cpu_widget_state.current_display_time = constants::STALE_MAX_MILLISECONDS;
|
cpu_widget_state.current_display_time = self.app_config_fields.retention_ms;
|
||||||
self.cpu_state.force_update = Some(self.current_widget.widget_id);
|
self.cpu_state.force_update = Some(self.current_widget.widget_id);
|
||||||
if self.app_config_fields.autohide_time {
|
if self.app_config_fields.autohide_time {
|
||||||
cpu_widget_state.autohide_timer = Some(Instant::now());
|
cpu_widget_state.autohide_timer = Some(Instant::now());
|
||||||
|
@ -2211,16 +2212,16 @@ impl App {
|
||||||
{
|
{
|
||||||
let new_time = mem_widget_state.current_display_time
|
let new_time = mem_widget_state.current_display_time
|
||||||
+ self.app_config_fields.time_interval;
|
+ self.app_config_fields.time_interval;
|
||||||
if new_time <= constants::STALE_MAX_MILLISECONDS {
|
if new_time <= self.app_config_fields.retention_ms {
|
||||||
mem_widget_state.current_display_time = new_time;
|
mem_widget_state.current_display_time = new_time;
|
||||||
self.mem_state.force_update = Some(self.current_widget.widget_id);
|
self.mem_state.force_update = Some(self.current_widget.widget_id);
|
||||||
if self.app_config_fields.autohide_time {
|
if self.app_config_fields.autohide_time {
|
||||||
mem_widget_state.autohide_timer = Some(Instant::now());
|
mem_widget_state.autohide_timer = Some(Instant::now());
|
||||||
}
|
}
|
||||||
} else if mem_widget_state.current_display_time
|
} else if mem_widget_state.current_display_time
|
||||||
!= constants::STALE_MAX_MILLISECONDS
|
!= self.app_config_fields.retention_ms
|
||||||
{
|
{
|
||||||
mem_widget_state.current_display_time = constants::STALE_MAX_MILLISECONDS;
|
mem_widget_state.current_display_time = self.app_config_fields.retention_ms;
|
||||||
self.mem_state.force_update = Some(self.current_widget.widget_id);
|
self.mem_state.force_update = Some(self.current_widget.widget_id);
|
||||||
if self.app_config_fields.autohide_time {
|
if self.app_config_fields.autohide_time {
|
||||||
mem_widget_state.autohide_timer = Some(Instant::now());
|
mem_widget_state.autohide_timer = Some(Instant::now());
|
||||||
|
@ -2236,16 +2237,16 @@ impl App {
|
||||||
{
|
{
|
||||||
let new_time = net_widget_state.current_display_time
|
let new_time = net_widget_state.current_display_time
|
||||||
+ self.app_config_fields.time_interval;
|
+ self.app_config_fields.time_interval;
|
||||||
if new_time <= constants::STALE_MAX_MILLISECONDS {
|
if new_time <= self.app_config_fields.retention_ms {
|
||||||
net_widget_state.current_display_time = new_time;
|
net_widget_state.current_display_time = new_time;
|
||||||
self.net_state.force_update = Some(self.current_widget.widget_id);
|
self.net_state.force_update = Some(self.current_widget.widget_id);
|
||||||
if self.app_config_fields.autohide_time {
|
if self.app_config_fields.autohide_time {
|
||||||
net_widget_state.autohide_timer = Some(Instant::now());
|
net_widget_state.autohide_timer = Some(Instant::now());
|
||||||
}
|
}
|
||||||
} else if net_widget_state.current_display_time
|
} else if net_widget_state.current_display_time
|
||||||
!= constants::STALE_MAX_MILLISECONDS
|
!= self.app_config_fields.retention_ms
|
||||||
{
|
{
|
||||||
net_widget_state.current_display_time = constants::STALE_MAX_MILLISECONDS;
|
net_widget_state.current_display_time = self.app_config_fields.retention_ms;
|
||||||
self.net_state.force_update = Some(self.current_widget.widget_id);
|
self.net_state.force_update = Some(self.current_widget.widget_id);
|
||||||
if self.app_config_fields.autohide_time {
|
if self.app_config_fields.autohide_time {
|
||||||
net_widget_state.autohide_timer = Some(Instant::now());
|
net_widget_state.autohide_timer = Some(Instant::now());
|
||||||
|
|
|
@ -85,12 +85,12 @@ fn main() -> Result<()> {
|
||||||
let lock = thread_termination_lock.clone();
|
let lock = thread_termination_lock.clone();
|
||||||
let cvar = thread_termination_cvar.clone();
|
let cvar = thread_termination_cvar.clone();
|
||||||
let cleaning_sender = sender.clone();
|
let cleaning_sender = sender.clone();
|
||||||
const OFFSET_WAIT_TIME: u64 = constants::STALE_MAX_MILLISECONDS + 60000;
|
let offset_wait_time = app.app_config_fields.retention_ms + 60000;
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
loop {
|
loop {
|
||||||
let result = cvar.wait_timeout(
|
let result = cvar.wait_timeout(
|
||||||
lock.lock().unwrap(),
|
lock.lock().unwrap(),
|
||||||
Duration::from_millis(OFFSET_WAIT_TIME),
|
Duration::from_millis(offset_wait_time),
|
||||||
);
|
);
|
||||||
if let Ok(result) = result {
|
if let Ok(result) = result {
|
||||||
if *(result.0) {
|
if *(result.0) {
|
||||||
|
@ -271,7 +271,7 @@ fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
BottomEvent::Clean => {
|
BottomEvent::Clean => {
|
||||||
app.data_collection
|
app.data_collection
|
||||||
.clean_data(constants::STALE_MAX_MILLISECONDS);
|
.clean_data(app.app_config_fields.retention_ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/clap.rs
10
src/clap.rs
|
@ -348,6 +348,13 @@ use CPU (3) as the default instead.
|
||||||
"Displays the network widget with binary prefixes (i.e. kibibits, mebibits) rather than a decimal prefix (i.e. kilobits, megabits). Defaults to decimal prefixes.",
|
"Displays the network widget with binary prefixes (i.e. kibibits, mebibits) rather than a decimal prefix (i.e. kilobits, megabits). Defaults to decimal prefixes.",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let retention = Arg::new("retention")
|
||||||
|
.long("retention")
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("time")
|
||||||
|
.help("The timespan of data kept.")
|
||||||
|
.long_help("How much data is stored at once in terms of time. Takes in human-readable time spans (e.g. 10m, 1h), with a minimum of 1 minute. Note higher values will take up more memory. Defaults to 10 minutes.");
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut app = Command::new(crate_name!())
|
let mut app = Command::new(crate_name!())
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
|
@ -391,7 +398,8 @@ use CPU (3) as the default instead.
|
||||||
.arg(network_use_binary_prefix)
|
.arg(network_use_binary_prefix)
|
||||||
.arg(current_usage)
|
.arg(current_usage)
|
||||||
.arg(use_old_network_legend)
|
.arg(use_old_network_legend)
|
||||||
.arg(whole_word);
|
.arg(whole_word)
|
||||||
|
.arg(retention);
|
||||||
|
|
||||||
#[cfg(feature = "battery")]
|
#[cfg(feature = "battery")]
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,9 +5,6 @@ use crate::options::ConfigColours;
|
||||||
// Default widget ID
|
// Default widget ID
|
||||||
pub const DEFAULT_WIDGET_ID: u64 = 56709;
|
pub const DEFAULT_WIDGET_ID: u64 = 56709;
|
||||||
|
|
||||||
// How long to store data.
|
|
||||||
pub const STALE_MAX_MILLISECONDS: u64 = 600 * 1000; // Keep 10 minutes of data.
|
|
||||||
|
|
||||||
// How much data is SHOWN
|
// How much data is SHOWN
|
||||||
pub const DEFAULT_TIME_MILLISECONDS: u64 = 60 * 1000; // Defaults to 1 min.
|
pub const DEFAULT_TIME_MILLISECONDS: u64 = 60 * 1000; // Defaults to 1 min.
|
||||||
pub const STALE_MIN_MILLISECONDS: u64 = 30 * 1000; // Lowest is 30 seconds
|
pub const STALE_MIN_MILLISECONDS: u64 = 30 * 1000; // Lowest is 30 seconds
|
||||||
|
@ -549,6 +546,8 @@ pub const CONFIG_TEXT: &str = r##"# This is a default config file for bottom. A
|
||||||
#disable_advanced_kill = false
|
#disable_advanced_kill = false
|
||||||
# Shows GPU(s) memory
|
# Shows GPU(s) memory
|
||||||
#enable_gpu_memory = false
|
#enable_gpu_memory = false
|
||||||
|
# How much data is stored at once in terms of time.
|
||||||
|
#retention = "10m"
|
||||||
|
|
||||||
# These are all the components that support custom theming. Note that colour support
|
# These are all the components that support custom theming. Note that colour support
|
||||||
# will depend on terminal support.
|
# will depend on terminal support.
|
||||||
|
|
115
src/options.rs
115
src/options.rs
|
@ -3,9 +3,10 @@ use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
convert::TryInto,
|
convert::TryInto,
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
time::Instant,
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use clap::ArgMatches;
|
||||||
use layout_options::*;
|
use layout_options::*;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -88,6 +89,9 @@ pub struct ConfigFlags {
|
||||||
pub network_use_log: Option<bool>,
|
pub network_use_log: Option<bool>,
|
||||||
pub network_use_binary_prefix: Option<bool>,
|
pub network_use_binary_prefix: Option<bool>,
|
||||||
pub enable_gpu_memory: Option<bool>,
|
pub enable_gpu_memory: Option<bool>,
|
||||||
|
#[serde(with = "humantime_serde")]
|
||||||
|
#[serde(default)]
|
||||||
|
pub retention: Option<Duration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Default, Debug, Deserialize, Serialize)]
|
||||||
|
@ -168,13 +172,16 @@ pub struct IgnoreList {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_app(
|
pub fn build_app(
|
||||||
matches: &clap::ArgMatches, config: &mut Config, widget_layout: &BottomLayout,
|
matches: &ArgMatches, config: &mut Config, widget_layout: &BottomLayout,
|
||||||
default_widget_id: u64, default_widget_type_option: &Option<BottomWidgetType>,
|
default_widget_id: u64, default_widget_type_option: &Option<BottomWidgetType>,
|
||||||
colours: &CanvasColours,
|
colours: &CanvasColours,
|
||||||
) -> Result<App> {
|
) -> Result<App> {
|
||||||
use BottomWidgetType::*;
|
use BottomWidgetType::*;
|
||||||
|
|
||||||
|
let retention_ms =
|
||||||
|
get_retention_ms(matches, config).context("Update `retention` in your config file.")?;
|
||||||
let autohide_time = get_autohide_time(matches, config);
|
let autohide_time = get_autohide_time(matches, config);
|
||||||
let default_time_value = get_default_time_value(matches, config)
|
let default_time_value = get_default_time_value(matches, config, retention_ms)
|
||||||
.context("Update 'default_time_value' in your config file.")?;
|
.context("Update 'default_time_value' in your config file.")?;
|
||||||
let use_basic_mode = get_use_basic_mode(matches, config);
|
let use_basic_mode = get_use_basic_mode(matches, config);
|
||||||
|
|
||||||
|
@ -224,7 +231,7 @@ pub fn build_app(
|
||||||
use_current_cpu_total: get_use_current_cpu_total(matches, config),
|
use_current_cpu_total: get_use_current_cpu_total(matches, config),
|
||||||
use_basic_mode,
|
use_basic_mode,
|
||||||
default_time_value,
|
default_time_value,
|
||||||
time_interval: get_time_interval(matches, config)
|
time_interval: get_time_interval(matches, config, retention_ms)
|
||||||
.context("Update 'time_delta' in your config file.")?,
|
.context("Update 'time_delta' in your config file.")?,
|
||||||
hide_time: get_hide_time(matches, config),
|
hide_time: get_hide_time(matches, config),
|
||||||
autohide_time,
|
autohide_time,
|
||||||
|
@ -241,6 +248,7 @@ pub fn build_app(
|
||||||
network_scale_type,
|
network_scale_type,
|
||||||
network_unit_type,
|
network_unit_type,
|
||||||
network_use_binary_prefix,
|
network_use_binary_prefix,
|
||||||
|
retention_ms,
|
||||||
};
|
};
|
||||||
|
|
||||||
for row in &widget_layout.rows {
|
for row in &widget_layout.rows {
|
||||||
|
@ -422,7 +430,7 @@ pub fn build_app(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_widget_layout(
|
pub fn get_widget_layout(
|
||||||
matches: &clap::ArgMatches, config: &Config,
|
matches: &ArgMatches, config: &Config,
|
||||||
) -> error::Result<(BottomLayout, u64, Option<BottomWidgetType>)> {
|
) -> error::Result<(BottomLayout, u64, Option<BottomWidgetType>)> {
|
||||||
let left_legend = get_use_left_legend(matches, config);
|
let left_legend = get_use_left_legend(matches, config);
|
||||||
let (default_widget_type, mut default_widget_count) =
|
let (default_widget_type, mut default_widget_count) =
|
||||||
|
@ -486,9 +494,7 @@ pub fn get_widget_layout(
|
||||||
Ok((bottom_layout, default_widget_id, default_widget_type))
|
Ok((bottom_layout, default_widget_id, default_widget_type))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_update_rate_in_milliseconds(
|
fn get_update_rate_in_milliseconds(matches: &ArgMatches, config: &Config) -> error::Result<u64> {
|
||||||
matches: &clap::ArgMatches, config: &Config,
|
|
||||||
) -> error::Result<u64> {
|
|
||||||
let update_rate_in_milliseconds = if let Some(update_rate) = matches.value_of("rate") {
|
let update_rate_in_milliseconds = if let Some(update_rate) = matches.value_of("rate") {
|
||||||
update_rate.parse::<u64>().map_err(|_| {
|
update_rate.parse::<u64>().map_err(|_| {
|
||||||
BottomError::ConfigError(
|
BottomError::ConfigError(
|
||||||
|
@ -515,7 +521,7 @@ fn get_update_rate_in_milliseconds(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_temperature(
|
fn get_temperature(
|
||||||
matches: &clap::ArgMatches, config: &Config,
|
matches: &ArgMatches, config: &Config,
|
||||||
) -> error::Result<data_harvester::temperature::TemperatureType> {
|
) -> error::Result<data_harvester::temperature::TemperatureType> {
|
||||||
if matches.is_present("fahrenheit") {
|
if matches.is_present("fahrenheit") {
|
||||||
return Ok(data_harvester::temperature::TemperatureType::Fahrenheit);
|
return Ok(data_harvester::temperature::TemperatureType::Fahrenheit);
|
||||||
|
@ -541,7 +547,7 @@ fn get_temperature(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Yes, this function gets whether to show average CPU (true) or not (false)
|
/// Yes, this function gets whether to show average CPU (true) or not (false)
|
||||||
fn get_show_average_cpu(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_show_average_cpu(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("hide_avg_cpu") {
|
if matches.is_present("hide_avg_cpu") {
|
||||||
return false;
|
return false;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -553,7 +559,7 @@ fn get_show_average_cpu(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_use_dot(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_use_dot(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("dot_marker") {
|
if matches.is_present("dot_marker") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -564,7 +570,7 @@ fn get_use_dot(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_use_left_legend(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_use_left_legend(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("left_legend") {
|
if matches.is_present("left_legend") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -576,7 +582,7 @@ fn get_use_left_legend(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_use_current_cpu_total(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_use_current_cpu_total(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("current_usage") {
|
if matches.is_present("current_usage") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -588,7 +594,7 @@ fn get_use_current_cpu_total(matches: &clap::ArgMatches, config: &Config) -> boo
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_use_basic_mode(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_use_basic_mode(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("basic") {
|
if matches.is_present("basic") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -600,7 +606,10 @@ fn get_use_basic_mode(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_default_time_value(matches: &clap::ArgMatches, config: &Config) -> error::Result<u64> {
|
/// FIXME: Let this accept human times.
|
||||||
|
fn get_default_time_value(
|
||||||
|
matches: &ArgMatches, config: &Config, retention_ms: u64,
|
||||||
|
) -> error::Result<u64> {
|
||||||
let default_time = if let Some(default_time_value) = matches.value_of("default_time_value") {
|
let default_time = if let Some(default_time_value) = matches.value_of("default_time_value") {
|
||||||
default_time_value.parse::<u64>().map_err(|_| {
|
default_time_value.parse::<u64>().map_err(|_| {
|
||||||
BottomError::ConfigError(
|
BottomError::ConfigError(
|
||||||
|
@ -621,17 +630,19 @@ fn get_default_time_value(matches: &clap::ArgMatches, config: &Config) -> error:
|
||||||
return Err(BottomError::ConfigError(
|
return Err(BottomError::ConfigError(
|
||||||
"set your default value to be at least 30000 milliseconds.".to_string(),
|
"set your default value to be at least 30000 milliseconds.".to_string(),
|
||||||
));
|
));
|
||||||
} else if default_time > STALE_MAX_MILLISECONDS {
|
} else if default_time > retention_ms {
|
||||||
return Err(BottomError::ConfigError(format!(
|
return Err(BottomError::ConfigError(format!(
|
||||||
"set your default value to be at most {} milliseconds.",
|
"set your default value to be at most {} milliseconds.",
|
||||||
STALE_MAX_MILLISECONDS
|
retention_ms
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(default_time)
|
Ok(default_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_time_interval(matches: &clap::ArgMatches, config: &Config) -> error::Result<u64> {
|
fn get_time_interval(
|
||||||
|
matches: &ArgMatches, config: &Config, retention_ms: u64,
|
||||||
|
) -> error::Result<u64> {
|
||||||
let time_interval = if let Some(time_interval) = matches.value_of("time_delta") {
|
let time_interval = if let Some(time_interval) = matches.value_of("time_delta") {
|
||||||
time_interval.parse::<u64>().map_err(|_| {
|
time_interval.parse::<u64>().map_err(|_| {
|
||||||
BottomError::ConfigError(
|
BottomError::ConfigError(
|
||||||
|
@ -652,17 +663,17 @@ fn get_time_interval(matches: &clap::ArgMatches, config: &Config) -> error::Resu
|
||||||
return Err(BottomError::ConfigError(
|
return Err(BottomError::ConfigError(
|
||||||
"set your time delta to be at least 1000 milliseconds.".to_string(),
|
"set your time delta to be at least 1000 milliseconds.".to_string(),
|
||||||
));
|
));
|
||||||
} else if time_interval > STALE_MAX_MILLISECONDS {
|
} else if time_interval > retention_ms {
|
||||||
return Err(BottomError::ConfigError(format!(
|
return Err(BottomError::ConfigError(format!(
|
||||||
"set your time delta to be at most {} milliseconds.",
|
"set your time delta to be at most {} milliseconds.",
|
||||||
STALE_MAX_MILLISECONDS
|
retention_ms
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(time_interval)
|
Ok(time_interval)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_app_grouping(matches: &clap::ArgMatches, config: &Config) -> bool {
|
pub fn get_app_grouping(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("group") {
|
if matches.is_present("group") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -673,7 +684,7 @@ pub fn get_app_grouping(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_app_case_sensitive(matches: &clap::ArgMatches, config: &Config) -> bool {
|
pub fn get_app_case_sensitive(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("case_sensitive") {
|
if matches.is_present("case_sensitive") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -684,7 +695,7 @@ pub fn get_app_case_sensitive(matches: &clap::ArgMatches, config: &Config) -> bo
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_app_match_whole_word(matches: &clap::ArgMatches, config: &Config) -> bool {
|
pub fn get_app_match_whole_word(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("whole_word") {
|
if matches.is_present("whole_word") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -695,7 +706,7 @@ pub fn get_app_match_whole_word(matches: &clap::ArgMatches, config: &Config) ->
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_app_use_regex(matches: &clap::ArgMatches, config: &Config) -> bool {
|
pub fn get_app_use_regex(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("regex") {
|
if matches.is_present("regex") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -706,7 +717,7 @@ pub fn get_app_use_regex(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_hide_time(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_hide_time(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("hide_time") {
|
if matches.is_present("hide_time") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -717,7 +728,7 @@ fn get_hide_time(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_autohide_time(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_autohide_time(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("autohide_time") {
|
if matches.is_present("autohide_time") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -730,7 +741,7 @@ fn get_autohide_time(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_default_widget_and_count(
|
fn get_default_widget_and_count(
|
||||||
matches: &clap::ArgMatches, config: &Config,
|
matches: &ArgMatches, config: &Config,
|
||||||
) -> error::Result<(Option<BottomWidgetType>, u64)> {
|
) -> error::Result<(Option<BottomWidgetType>, u64)> {
|
||||||
let widget_type = if let Some(widget_type) = matches.value_of("default_widget_type") {
|
let widget_type = if let Some(widget_type) = matches.value_of("default_widget_type") {
|
||||||
let parsed_widget = widget_type.parse::<BottomWidgetType>()?;
|
let parsed_widget = widget_type.parse::<BottomWidgetType>()?;
|
||||||
|
@ -779,7 +790,7 @@ fn get_default_widget_and_count(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_disable_click(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_disable_click(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("disable_click") {
|
if matches.is_present("disable_click") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -790,7 +801,7 @@ fn get_disable_click(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_use_old_network_legend(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_use_old_network_legend(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("use_old_network_legend") {
|
if matches.is_present("use_old_network_legend") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -801,7 +812,7 @@ fn get_use_old_network_legend(matches: &clap::ArgMatches, config: &Config) -> bo
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_hide_table_gap(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_hide_table_gap(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("hide_table_gap") {
|
if matches.is_present("hide_table_gap") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -812,7 +823,7 @@ fn get_hide_table_gap(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_use_battery(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_use_battery(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if cfg!(feature = "battery") {
|
if cfg!(feature = "battery") {
|
||||||
if matches.is_present("battery") {
|
if matches.is_present("battery") {
|
||||||
return true;
|
return true;
|
||||||
|
@ -825,7 +836,7 @@ fn get_use_battery(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_enable_gpu_memory(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_enable_gpu_memory(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if cfg!(feature = "gpu") {
|
if cfg!(feature = "gpu") {
|
||||||
if matches.is_present("enable_gpu_memory") {
|
if matches.is_present("enable_gpu_memory") {
|
||||||
return true;
|
return true;
|
||||||
|
@ -839,7 +850,7 @@ fn get_enable_gpu_memory(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn get_no_write(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_no_write(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("no_write") {
|
if matches.is_present("no_write") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -887,9 +898,7 @@ fn get_ignore_list(ignore_list: &Option<IgnoreList>) -> error::Result<Option<Fil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_color_scheme(
|
pub fn get_color_scheme(matches: &ArgMatches, config: &Config) -> error::Result<ColourScheme> {
|
||||||
matches: &clap::ArgMatches, config: &Config,
|
|
||||||
) -> error::Result<ColourScheme> {
|
|
||||||
if let Some(color) = matches.value_of("color") {
|
if let Some(color) = matches.value_of("color") {
|
||||||
// Highest priority is always command line flags...
|
// Highest priority is always command line flags...
|
||||||
return ColourScheme::from_str(color);
|
return ColourScheme::from_str(color);
|
||||||
|
@ -914,7 +923,7 @@ pub fn get_color_scheme(
|
||||||
Ok(ColourScheme::Default)
|
Ok(ColourScheme::Default)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mem_as_value(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_mem_as_value(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("mem_as_value") {
|
if matches.is_present("mem_as_value") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -925,7 +934,7 @@ fn get_mem_as_value(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_is_default_tree(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_is_default_tree(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("tree") {
|
if matches.is_present("tree") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -936,7 +945,7 @@ fn get_is_default_tree(matches: &clap::ArgMatches, config: &Config) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_show_table_scroll_position(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_show_table_scroll_position(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("show_table_scroll_position") {
|
if matches.is_present("show_table_scroll_position") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -947,7 +956,7 @@ fn get_show_table_scroll_position(matches: &clap::ArgMatches, config: &Config) -
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_is_default_process_command(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_is_default_process_command(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("process_command") {
|
if matches.is_present("process_command") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -958,7 +967,7 @@ fn get_is_default_process_command(matches: &clap::ArgMatches, config: &Config) -
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_is_advanced_kill_disabled(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_is_advanced_kill_disabled(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("disable_advanced_kill") {
|
if matches.is_present("disable_advanced_kill") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -969,7 +978,7 @@ fn get_is_advanced_kill_disabled(matches: &clap::ArgMatches, config: &Config) ->
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_network_unit_type(matches: &clap::ArgMatches, config: &Config) -> DataUnit {
|
fn get_network_unit_type(matches: &ArgMatches, config: &Config) -> DataUnit {
|
||||||
if matches.is_present("network_use_bytes") {
|
if matches.is_present("network_use_bytes") {
|
||||||
return DataUnit::Byte;
|
return DataUnit::Byte;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -983,7 +992,7 @@ fn get_network_unit_type(matches: &clap::ArgMatches, config: &Config) -> DataUni
|
||||||
DataUnit::Bit
|
DataUnit::Bit
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_network_scale_type(matches: &clap::ArgMatches, config: &Config) -> AxisScaling {
|
fn get_network_scale_type(matches: &ArgMatches, config: &Config) -> AxisScaling {
|
||||||
if matches.is_present("network_use_log") {
|
if matches.is_present("network_use_log") {
|
||||||
return AxisScaling::Log;
|
return AxisScaling::Log;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -997,7 +1006,7 @@ fn get_network_scale_type(matches: &clap::ArgMatches, config: &Config) -> AxisSc
|
||||||
AxisScaling::Linear
|
AxisScaling::Linear
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_network_use_binary_prefix(matches: &clap::ArgMatches, config: &Config) -> bool {
|
fn get_network_use_binary_prefix(matches: &ArgMatches, config: &Config) -> bool {
|
||||||
if matches.is_present("network_use_binary_prefix") {
|
if matches.is_present("network_use_binary_prefix") {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(flags) = &config.flags {
|
} else if let Some(flags) = &config.flags {
|
||||||
|
@ -1007,3 +1016,21 @@ fn get_network_use_binary_prefix(matches: &clap::ArgMatches, config: &Config) ->
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_retention_ms(matches: &ArgMatches, config: &Config) -> error::Result<u64> {
|
||||||
|
const DEFAULT_RETENTION_MS: u64 = 600 * 1000; // Keep 10 minutes of data.
|
||||||
|
|
||||||
|
if let Some(retention) = matches.value_of("retention") {
|
||||||
|
humantime::parse_duration(retention)
|
||||||
|
.map(|dur| dur.as_millis() as u64)
|
||||||
|
.map_err(|err| BottomError::ConfigError(format!("invalid retention duration: {err:?}")))
|
||||||
|
} else if let Some(flags) = &config.flags {
|
||||||
|
if let Some(retention) = flags.retention {
|
||||||
|
Ok(retention.as_millis() as u64)
|
||||||
|
} else {
|
||||||
|
Ok(DEFAULT_RETENTION_MS)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(DEFAULT_RETENTION_MS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue