M4: fetch mode, cleanup and documentation
- --fetch with a Jinja-subset renderer and the shipped templates - clippy clean, cargo fmt, all tests green - README status and differential testing instructions
This commit is contained in:
@@ -51,13 +51,23 @@ impl QuicklookPlugin {
|
||||
args.disable_config_exec,
|
||||
);
|
||||
let stats_list = model.get_conf_value("list", "");
|
||||
let mut stats_list: Vec<String> =
|
||||
if stats_list.is_empty() { DEFAULT_STATS_LIST.iter().map(|s| s.to_string()).collect() } else { stats_list };
|
||||
if stats_list.iter().any(|s| !AVAILABLE_STATS_LIST.contains(&s.as_str())) {
|
||||
let mut stats_list: Vec<String> = if stats_list.is_empty() {
|
||||
DEFAULT_STATS_LIST.iter().map(|s| s.to_string()).collect()
|
||||
} else {
|
||||
stats_list
|
||||
};
|
||||
if stats_list
|
||||
.iter()
|
||||
.any(|s| !AVAILABLE_STATS_LIST.contains(&s.as_str()))
|
||||
{
|
||||
stats_list = DEFAULT_STATS_LIST.iter().map(|s| s.to_string()).collect();
|
||||
}
|
||||
let max_cpu_display = config.get_int_value("percpu", "max_cpu_display", 4).max(0) as usize;
|
||||
Self { model, stats_list, max_cpu_display }
|
||||
Self {
|
||||
model,
|
||||
stats_list,
|
||||
max_cpu_display,
|
||||
}
|
||||
}
|
||||
|
||||
fn mhz_to_hz(value: Option<f64>) -> Option<f64> {
|
||||
@@ -88,7 +98,10 @@ impl Plugin for QuicklookPlugin {
|
||||
(info, cpu, percpu)
|
||||
};
|
||||
stats.insert("cpu_name".to_string(), json!(info.cpu_name));
|
||||
stats.insert("cpu_hz_current".to_string(), json!(Self::mhz_to_hz(info.cpu_hz_current)));
|
||||
stats.insert(
|
||||
"cpu_hz_current".to_string(),
|
||||
json!(Self::mhz_to_hz(info.cpu_hz_current)),
|
||||
);
|
||||
stats.insert("cpu_hz".to_string(), json!(Self::mhz_to_hz(info.cpu_hz)));
|
||||
stats.insert("cpu".to_string(), json!(cpu_value));
|
||||
stats.insert("percpu".to_string(), Value::Array(percpu_values));
|
||||
@@ -98,14 +111,19 @@ impl Plugin for QuicklookPlugin {
|
||||
let available = meminfo.get("MemAvailable").copied().unwrap_or(0) as f64;
|
||||
stats.insert(
|
||||
"mem".to_string(),
|
||||
json!(if total > 0.0 { ((total - available) / total * 100.0 * 10.0).round() / 10.0 } else { 0.0 }),
|
||||
json!(if total > 0.0 {
|
||||
((total - available) / total * 100.0 * 10.0).round() / 10.0
|
||||
} else {
|
||||
0.0
|
||||
}),
|
||||
);
|
||||
let swap_total = meminfo.get("SwapTotal").copied().unwrap_or(0);
|
||||
let swap_free = meminfo.get("SwapFree").copied().unwrap_or(0);
|
||||
stats.insert(
|
||||
"swap".to_string(),
|
||||
json!(if swap_total > 0 {
|
||||
(((swap_total - swap_free) as f64 * 100.0 / swap_total as f64) * 10.0).round() / 10.0
|
||||
(((swap_total - swap_free) as f64 * 100.0 / swap_total as f64) * 10.0).round()
|
||||
/ 10.0
|
||||
} else {
|
||||
0.0
|
||||
}),
|
||||
@@ -113,9 +131,16 @@ impl Plugin for QuicklookPlugin {
|
||||
|
||||
let log_core = crate::collectors::logical_core_count();
|
||||
stats.insert("cpu_log_core".to_string(), json!(log_core));
|
||||
stats.insert("cpu_phys_core".to_string(), json!(crate::collectors::physical_core_count()));
|
||||
stats.insert(
|
||||
"cpu_phys_core".to_string(),
|
||||
json!(crate::collectors::physical_core_count()),
|
||||
);
|
||||
let load = crate::collectors::read_loadavg().map(|(_, _, min15)| {
|
||||
if log_core > 0 { min15 / log_core as f64 * 100.0 } else { 0.0 }
|
||||
if log_core > 0 {
|
||||
min15 / log_core as f64 * 100.0
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
});
|
||||
stats.insert("load".to_string(), json!(load));
|
||||
stats.insert("gpu_mem".to_string(), Value::Null);
|
||||
@@ -130,8 +155,16 @@ impl Plugin for QuicklookPlugin {
|
||||
let stats_list = self.stats_list.clone();
|
||||
for stat_key in &stats_list {
|
||||
if let Some(value) = self.model.stats.get(stat_key).and_then(Value::as_f64) {
|
||||
let decoration =
|
||||
self.model.get_alert(value, 0.0, 100.0, true, false, Some(stat_key), None, false);
|
||||
let decoration = self.model.get_alert(
|
||||
value,
|
||||
0.0,
|
||||
100.0,
|
||||
true,
|
||||
false,
|
||||
Some(stat_key),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
self.model.set_view_decoration(None, stat_key, decoration);
|
||||
}
|
||||
}
|
||||
@@ -142,22 +175,36 @@ impl Plugin for QuicklookPlugin {
|
||||
let mut percpu_decoration = serde_json::Map::new();
|
||||
if let Some(percpu) = self.model.stats.get("percpu").and_then(Value::as_array) {
|
||||
for cpu in percpu {
|
||||
let number = cpu.get("cpu_number").map(glances_core::py_str).unwrap_or_default();
|
||||
let number = cpu
|
||||
.get("cpu_number")
|
||||
.map(glances_core::py_str)
|
||||
.unwrap_or_default();
|
||||
let total = cpu.get("total").and_then(Value::as_f64).unwrap_or(0.0);
|
||||
percpu_decoration.insert(number, json!(decoration_for_percent(&self.model, total).name()));
|
||||
percpu_decoration.insert(
|
||||
number,
|
||||
json!(decoration_for_percent(&self.model, total).name()),
|
||||
);
|
||||
}
|
||||
if percpu.len() > self.max_cpu_display && self.max_cpu_display > 0 {
|
||||
let mut hidden: Vec<f64> =
|
||||
percpu.iter().filter_map(|cpu| cpu.get("total").and_then(Value::as_f64)).collect();
|
||||
let mut hidden: Vec<f64> = percpu
|
||||
.iter()
|
||||
.filter_map(|cpu| cpu.get("total").and_then(Value::as_f64))
|
||||
.collect();
|
||||
hidden.sort_by(|a, b| b.partial_cmp(a).unwrap_or(std::cmp::Ordering::Equal));
|
||||
let hidden = &hidden[self.max_cpu_display.min(hidden.len())..];
|
||||
if !hidden.is_empty() {
|
||||
let mean = hidden.iter().sum::<f64>() / hidden.len() as f64;
|
||||
percpu_decoration.insert("other".to_string(), json!(decoration_for_percent(&self.model, mean).name()));
|
||||
percpu_decoration.insert(
|
||||
"other".to_string(),
|
||||
json!(decoration_for_percent(&self.model, mean).name()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.model.views.insert("percpu_decoration".to_string(), Value::Object(percpu_decoration));
|
||||
self.model.views.insert(
|
||||
"percpu_decoration".to_string(),
|
||||
Value::Object(percpu_decoration),
|
||||
);
|
||||
}
|
||||
|
||||
fn display_curse(&self) -> bool {
|
||||
@@ -171,26 +218,45 @@ impl Plugin for QuicklookPlugin {
|
||||
return ret;
|
||||
}
|
||||
// System information: CPU name + frequency.
|
||||
let freq = match (s.get("cpu_hz_current").and_then(Value::as_f64), s.get("cpu_hz").and_then(Value::as_f64)) {
|
||||
let freq = match (
|
||||
s.get("cpu_hz_current").and_then(Value::as_f64),
|
||||
s.get("cpu_hz").and_then(Value::as_f64),
|
||||
) {
|
||||
(Some(current), Some(max)) => format!(" {:.2}/{:.2}GHz", current / 1e9, max / 1e9),
|
||||
(Some(current), None) => format!(" {:.2}GHz", current / 1e9),
|
||||
_ => String::new(),
|
||||
};
|
||||
let cpu_name = s.get("cpu_name").and_then(Value::as_str).unwrap_or("");
|
||||
let name = if (ctx.max_width as i64 - freq.len() as i64 + 7) > 0 {
|
||||
format!("{:<width$}", cpu_name, width = ctx.max_width - freq.len() + 7)
|
||||
format!(
|
||||
"{:<width$}",
|
||||
cpu_name,
|
||||
width = ctx.max_width - freq.len() + 7
|
||||
)
|
||||
} else if freq.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
"Frequency".to_string()
|
||||
};
|
||||
ret.push(self.model.curse_add_line(name.clone(), glances_core::Decoration::Default, false, false, false));
|
||||
ret.push(self.model.curse_add_line(freq.clone(), glances_core::Decoration::Default, false, false, false));
|
||||
ret.push(self.model.curse_add_line(
|
||||
name.clone(),
|
||||
glances_core::Decoration::Default,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
));
|
||||
ret.push(self.model.curse_add_line(
|
||||
freq.clone(),
|
||||
glances_core::Decoration::Default,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
));
|
||||
ret.push(self.model.curse_new_line());
|
||||
|
||||
let bar_size = std::cmp::max(
|
||||
name.len().saturating_add(freq.len()).saturating_sub(7),
|
||||
(ctx.max_width as usize).saturating_sub(9),
|
||||
ctx.max_width.saturating_sub(9),
|
||||
)
|
||||
.max(10);
|
||||
let bar_char = self
|
||||
@@ -201,14 +267,32 @@ impl Plugin for QuicklookPlugin {
|
||||
.unwrap_or_else(|| "|".to_string());
|
||||
|
||||
let mut lines: Vec<Vec<glances_core::StatLine>> = Vec::new();
|
||||
let mut push_line = |msg: String, bar_key: &str, percent: f64, decoration: glances_core::Decoration| {
|
||||
let mut push_line = |msg: String,
|
||||
bar_key: &str,
|
||||
percent: f64,
|
||||
decoration: glances_core::Decoration| {
|
||||
let bar = glances_core::units::bar_percent(percent, bar_size, &bar_char, true);
|
||||
lines.push(vec![
|
||||
self.model.curse_add_line(msg, glances_core::Decoration::Default, false, false, false),
|
||||
self.model.curse_add_line("[", glances_core::Decoration::Bold, false, false, false),
|
||||
self.model.curse_add_line(bar, decoration, false, false, false),
|
||||
self.model.curse_add_line("]", glances_core::Decoration::Bold, false, false, false),
|
||||
self.model.curse_add_line(" ", glances_core::Decoration::Default, false, false, false),
|
||||
self.model.curse_add_line(
|
||||
msg,
|
||||
glances_core::Decoration::Default,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
self.model
|
||||
.curse_add_line("[", glances_core::Decoration::Bold, false, false, false),
|
||||
self.model
|
||||
.curse_add_line(bar, decoration, false, false, false),
|
||||
self.model
|
||||
.curse_add_line("]", glances_core::Decoration::Bold, false, false, false),
|
||||
self.model.curse_add_line(
|
||||
" ",
|
||||
glances_core::Decoration::Default,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
]);
|
||||
let _ = bar_key;
|
||||
};
|
||||
@@ -230,7 +314,11 @@ impl Plugin for QuicklookPlugin {
|
||||
for cpu in sorted.iter().take(self.max_cpu_display) {
|
||||
let cpu_id = cpu.get("cpu_number").and_then(Value::as_i64).unwrap_or(0);
|
||||
let total = cpu.get("total").and_then(Value::as_f64).unwrap_or(0.0);
|
||||
let msg = if cpu_id < 10 { format!("{:<3}{cpu_id} ", key.to_uppercase()) } else { format!("{cpu_id:4} ") };
|
||||
let msg = if cpu_id < 10 {
|
||||
format!("{:<3}{cpu_id} ", key.to_uppercase())
|
||||
} else {
|
||||
format!("{cpu_id:4} ")
|
||||
};
|
||||
let decoration = self.decoration_for_percpu(cpu_id);
|
||||
push_line(msg, key, total, decoration);
|
||||
}
|
||||
@@ -240,14 +328,28 @@ impl Plugin for QuicklookPlugin {
|
||||
.skip(self.max_cpu_display)
|
||||
.filter_map(|cpu| cpu.get("total").and_then(Value::as_f64))
|
||||
.collect();
|
||||
let mean = if hidden.is_empty() { 0.0 } else { hidden.iter().sum::<f64>() / hidden.len() as f64 };
|
||||
let mean = if hidden.is_empty() {
|
||||
0.0
|
||||
} else {
|
||||
hidden.iter().sum::<f64>() / hidden.len() as f64
|
||||
};
|
||||
let decoration = self.decoration_for_percpu(-1);
|
||||
push_line(format!("{:<3}* ", key.to_uppercase()), key, mean, decoration);
|
||||
push_line(
|
||||
format!("{:<3}* ", key.to_uppercase()),
|
||||
key,
|
||||
mean,
|
||||
decoration,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if let Some(value) = s.get(key).and_then(Value::as_f64) {
|
||||
let decoration = self.model.view_decoration(None, key);
|
||||
push_line(format!("{:<4} ", key.to_uppercase()), key, value, decoration);
|
||||
push_line(
|
||||
format!("{:<4} ", key.to_uppercase()),
|
||||
key,
|
||||
value,
|
||||
decoration,
|
||||
);
|
||||
}
|
||||
}
|
||||
for line in lines {
|
||||
@@ -261,7 +363,11 @@ impl Plugin for QuicklookPlugin {
|
||||
|
||||
impl QuicklookPlugin {
|
||||
fn decoration_for_percpu(&self, cpu_id: i64) -> glances_core::Decoration {
|
||||
let key = if cpu_id < 0 { "other".to_string() } else { cpu_id.to_string() };
|
||||
let key = if cpu_id < 0 {
|
||||
"other".to_string()
|
||||
} else {
|
||||
cpu_id.to_string()
|
||||
};
|
||||
match self.model.get_view(None, "percpu_decoration", &key) {
|
||||
Value::String(name) => glances_core::Decoration::from_name(&name),
|
||||
_ => glances_core::Decoration::Default,
|
||||
|
||||
Reference in New Issue
Block a user