CPU, GPU and memory information have been converted to Golang functions
This commit is contained in:
parent
1fc9a9ea79
commit
a29a8f1dd9
207
Utils.go
Normal file
207
Utils.go
Normal file
@ -0,0 +1,207 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"github.com/jackmordaunt/ghw"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type DistroInfo struct {
|
||||
ID string
|
||||
LongName string
|
||||
ShortName string
|
||||
}
|
||||
|
||||
func getDistroInfo() DistroInfo {
|
||||
distroID := ""
|
||||
var releaseMap = make(map[string]string)
|
||||
if _, err := os.Stat("/etc/os-release"); err == nil {
|
||||
releaseMap, err = readKeyValueFile("/etc/os-release")
|
||||
if err != nil {
|
||||
return DistroInfo{
|
||||
ID: "unknown",
|
||||
LongName: "Unknown",
|
||||
ShortName: "Unknown",
|
||||
}
|
||||
}
|
||||
if value, ok := releaseMap["ID"]; ok {
|
||||
distroID = value
|
||||
}
|
||||
}
|
||||
|
||||
switch distroID {
|
||||
default:
|
||||
if id, ok := releaseMap["ID"]; ok {
|
||||
if longName, ok := releaseMap["PRETTY_NAME"]; ok {
|
||||
if shortName, ok := releaseMap["NAME"]; ok {
|
||||
return DistroInfo{
|
||||
ID: id,
|
||||
LongName: longName,
|
||||
ShortName: shortName,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return DistroInfo{
|
||||
ID: "unknown",
|
||||
LongName: "Unknown",
|
||||
ShortName: "Unknown",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getDistroAsciiArt() string {
|
||||
defaultAscii :=
|
||||
` .--.
|
||||
|o_o |
|
||||
|:_/ |
|
||||
// \ \
|
||||
(| | )
|
||||
/'\_ _/'\
|
||||
\___)=(___/ `
|
||||
var id string
|
||||
if config.Ascii == "auto" {
|
||||
id = getDistroInfo().ID
|
||||
} else {
|
||||
id = config.Ascii
|
||||
}
|
||||
userConfDir, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
if _, err := os.Stat(path.Join("/etc/stormfetch/ascii/", id)); err == nil {
|
||||
bytes, err := os.ReadFile(path.Join("/etc/stormfetch/ascii/", id))
|
||||
if err != nil {
|
||||
return defaultAscii
|
||||
}
|
||||
return string(bytes)
|
||||
} else {
|
||||
return defaultAscii
|
||||
}
|
||||
}
|
||||
if _, err := os.Stat(path.Join(userConfDir, "stormfetch/ascii/", id)); err == nil {
|
||||
bytes, err := os.ReadFile(path.Join(userConfDir, "stormfetch/ascii/", id))
|
||||
if err != nil {
|
||||
return defaultAscii
|
||||
}
|
||||
return string(bytes)
|
||||
} else if _, err := os.Stat(path.Join("/etc/stormfetch/ascii/", id)); err == nil {
|
||||
bytes, err := os.ReadFile(path.Join("/etc/stormfetch/ascii/", id))
|
||||
if err != nil {
|
||||
return defaultAscii
|
||||
}
|
||||
return string(bytes)
|
||||
} else {
|
||||
return defaultAscii
|
||||
}
|
||||
}
|
||||
|
||||
func getCPUName() string {
|
||||
cpu, err := ghw.CPU()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return cpu.Processors[0].Model
|
||||
}
|
||||
|
||||
func getCPUThreads() int {
|
||||
cpu, err := ghw.CPU()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return int(cpu.TotalThreads)
|
||||
}
|
||||
|
||||
func getGPUName() string {
|
||||
null, _ := os.Open(os.DevNull)
|
||||
serr := os.Stderr
|
||||
os.Stderr = null
|
||||
gpu, err := ghw.GPU()
|
||||
defer null.Close()
|
||||
os.Stderr = serr
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
if len(gpu.GraphicsCards) == 0 {
|
||||
return ""
|
||||
}
|
||||
return gpu.GraphicsCards[0].DeviceInfo.Product.Name
|
||||
}
|
||||
|
||||
type Memory struct {
|
||||
MemTotal int
|
||||
MemFree int
|
||||
MemAvailable int
|
||||
}
|
||||
|
||||
func GetMemoryInfo() Memory {
|
||||
toInt := func(raw string) int {
|
||||
if raw == "" {
|
||||
return 0
|
||||
}
|
||||
res, err := strconv.Atoi(raw)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
parseLine := func(raw string) (key string, value int) {
|
||||
text := strings.ReplaceAll(raw[:len(raw)-2], " ", "")
|
||||
keyValue := strings.Split(text, ":")
|
||||
return keyValue[0], toInt(keyValue[1])
|
||||
}
|
||||
|
||||
file, err := os.Open("/proc/meminfo")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
bufio.NewScanner(file)
|
||||
scanner := bufio.NewScanner(file)
|
||||
res := Memory{}
|
||||
for scanner.Scan() {
|
||||
key, value := parseLine(scanner.Text())
|
||||
switch key {
|
||||
case "MemTotal":
|
||||
res.MemTotal = value / 1024
|
||||
case "MemFree":
|
||||
res.MemFree = value / 1024
|
||||
case "MemAvailable":
|
||||
res.MemAvailable = value / 1024
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func stripAnsii(str string) string {
|
||||
const ansi = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
|
||||
var re = regexp.MustCompile(ansi)
|
||||
return re.ReplaceAllString(str, "")
|
||||
}
|
||||
|
||||
func readKeyValueFile(filepath string) (map[string]string, error) {
|
||||
ret := make(map[string]string)
|
||||
if _, err := os.Stat(filepath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bytes, err := os.ReadFile(filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
str := string(bytes)
|
||||
lines := strings.Split(str, "\n")
|
||||
for _, line := range lines {
|
||||
if len(strings.Split(line, "=")) >= 2 {
|
||||
key := strings.SplitN(line, "=", 2)[0]
|
||||
value := strings.SplitN(line, "=", 2)[1]
|
||||
if strings.HasPrefix(value, "\"") && strings.HasSuffix(value, "\"") {
|
||||
value = value[1 : len(value)-1]
|
||||
}
|
||||
ret[key] = value
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
@ -5,11 +5,11 @@ echo -e "${C3}Hostname: ${C4}$(cat /etc/hostname)"
|
||||
echo -e "${C3}Kernel: ${C4}$(uname -s) $(uname -r)"
|
||||
echo -e "${C3}Packages: ${C4}$(get_packages)"
|
||||
echo -e "${C3}Shell: ${C4}$(get_shell)"
|
||||
echo -e "${C3}CPU: ${C4}$(get_cpu_name) ($(nproc) threads)"
|
||||
if command_exists lshw; then
|
||||
echo -e "${C3}GPU: ${C4}$(lshw -class display 2> /dev/null | grep 'product' | cut -d":" -f2 | xargs)"
|
||||
echo -e "${C3}CPU: ${C4}${CPU_MODEL} (${CPU_THREADS} threads)"
|
||||
if [ ! -z "$GPU_MODEL" ]; then
|
||||
echo -e "${C3}GPU: ${C4}${GPU_MODEL})"
|
||||
fi
|
||||
echo -e "${C3}Memory: ${C4}$(get_used_mem) MiB / $(get_total_mem) MiB"
|
||||
echo -e "${C3}Memory: ${C4}${MEM_USED} MiB / ${MEM_TOTAL} MiB"
|
||||
if xhost >& /dev/null ; then
|
||||
if get_de_wm &> /dev/null; then
|
||||
echo -e "${C3}DE/WM: ${C4}$(get_de_wm)"
|
||||
|
@ -34,22 +34,6 @@ get_shell() {
|
||||
esac
|
||||
}
|
||||
|
||||
get_cpu_name() {
|
||||
grep -m1 "model name" /proc/cpuinfo | cut -d: -f2 | xargs
|
||||
}
|
||||
|
||||
get_total_mem() {
|
||||
free --mebi -t | grep 'Total' | tr -s ' ' | cut -d" " -f2
|
||||
}
|
||||
|
||||
get_free_mem() {
|
||||
free --mebi -t | grep 'Total' | tr -s ' ' | cut -d" " -f4
|
||||
}
|
||||
|
||||
get_used_mem() {
|
||||
free --mebi -t | grep 'Total' | tr -s ' ' | cut -d" " -f3
|
||||
}
|
||||
|
||||
get_de_wm() {
|
||||
if ps -e | grep "plasmashell" &> /dev/null ; then
|
||||
echo "KDE Plasma $(plasmashell --version | awk '{print $2}')"
|
||||
|
17
go.mod
17
go.mod
@ -2,4 +2,19 @@ module stormfetch
|
||||
|
||||
go 1.22
|
||||
|
||||
require gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
require (
|
||||
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/jackmordaunt/ghw v1.0.4 // indirect
|
||||
github.com/jackmordaunt/pcidb v1.0.1 // indirect
|
||||
github.com/jackmordaunt/wmi v1.2.4 // indirect
|
||||
github.com/jaypipes/ghw v0.12.0 // indirect
|
||||
github.com/jaypipes/pcidb v1.0.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
golang.org/x/sys v0.3.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
howett.net/plist v1.0.0 // indirect
|
||||
)
|
||||
|
31
go.sum
31
go.sum
@ -1,3 +1,34 @@
|
||||
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
|
||||
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/jackmordaunt/ghw v1.0.4 h1:as+COFuPuXaNQC3WqzoHS/E2JYWZU7gN8ompNTUxNxs=
|
||||
github.com/jackmordaunt/ghw v1.0.4/go.mod h1:4dReYvJ36CoAzIxlEx8du25Qi/YqKYvEGE9QJoRXiK8=
|
||||
github.com/jackmordaunt/pcidb v1.0.1 h1:uLLZa6kD5P39r2cwMyJJkxmuHfH9Wq19gYQEbYcB0Z4=
|
||||
github.com/jackmordaunt/pcidb v1.0.1/go.mod h1:OMmhrZOZVu2hYXhBDZXddypxwKR/dp4DbIgzCkQDxdQ=
|
||||
github.com/jackmordaunt/wmi v1.2.4 h1:/XyuMiKby0qXNQp1j0uU0JqTWLM0QGOVok1Hf5Yagtg=
|
||||
github.com/jackmordaunt/wmi v1.2.4/go.mod h1:K/+FH4467Vk2fJXhYQTZzhctkCMMR7PwHqKbnizFySo=
|
||||
github.com/jaypipes/ghw v0.11.0/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g=
|
||||
github.com/jaypipes/ghw v0.12.0 h1:xU2/MDJfWmBhJnujHY9qwXQLs3DBsf0/Xa9vECY0Tho=
|
||||
github.com/jaypipes/ghw v0.12.0/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g=
|
||||
github.com/jaypipes/pcidb v1.0.0 h1:vtZIfkiCUE42oYbJS0TAq9XSfSmcsgo9IdxSm9qzYU8=
|
||||
github.com/jaypipes/pcidb v1.0.0/go.mod h1:TnYUvqhPBzCKnH34KrIX22kAeEbDCSRJ9cqLRCuNDfk=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
|
||||
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||
|
128
main.go
128
main.go
@ -31,12 +31,6 @@ type StormfetchConfig struct {
|
||||
DependencyWarning bool `yaml:"dependency_warning"`
|
||||
}
|
||||
|
||||
type DistroInfo struct {
|
||||
ID string
|
||||
LongName string
|
||||
ShortName string
|
||||
}
|
||||
|
||||
func main() {
|
||||
readConfig()
|
||||
}
|
||||
@ -147,6 +141,16 @@ func readConfig() {
|
||||
}
|
||||
cmd.Env = append(cmd.Env, "DISTRO_LONG_NAME="+getDistroInfo().LongName)
|
||||
cmd.Env = append(cmd.Env, "DISTRO_SHORT_NAME="+getDistroInfo().ShortName)
|
||||
cmd.Env = append(cmd.Env, "CPU_MODEL="+getCPUName())
|
||||
cmd.Env = append(cmd.Env, "CPU_THREADS="+strconv.Itoa(getCPUThreads()))
|
||||
memory := GetMemoryInfo()
|
||||
cmd.Env = append(cmd.Env, "MEM_TOTAL="+strconv.Itoa(memory.MemTotal))
|
||||
cmd.Env = append(cmd.Env, "MEM_USED="+strconv.Itoa(memory.MemTotal-memory.MemAvailable))
|
||||
cmd.Env = append(cmd.Env, "MEM_FREE="+strconv.Itoa(memory.MemAvailable))
|
||||
|
||||
if getGPUName() != "" {
|
||||
cmd.Env = append(cmd.Env, "GPU_MODEL="+getGPUName())
|
||||
}
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@ -181,115 +185,3 @@ func readConfig() {
|
||||
}
|
||||
fmt.Println(final)
|
||||
}
|
||||
|
||||
func readKeyValueFile(filepath string) (map[string]string, error) {
|
||||
ret := make(map[string]string)
|
||||
if _, err := os.Stat(filepath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bytes, err := os.ReadFile(filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
str := string(bytes)
|
||||
lines := strings.Split(str, "\n")
|
||||
for _, line := range lines {
|
||||
if len(strings.Split(line, "=")) >= 2 {
|
||||
key := strings.SplitN(line, "=", 2)[0]
|
||||
value := strings.SplitN(line, "=", 2)[1]
|
||||
if strings.HasPrefix(value, "\"") && strings.HasSuffix(value, "\"") {
|
||||
value = value[1 : len(value)-1]
|
||||
}
|
||||
ret[key] = value
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func getDistroInfo() DistroInfo {
|
||||
distroID := ""
|
||||
var releaseMap = make(map[string]string)
|
||||
if _, err := os.Stat("/etc/os-release"); err == nil {
|
||||
releaseMap, err = readKeyValueFile("/etc/os-release")
|
||||
if err != nil {
|
||||
return DistroInfo{
|
||||
ID: "unknown",
|
||||
LongName: "Unknown",
|
||||
ShortName: "Unknown",
|
||||
}
|
||||
}
|
||||
if value, ok := releaseMap["ID"]; ok {
|
||||
distroID = value
|
||||
}
|
||||
}
|
||||
|
||||
switch distroID {
|
||||
default:
|
||||
if id, ok := releaseMap["ID"]; ok {
|
||||
if longName, ok := releaseMap["PRETTY_NAME"]; ok {
|
||||
if shortName, ok := releaseMap["NAME"]; ok {
|
||||
return DistroInfo{
|
||||
ID: id,
|
||||
LongName: longName,
|
||||
ShortName: shortName,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return DistroInfo{
|
||||
ID: "unknown",
|
||||
LongName: "Unknown",
|
||||
ShortName: "Unknown",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getDistroAsciiArt() string {
|
||||
defaultAscii :=
|
||||
` .--.
|
||||
|o_o |
|
||||
|:_/ |
|
||||
// \ \
|
||||
(| | )
|
||||
/'\_ _/'\
|
||||
\___)=(___/ `
|
||||
var id string
|
||||
if config.Ascii == "auto" {
|
||||
id = getDistroInfo().ID
|
||||
} else {
|
||||
id = config.Ascii
|
||||
}
|
||||
userConfDir, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
if _, err := os.Stat(path.Join("/etc/stormfetch/ascii/", id)); err == nil {
|
||||
bytes, err := os.ReadFile(path.Join("/etc/stormfetch/ascii/", id))
|
||||
if err != nil {
|
||||
return defaultAscii
|
||||
}
|
||||
return string(bytes)
|
||||
} else {
|
||||
return defaultAscii
|
||||
}
|
||||
}
|
||||
if _, err := os.Stat(path.Join(userConfDir, "stormfetch/ascii/", id)); err == nil {
|
||||
bytes, err := os.ReadFile(path.Join(userConfDir, "stormfetch/ascii/", id))
|
||||
if err != nil {
|
||||
return defaultAscii
|
||||
}
|
||||
return string(bytes)
|
||||
} else if _, err := os.Stat(path.Join("/etc/stormfetch/ascii/", id)); err == nil {
|
||||
bytes, err := os.ReadFile(path.Join("/etc/stormfetch/ascii/", id))
|
||||
if err != nil {
|
||||
return defaultAscii
|
||||
}
|
||||
return string(bytes)
|
||||
} else {
|
||||
return defaultAscii
|
||||
}
|
||||
}
|
||||
|
||||
func stripAnsii(str string) string {
|
||||
const ansi = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
|
||||
var re = regexp.MustCompile(ansi)
|
||||
return re.ReplaceAllString(str, "")
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user