Git Product home page Git Product logo

nixinfo's Introduction

nixinfo

A lib crate for gathering system info such as cpu, distro, environment, kernel, etc in Rust.

I may often be behind on updating the release on crates.io.

So if you want the latest and greatest, add:

nixinfo = { git = "https://github.com/Phate6660/nixinfo" }

To your dependencies section in Cargo.toml.

Otherwise add: nixinfo = "0.3.2" instead.

Currently supported

  • CPU model and temperature by thermal zones (Celsius)
    • nixinfo::cpu() -> Result<String>
    • nixinfo::temp() -> Result<Vec<(String, String)>>
      • The tuple contains the device name and the temperature in that order
  • Device name
    • nixinfo::device() -> Result<String>
  • Distro name
    • nixinfo::distro() -> Result<String>
  • Environment (e.g. DE or WM)
    • nixinfo::environment() -> Result<String>
  • env variables
    • nixinfo::env("VARIABLE") -> Option<String>
  • GPU info (requires lspci and grep to be installed for now until I find a pure rust solution)
    • nixinfo::gpu() -> Result<String>
  • Hostname
    • nixinfo::hostname() -> Result<String>
  • Kernel
    • nixinfo::kernel() -> Result<String>
  • Total memory in MBs
    • nixinfo::memory_total() -> Result<String>
  • Free memory in MBs
    • nixinfo::memory_free() -> Result<String>
  • Available memory in MBs
  • nixinfo::memory_available() -> Result<String>
  • Used memory in MBs
  • nixinfo::memory_used() -> Result<String>
  • Music info
    • Features for this:
      • music_mpd for music info from mpd
      • music_playerctl for music info from an MPRIS supporting program via playerctl
      • Enable neither of the features to get an N/A message
    • nixinfo::music() -> String
  • Package counts (managers supported are apk, apt, dnf, dpkg, eopkg, pacman, pip, portage, rpm, and xbps)
    • nixinfo::packages("manager") -> Result<String>
  • Terminal being used (unless tmux is used, in which case N/A will be outputted because reasons)
    • nixnfo::terminal() -> Result<String>
  • Uptime of device
    • nixinfo::uptime() -> Result<String>

TODO

  • Get all package counts in pure Rust
    • apk
    • apt/dpkg
      • explicitely installed
      • total installed
    • dnf
    • eopkg
    • flatpak
    • pacman
      • explicitly installed
      • total installed
    • pip
    • portage
      • explicitly installed
      • total installed
    • rpm
    • xbps
  • Get GPU in pure Rust
  • Restructure code
  • Support *BSD

nixinfo's People

Contributors

bencelaszlo avatar dam-0 avatar dependabot[bot] avatar lnicola avatar pandafoss avatar phate6660 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

nixinfo's Issues

Logical error in meminfo possible

Hi,

You assume in your implementation of memory() that "MemTotal" is always in the first line. If this is not the case, then a wrong value will be returned, which is however assumed as "correct" (here no error handling takes place, it is a "logical error").
I think the memory() function should be implemented in another way.
I've written two example implementations, you can use one of them, if you want:

use std::io;
use std::fs;

/// Obtain total memory in a human readable size, outputs to a Result<String>
pub fn memory() -> io::Result<String> {
	let meminfo = fs::read_to_string(MEMINFO)?;
	for line in meminfo.lines() {
		if line.starts_with(MEMTOTAL) {
			let mut rsplit = line.rsplit(SEPARATOR_COLON);
			let size = match rsplit.next() {
				Some(x) => x.replace(UNIT[0], EMPTY_STRING).trim().parse::<u64>().to_io_result()?,
				None => return Err(io::Error::new(io::ErrorKind::Other, ERROR_02))
			};
			let mut current_multiplier = 1.0;
			while (size as f64) >= DIVISOR_F64.powf(current_multiplier) {
				current_multiplier += 1.0;
			}
			let mut memory = String::new();
			memory.push_str(&(format!("{:.2}", (size as f64) / 
				DIVISOR_F64.powf(current_multiplier - 1.0))).to_string());
			memory.push_str(&(UNIT[(current_multiplier - 1.0) as usize].to_string()));
			return Ok(memory)
		}
	}
	Err(io::Error::new(io::ErrorKind::Other, ERROR_01))
}

/// Obtain total memory in MB, outputs to a Result<String>
pub fn memory_mb() -> io::Result<String> {
	let meminfo = fs::read_to_string(MEMINFO)?;
	for line in meminfo.lines() {
		if line.starts_with(MEMTOTAL) {
			let mut rsplit = line.rsplit(SEPARATOR_COLON);
			let size = match rsplit.next() {
				Some(x) => x.replace(UNIT[0], EMPTY_STRING).trim().parse::<u64>().to_io_result()?,
				None => return Err(io::Error::new(io::ErrorKind::Other, ERROR_02))
			};
			return Ok(format!("{} {}", (size / DIVISOR_U64), UNIT_MB))
		}
	}
	Err(io::Error::new(io::ErrorKind::Other, ERROR_01))
}

