From e9b572888e3bd85ff1370cfbfeef5a234e783799 Mon Sep 17 00:00:00 2001 From: Xorycode Date: Fri, 5 Apr 2024 17:28:52 +0300 Subject: [PATCH] Restructure according to standard and remove ansi_term dependency --- Cargo.lock | 36 +--------- Cargo.toml | 3 +- shell.nix | 11 +++ src/lib.rs | 178 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 193 +++++----------------------------------------------- 5 files changed, 208 insertions(+), 213 deletions(-) create mode 100644 shell.nix create mode 100644 src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 736ffde..0dfe62e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,40 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "mrfetch" -version = "0.1.0" -dependencies = [ - "ansi_term", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index 175b8fd..513cd5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,8 @@ [package] name = "mrfetch" -version = "0.1.0" +version = "2.0.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -ansi_term = "0.12.1" diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..e0c93b8 --- /dev/null +++ b/shell.nix @@ -0,0 +1,11 @@ +{ pkgs ? import {} }: + pkgs.mkShell { + nativeBuildInputs = with pkgs.buildPackages; [ + rustup + git + ]; + shellHook = '' + rustup default stable + rustup component add rust-analyzer + ''; + } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..803d907 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,178 @@ +use std::env; +use std::fs::File; +use std::io::{BufRead, BufReader}; + +pub struct Machine { + pub user: String, + pub hostname: String, + pub distro: String, + pub kernel: String, + pub uptime: String, + pub shell: String, + pub ramused: u32, + pub ramtotal: u32, + pub ramavail: u32, + pub cpu: String, +} + +impl Machine { + pub fn new() -> Machine { + let user: String = env::var("USER").unwrap(); + + let mut hostname = String::new(); + { + let hostname_file = File::open("/etc/hostname") + .expect("u forgor the /etc/hostname file u arch-using moronbox"); + let mut hostname_reader = BufReader::new(hostname_file); + hostname_reader.read_line(&mut hostname).expect("Failed string conversion... EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"); + hostname = hostname.trim().to_string(); + } + + // Read release file, AKA get OS name + let mut release_distro = String::new(); + { + let release_file = File::open("/etc/os-release").expect("Failed to find release file."); + let release_reader = BufReader::new(release_file); + for line in release_reader.lines() { + let unwrapped_line: String = line.unwrap(); + if unwrapped_line.starts_with("PRETTY_NAME=") { + release_distro = unwrapped_line + } + } + } + let mut distro_name: String = release_distro[12..release_distro.len() - 1].to_string(); + distro_name = distro_name.replace('\"', ""); + + // Quick fix for NixOS + // I know I should change the way the program gets the distro, but I haven't been able to find a + // fix that doesn't rely on other crates or libraries. + if distro_name.starts_with("NixOS") { + distro_name = "NixOS".to_string(); + } + let distro: String = distro_name; + + let mut kernel = String::new(); + { + let kernel_file = File::open("/proc/version").expect("Read the README.md you dumbass"); + let mut kernel_reader = BufReader::new(kernel_file); + kernel_reader + .read_line(&mut kernel) + .expect("Failed string conversion"); + } + + let mut kernel_name: String = (kernel[14..kernel.len()]).to_string(); + kernel_name = kernel_name.split_whitespace().next().unwrap().to_string(); + + // Read memfile + #[allow(unused_assignments)] + let mut uptime_mins: u32 = 0; + let mut ramused: u32 = 0; + let mut ramtotal: u32 = 0; + let mut ramavail: u32 = 0; + if let Ok(file) = File::open("/proc/meminfo") { + // Reader & Iterator + let reader = BufReader::new(file); + let mut lines = reader.lines(); + + // Read 1st & 2nd line + if let Some(Ok(line)) = lines.next() { + if let Some(idx) = line.find(char::is_whitespace) { + // Reading & Parsing + let mut line_processed = line[idx..].trim(); + line_processed = &line_processed[0..line_processed.len() - 3]; + // mafs + let mut ram_gb: u32 = line_processed.parse().unwrap(); + ram_gb /= 1048576; + ramtotal = ram_gb; + } + } + + lines.next(); + + if let Some(Ok(line)) = lines.next() { + if let Some(idx) = line.find(char::is_whitespace) { + // Reading & Parsing + let mut line_processed = line[idx..].trim(); + line_processed = &line_processed[0..line_processed.len() - 3]; + // mafs + let mut ram_gb: u32 = line_processed.parse().unwrap(); + ram_gb /= 1048576; + ramavail = ram_gb; + } + } + + ramused = ramtotal - ramavail; + + } + + { + // This took me unusually long. + + // Generic file stuff + let mut uptime = String::new(); + let uptime_file = File::open("/proc/uptime").expect(":skull:"); + let mut uptime_reader = BufReader::new(uptime_file); + uptime_reader.read_line(&mut uptime).expect("what"); + let mut iterator = uptime.split_whitespace(); + uptime = iterator + .next() + .expect("*screeches at the top of his lungs*") + .to_string(); + + // was never expecting rounding to be this difficult + let uptimeint = uptime.parse::(); + let roundeduptimeint: u32 = uptimeint.expect("phoque").round() as u32; + uptime_mins = roundeduptimeint / 60; + } + + // Get shell + let mut shell = String::new(); + let shell_raw = env::var("SHELL").expect("Could not read $SHELL variable"); + + // Split the path using '/' as the separator + // Thanks ChatGPT + let parts: Vec<&str> = shell_raw.rsplitn(2, '/').collect(); + + // Check if the path contains at least one '/' + if parts.len() > 1 { + shell = parts[0].to_string(); + } + + + let mut cpu = String::new(); + // Time for a challenge, Get CPU model! + { + let file = File::open("/proc/cpuinfo").expect("Could not read /proc/cpuinfo"); + let reader = BufReader::new(file); + let mut lines = reader.lines(); + + // Read up until the 5th line + let mut i = 1; + while i < 5 { + lines.next(); + i += 1; + } + + if let Some(Ok(line)) = lines.next() { + cpu = line + .split(':') + .nth(1) + .expect("Failed to parse CPU Info") + .trim() + .to_string(); + } + } + + + // Fucking finally. + Machine { user, hostname, distro, kernel: kernel_name, uptime: uptime_mins.to_string(), shell, ramused, ramtotal, ramavail, cpu } + + } + +} + +impl Default for Machine { + fn default() -> Self { + Self::new() + } +} diff --git a/src/main.rs b/src/main.rs index 49ec146..1045a32 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,184 +1,25 @@ -use std::fs::File; -use std::io::{BufRead, BufReader}; +use mrfetch::Machine; use std::process::Command; -use ansi_term::Colour::{Red, Green, Yellow, Blue, Purple, Cyan}; -use std::env; fn main() { + let machine = Machine::new(); - // User & hostname - // let user = Command::new("whoami") - // .output() - // .expect("Failed to get user"); + let figlet = Command::new("figlet") + .args(["-f", "smslant", machine.distro.as_str()]) + .output() + .expect("AS OF THE UPDATE, FIGLET IS *NECESSARY*."); - // let user = String::from_utf8_lossy(&user.stdout); + let figlet: String = String::from_utf8(figlet.stdout).unwrap().trim_end().to_string(); // No possible way the shell can return non-UTF-8... right? RIGHT!? - // let hostname = Command::new("uname") - // .args(["-n"]) - // .output() - // .expect("Failed to get hostname"); - - - - // let hostname = String::from_utf8_lossy(&hostname.stdout); - let user = env::var("USER"); - - let mut hostname = String::new(); - { - let hostname_file = File::open("/etc/hostname").expect("u forgor the /etc/hostname file u arch-using moronbox"); - let mut hostname_reader = BufReader::new(hostname_file); - hostname_reader.read_line(&mut hostname).expect("Failed string conversion... EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"); - } - - // Read release file, AKA get OS name - let mut release_distro = String::new(); - { - let release_file = File::open("/etc/os-release").expect("Failed to find release file."); - let mut release_reader = BufReader::new(release_file); - release_reader.read_line(&mut release_distro).expect("Failed string conversion."); - } - - // Release file processing, huge credit to ChatGPT for this one! - let mut distro_name: String = release_distro[5..release_distro.len() - 1].to_string(); - distro_name = distro_name.replace('\"', ""); - // println!("OS: {}", Red.paint(distro_name.clone())); - - // Quick fix for NixOS - // I know I should change the way the program gets the distro, but I haven't been able to find a - // fix that doesn't rely on other crates or libraries. - if distro_name == "EPORT_URL=https://github.com/NixOS/nixpkgs/issues" { - distro_name = "NixOS".to_string(); - } - - let figlet = Command::new("figlet") - .args(["-f", "smslant", &distro_name]) - .output(); - - if let Ok(output) = figlet { - let output = String::from_utf8_lossy(&output.stdout); - print!("{}", output); - } - // Print all the things we've been saving. - println!("{}@{}", user.unwrap(), hostname); - println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); - println!("┐ OS: {}", Red.paint(distro_name)); - - // I know it's terrible, but it works. - let mut kernel = String::new(); - { - let kernel_file = File::open("/proc/version").expect("Read the README.md you dumbass"); - let mut kernel_reader = BufReader::new(kernel_file); - kernel_reader.read_line(&mut kernel).expect("Failed string conversion"); - } - - let mut kernel_name: String = (kernel[14..kernel.len()]).to_string(); - kernel_name = kernel_name.split_whitespace() - .next() - .unwrap() - .to_string(); - - println!("│ Kernel: {}", Yellow.paint(kernel_name.trim())); - - // Read memfile - if let Ok(file) = File::open("/proc/meminfo") { - // Reader & Iterator - let reader = BufReader::new(file); - let mut lines = reader.lines(); - - // Vars - let mut ramtotal: u32 = 0; - let mut ramavail: u32 = 0; - - // Read 1st & 2nd line - if let Some(Ok(line)) = lines.next() { - if let Some(idx) = line.find(char::is_whitespace) { - // Reading & Parsing - let mut line_processed = line[idx..].trim(); - line_processed = &line_processed[0..line_processed.len() - 3]; - // mafs - let mut ram_gb: u32 = line_processed.parse().unwrap(); - ram_gb /= 1048576; - ramtotal = ram_gb; - } - } - - lines.next(); - - if let Some(Ok(line)) = lines.next() { - if let Some(idx) = line.find(char::is_whitespace) { - // Reading & Parsing - let mut line_processed = line[idx..].trim(); - line_processed = &line_processed[0..line_processed.len() - 3]; - // mafs - let mut ram_gb: u32 = line_processed.parse().unwrap(); - ram_gb /= 1048576; - ramavail = ram_gb; - } - } - - let ramused = ramtotal - ramavail; - - println!("│ Mem: {}/{} GB ({} GB Available)", Green.paint(ramused.to_string()), Green.paint(ramtotal.to_string()), Green.paint(ramavail.to_string())); - - } - - { - // This took me unusually long. - - // Generic file stuff - let mut uptime = String::new(); - let uptime_file = File::open("/proc/uptime").expect(":skull:"); - let mut uptime_reader = BufReader::new(uptime_file); - uptime_reader.read_line(&mut uptime).expect("what"); - let mut iterator = uptime.split_whitespace(); - uptime = iterator.next().expect("*screeches at the top of his lungs*").to_string(); - - // was never expecting rounding to be this difficult - let uptimeint = uptime.parse::(); - let roundeduptimeint: u32 = uptimeint.expect("phoque").round() as u32; - let uptimemins: u32 = roundeduptimeint / 60; - println!("│ Uptime: {} minutes", Blue.paint(uptimemins.to_string())) - - } - - // Get shell - let shell_raw = env::var("SHELL").expect("Could not read $SHELL variable"); - - // Split the path using '/' as the separator - // Thanks ChatGPT - let parts: Vec<&str> = shell_raw.rsplitn(2, '/').collect(); - - // Check if the path contains at least one '/' - if parts.len() > 1 { - let shell = parts[0]; - println!("│ Shell: {}", Cyan.paint(shell)); - } else { - println!("Invalid path format."); - } - // Time for a challenge, Get CPU model! - { - let file = File::open("/proc/cpuinfo").expect("Could not read /proc/cpuinfo"); - let reader = BufReader::new(file); - let mut lines = reader.lines(); - - // Read up until the 5th line - let mut i = 1; - while i < 5 { - lines.next(); - i += 1; - - } - let mut model: String = String::new(); - - if let Some(Ok(line)) = lines.next() { - model = line.split(':').nth(1).expect("Failed to parse CPU Info").trim().to_string(); - } - - println!("┘ CPU: {}", Purple.paint(model)); - - } - - // Colours - println!("\n{} {} {} {} {} {}", Red.paint("◆"), Green.paint("◆"), Yellow.paint("◆"), Blue.paint("◆"), Purple.paint("◆"), Cyan.paint("◆")); + println!("{} +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +\x1B[38:5:15m┐\x1B[38:5:196m • User: {} +\x1B[38:5:15m│\x1B[38:5:226m • Hostname: {} +\x1B[38:5:15m│\x1B[38:5:46m • Kernel Version: {} +\x1B[38:5:15m│\x1B[38:5:45m • Uptime (minutes): {} +\x1B[38:5:15m│\x1B[38:5:165m • Shell: {} +\x1B[38:5:15m│\x1B[38:5:201m • RAM: {} +\x1B[38:5:15m┘\x1B[38:5:219m • CPU: {} ", + figlet, machine.user, machine.hostname, machine.kernel, machine.uptime, machine.shell, machine.ramtotal, machine.cpu); }