Skip to content

Commit

Permalink
Add GPU information to basic system information
Browse files Browse the repository at this point in the history
  • Loading branch information
dormant-user committed Sep 27, 2024
1 parent 082c12e commit 5c578e0
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 3 deletions.
File renamed without changes.
134 changes: 134 additions & 0 deletions src/legacy/gpu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use std::collections::HashMap;
use serde_json::Value;
use crate::squire;

pub fn get_gpu_info() -> Vec<HashMap<String, String>> {
let operating_system = std::env::consts::OS;
match operating_system {
"macos" => get_gpu_info_darwin("/usr/sbin/system_profiler"),
"linux" => get_gpu_info_linux("/usr/bin/lspci"),
"windows" => get_gpu_info_windows("C:\\Windows\\System32\\wbem\\wmic.exe"),
_ => {
log::error!("Unsupported operating system: {}", operating_system);
Vec::new()
}
}
}

fn get_gpu_info_darwin(lib_path: &str) -> Vec<HashMap<String, String>> {
let result = squire::util::run_command(
lib_path,
&["SPDisplaysDataType", "-json"],
true
);
if result.is_err() {
return Vec::new();
}
let json: Value = serde_json::from_str(&result.unwrap()).unwrap();

let displays = json["SPDisplaysDataType"].as_array().unwrap();
let mut gpu_info = Vec::new();

let na = "N/A".to_string();
for display in displays {
if let Some(model) = display.get("sppci_model") {
let mut info = HashMap::new();
info.insert(
"model".to_string(),
model.as_str()
.unwrap_or(na.as_str())
.to_string()
);

// Handle cores
info.insert(
"cores".to_string(),
display.get("sppci_cores")
.or(display.get("spdisplays_cores"))
.and_then(|v| v.as_str())
.unwrap_or(&na)
.to_string(),
);

// Handle memory
info.insert(
"memory".to_string(),
display.get("sppci_vram")
.or(display.get("spdisplays_vram"))
.and_then(|v| v.as_str())
.unwrap_or(&na)
.to_string(),
);

// Handle vendor
info.insert(
"vendor".to_string(),
display.get("sppci_vendor")
.and_then(|v| v.as_str())
.unwrap_or(&na)
.to_string(),
);

gpu_info.push(info);
}
}
gpu_info
}

fn get_gpu_info_linux(lib_path: &str) -> Vec<HashMap<String, String>> {
let result = squire::util::run_command(
lib_path,
&[],
true
);
if result.is_err() {
return Vec::new();
}
let mut gpu_info = Vec::new();
for line in result.unwrap().lines() {
if line.contains("VGA") {
let gpu = line.split(':').last().unwrap().trim();
let mut info = HashMap::new();
info.insert("model".to_string(), gpu.to_string());
gpu_info.push(info);
}
}
gpu_info
}

fn get_gpu_info_windows(lib_path: &str) -> Vec<HashMap<String, String>> {
let result = squire::util::run_command(
lib_path,
&["path", "win32_videocontroller", "get", "Name,AdapterCompatibility", "/format:csv"],
true
);
if result.is_err() {
return Vec::new();
}
let stdout = result.unwrap();
let gpus_raw: Vec<&str> = stdout.lines().filter(|line| !line.trim().is_empty()).collect();
if gpus_raw.is_empty() {
return vec![];
}

let keys: Vec<String> = gpus_raw[0]
.replace("Node", "node")
.replace("AdapterCompatibility", "vendor")
.replace("Name", "model")
.split(',')
.map(|key| key.to_string())
.collect();

let mut gpu_info = Vec::new();

for values in gpus_raw[1..].chunks(keys.len()) {
if values.len() == keys.len() {
let mut info = HashMap::new();
for (key, value) in keys.iter().zip(values.iter()) {
info.insert(key.clone(), value.to_string());
}
gpu_info.push(info);
}
}
gpu_info
}
4 changes: 3 additions & 1 deletion src/legacy/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/// This module contains functions that gathers CPU brand information.
pub mod cpu_brand;
pub mod cpu;
/// This module contains functions that gathers GPU brand information.
pub mod gpu;
/// This module contains disk related functions.
pub mod disks;
22 changes: 20 additions & 2 deletions src/resources/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ pub fn get_disks(disks: &Disks) -> Vec<HashMap<String, String>> {
disks_info
}


fn get_gpu_info() -> Vec<String> {
let gpu_info = legacy::gpu::get_gpu_info();
log::info!("GPUs: {:?}", gpu_info);
let mut gpus: Vec<String> = vec![];
for gpu in gpu_info {
if let Some(gpu_model) = gpu.get("model") {
gpus.push(gpu_model.to_string());
}
}
gpus
}

/// Function to get CPU brand names as a comma separated string.
///
/// # Arguments
Expand All @@ -54,7 +67,7 @@ fn get_cpu_brand(sys: &System) -> String {
cpu_brands.insert(cpu.brand().to_string());
}
if cpu_brands.is_empty() {
let legacy_cpu_brand_name = legacy::cpu_brand::get_name();
let legacy_cpu_brand_name = legacy::cpu::get_name();
return if let Some(cpu_brand) = legacy_cpu_brand_name {
log::debug!("Using legacy methods for CPU brand!!");
cpu_brand
Expand Down Expand Up @@ -97,14 +110,19 @@ pub fn get_sys_info(disks: &Disks) -> HashMap<&'static str, HashMap<&'static str

// Basic and Memory/Storage Info
let os_arch = resources::system::os_arch();
let basic = HashMap::from_iter(vec![
let mut basic = HashMap::from_iter(vec![
("Hostname", System::host_name().unwrap_or("Unknown".to_string())),
("Operating System", squire::util::capwords(&os_arch.name, None)),
("Architecture", os_arch.architecture),
("Uptime", uptime),
("CPU cores", sys.cpus().len().to_string()),
("CPU brand", get_cpu_brand(&sys))
]);
let gpu_info = get_gpu_info();
if !gpu_info.is_empty() {
let key = if gpu_info.len() == 1 { "GPU" } else { "GPUs" };
basic.insert(key, gpu_info.join(", "));
}
let mut hash_vec = vec![
("Memory", total_memory),
("Storage", total_storage)
Expand Down

0 comments on commit 5c578e0

Please sign in to comment.