From 070e8257037a43a167439a1cba981d8e6d108db7 Mon Sep 17 00:00:00 2001 From: clerie Date: Sat, 13 Jan 2024 22:57:35 +0100 Subject: [PATCH] Init repo --- .gitignore | 2 + Cargo.lock | 7 ++++ Cargo.toml | 4 ++ README.md | 3 ++ flake.lock | 27 ++++++++++++++ flake.nix | 37 ++++++++++++++++++ src/ansiiescape.rs | 11 ++++++ src/braille.rs | 8 ++++ src/cpustats.rs | 36 ++++++++++++++++++ src/cpuusagebuffer.rs | 87 +++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 4 ++ src/main.rs | 27 ++++++++++++++ 12 files changed, 253 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 src/ansiiescape.rs create mode 100644 src/braille.rs create mode 100644 src/cpustats.rs create mode 100644 src/cpuusagebuffer.rs create mode 100644 src/lib.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8ea0ee8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +result* diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..43d21b1 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "fuedra-schwitzt" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a2d45b3 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "fuedra-schwitzt" +version = "0.1.0" +edition = "2021" diff --git a/README.md b/README.md new file mode 100644 index 0000000..3e65fc3 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# fuedra-schwitzt + +This regularly checks cpu usage and prints it as utf8 braille representation diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..0fd7eb1 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1704194953, + "narHash": "sha256-RtDKd8Mynhe5CFnVT8s0/0yqtWFMM9LmCzXv/YKxnq4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "bd645e8668ec6612439a9ee7e71f7eac4099d4f6", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..2d8df0c --- /dev/null +++ b/flake.nix @@ -0,0 +1,37 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + outputs = { self, nixpkgs, ... }: { + packages.x86_64-linux = let + pkgs = import nixpkgs { + system = "x86_64-linux"; + }; + in { + fuedra-schwitzt = pkgs.rustPlatform.buildRustPackage rec { + pname = "fuedra-schwitzt"; + version = "0.1.0"; + + src = ./.; + + cargoLock.lockFile = ./Cargo.lock; + + }; + default = self.packages.x86_64-linux.fuedra-schwitzt; + }; + + apps.x86_64-linux = { + fuedra-schwitzt = { + type = "app"; + program = self.packages.x86_64-linux.fuedra-schwitzt + "/bin/fuedra-schwitzt"; + }; + default = self.apps.x86_64-linux.fuedra-schwitzt; + }; + + hydraJobs = { + inherit (self) + packages; + }; + }; +} + diff --git a/src/ansiiescape.rs b/src/ansiiescape.rs new file mode 100644 index 0000000..c5bcafb --- /dev/null +++ b/src/ansiiescape.rs @@ -0,0 +1,11 @@ +fn escape(s: String) -> String { + format!("\x1b[{}m", s) +} + +pub fn reset() -> String { + escape("0".to_string()) +} + +pub fn color(r: u8, g: u8, b: u8) -> String { + escape(format!("38;2;{};{};{}", r, g, b)) +} diff --git a/src/braille.rs b/src/braille.rs new file mode 100644 index 0000000..ac6b0fe --- /dev/null +++ b/src/braille.rs @@ -0,0 +1,8 @@ +use std::str; + +pub fn braille_symbol(nu: u8) -> String { + let lower = (nu & 0b00111111) + 0b10000000; + let upper = ((nu & 0b11000000) >> 6) + 0b10100000; + let symbol: Vec = vec![0b11100010, upper, lower]; + str::from_utf8(&symbol).unwrap().to_string() +} diff --git a/src/cpustats.rs b/src/cpustats.rs new file mode 100644 index 0000000..c33ba1f --- /dev/null +++ b/src/cpustats.rs @@ -0,0 +1,36 @@ +use std::fs; +use std::str; +use std::process::Command; + + +pub fn get_cpu_usage() -> Vec { + let stats = fs::read_to_string("/proc/stat").expect("Aren't you running linux?"); + + let elements: Vec = stats + .split("\n") + .map(|line| line + .split_whitespace() + .collect() + ) + .filter(|line: &Vec<&str>| line.len() > 0 && line[0] != "cpu" && line[0].starts_with("cpu")) + .map(|line| line[1].parse::().unwrap() + line[3].parse::().unwrap()) + .collect(); + + elements +} + +pub fn get_clk_tck() -> u32 { + let clk_tck = str::from_utf8(&Command::new("getconf") + .arg("CLK_TCK") + .output() + .expect("Are you running Linux???") + .stdout + ) + .unwrap() + .trim() + .parse::() + .unwrap(); + + clk_tck +} + diff --git a/src/cpuusagebuffer.rs b/src/cpuusagebuffer.rs new file mode 100644 index 0000000..0b73f36 --- /dev/null +++ b/src/cpuusagebuffer.rs @@ -0,0 +1,87 @@ +use crate::cpustats::get_cpu_usage; +use crate::cpustats::get_clk_tck; +use crate::ansiiescape; +use crate::braille::braille_symbol; + +pub struct CpuUsageBuffer { + clk_tck: u32, + last_value: Vec, + buffer: Vec>, +} + +fn calc_diff(a: Vec, b: Vec) -> Vec { + a.into_iter().zip(b).map(|(a, b)| b - a).collect() +} + +fn cpu_usage_to_braille(cu: u32) -> u8 { + match cu { + 0..=24 => 0b01000000, + 25..=49 => 0b01000100, + 50..=74 => 0b01000110, + 75..=100 => 0b01000111, + _ => 0, + } +} + +fn cpu_usage_to_color(cu: u32) -> String { + match cu { + 0..=19 => ansiiescape::color(0x00, 0xFF, 0x00), + 20..=39 => ansiiescape::color(0x88, 0xFF, 0x00), + 40..=59 => ansiiescape::color(0xFF, 0xFF, 0x00), + 60..=79 => ansiiescape::color(0xFF, 0x88, 0x00), + 80..=100 => ansiiescape::color(0xFF, 0x00, 0x00), + _ => "".to_string(), + } +} + +fn shift_braille_one_col(b: u8) -> u8 { + let upper = (b & 0b0000111) << 3; + let lower = (b & 0b01000000) << 1; + + upper + lower +} + +fn cpu_usages_to_braille(a: u32, b: u32) -> u8 { + let ab = cpu_usage_to_braille(a); + let bb = cpu_usage_to_braille(b); + + ab + shift_braille_one_col(bb) +} + +impl CpuUsageBuffer { + pub fn new() -> Self { + let first_value = get_cpu_usage(); + Self { + clk_tck: get_clk_tck(), + last_value: first_value.clone(), + buffer: vec![vec![0;first_value.len()];100], + } + } + + pub fn push(&mut self) { + let new_value = get_cpu_usage(); + + self.buffer.rotate_right(1); + self.buffer[0] = calc_diff(self.last_value.clone(), new_value.clone()).into_iter().map(|v| (v * 100) / self.clk_tck).collect(); + self.last_value = new_value; + } + + pub fn cpu_num(&self) -> usize { + self.buffer[0].len() + } + + pub fn braille(&self) -> String { + let mut out: String = String::new(); + for n in 0..(self.cpu_num()) { + for u in &self.buffer { + out += &cpu_usage_to_color(u[n]); + out += &braille_symbol(cpu_usages_to_braille(u[n], u[n])); + } + out += &ansiiescape::reset(); + out += "\n"; + } + + out + } +} + diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..45c5efe --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,4 @@ +pub mod ansiiescape; +pub mod braille; +pub mod cpustats; +pub mod cpuusagebuffer; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..def1e8b --- /dev/null +++ b/src/main.rs @@ -0,0 +1,27 @@ +use std::thread::sleep; +use std::time; +use fuedra_schwitzt::cpuusagebuffer::CpuUsageBuffer; + + +fn main() { + + + // Init buffer + let mut buffer = CpuUsageBuffer::new(); + + // Print buffer + print!("{}", buffer.braille()); + + for _ in 0..100 { + // Push new cpu usage stats + buffer.push(); + + // Reset paint area + print!("\x1b[{}A", buffer.cpu_num()); + // Print buffer + print!("{}", buffer.braille()); + + // Wait a while + sleep(time::Duration::from_millis(1000)); + } +}