pub trait ToIOResult<T> {
	fn to_io_result(self) -> io::Result<T>;
}

impl<T, E: ToString> ToIOResult<T> for Result<T, E> {
	fn to_io_result(self) -> io::Result<T> {
		match self {
			Ok(x) => Ok(x),
			Err(err) => Err(io::Error::new(io::ErrorKind::Other, err.to_string())),
		}
	}
}

const MEMTOTAL: &str = "MemTotal";
const MEMINFO: &str = "/proc/meminfo";
const ERROR_01: &str = "no MemTotal line found in /proc/meminfo!";
const ERROR_02: &str = "No memoryinfo in MemTotal line!";
const UNIT: [&str; 5] = ["kB", "MB", "GB", "TB", "PB"];
const DIVISOR_F64: f64 = 1024.0;
const SEPARATOR_COLON: &str = ":";
const EMPTY_STRING: &str = "";

const DIVISOR_U64: u64 = 1024;
const UNIT_MB: &str = "MB";

fn main() {
    println!("{:?}", memory());
    println!("{:?}", memory_mb());
}

It's not working on mac

this is the code:

use nixinfo;

fn main() {
    let cpu = nixinfo::hostname();
    println!("cpu: {:?}", cpu);
}

and this is the error. If I'm wrong somewhere let me know

cpu: Err(Os { code: 2, kind: NotFound, message: "No such file or directory" })

Check config file if ~/.xinitrc doesn't exist !!!

Hi, Most of the people these days add xinitrc in .config, tried to make it work with the following changes. If it works for you too, let me know; will create a PR anyways.

use std::env;
use std::fs;

use crate::error::Error;

pub fn de() -> Result<String, Error> {
    Ok(env::var("XDG_DESKTOP_SESSION")
        .or_else(|_| env::var("XDG_CURRENT_DESKTOP"))
        .or_else(|_| env::var("DESKTOP_SESSION"))
        .unwrap_or_else(|_| "N/A".to_string()))
}

pub fn wm() -> Result<String, Error> {
    let home_dir = env::var("HOME").unwrap();
    let path = format!("{}/.xinitrc", home_dir);
    let file = match fs::File::open(&path) {
        Ok(file) => file,
        Err(_) => {
            let config_path = format!("{}/.config/x11/xinitrc", home_dir);
            match fs::File::open(config_path) {
                Ok(file) => file,
                Err(_) => return Err(Error::new("File not found")),
            }
        }
    };

    let contents = crate::shared_functions::read(file)?;
    let line = contents.lines().last().unwrap();
    Ok(line.split(' ').last().unwrap().to_string())
}

[Idea] Get GPU information using pure Rust

First of all, I love the initiative of the project. I started to learn Rust a few weeks ago and as my first project I set out to build a neofetch style tool, without realizing the existence of rsfetch, so I'd like to contribute here in what I can.

I saw that external commands are used to obtain information from the GPU, so I started to investigate how else could be done without depending on grep and lspci.

I found in the pciutils repository the following:

In runs on the following systems:

Linux (via /sys/bus/pci, /proc/bus/pci or i386 ports)
FreeBSD (via /dev/pci)
NetBSD (via libpci)
OpenBSD (via /dev/pci)
GNU/kFreeBSD (via /dev/pci)
Solaris/i386 (direct port access)
Aix (via /dev/pci and odmget)
GNU Hurd (direct port access)
Windows (direct port access, see README.Windows for caveats)
CYGWIN (direct port access)
BeOS (via syscalls)
Haiku (via /dev/misc/poke)
Darwin (via IOKit)
DOS/DJGPP (via i386 ports)
SylixOS (via /proc/pci)

There are many possible places to search, depending on the kernel (or operating system). But in some cases it's a matter of reading a plain text file. In order not to make the issue too long, I recommend the first part of this article. As you can see in the article, it is possible to read the vendor identifier, device identifier and class identifier.

I quote again the previous repository, the following:

The database of PCI IDs (the pci.ids file) gets out of date much faster
than I release new versions of this package, so it is maintained separately.

It lives at https://pci-ids.ucw.cz/, where you can browse the database,
download the most recent pci.ids file (e.g., by running the update-ids utility)
and also submit new entries.

If we go through that website, we can corroborate that the GPU information (in addition to other devices that are not relevant) can be obtained from these ID's.

At first I thought that the pci.ids file should be downloaded regularly to keep it updated but, at least in Arch Linux, I found it in /usr/share/hwdata/pci.ids.

I'm not sure this is the best way to solve it, but I think it can work, without relying on system commands or external crates.

[Feature] Windows Support

Similar to MacOS Support #5, it would be nice if Windows was a supported target, It may be possible to reference winfetch for some inspiration.

This should probably include Win-Get and Chocolatey package counts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.