252 lines
5.5 KiB
Go
252 lines
5.5 KiB
Go
package providers
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
var id, prettyName string
|
|
|
|
func GetDist() (string, string) {
|
|
f, _ := os.Open("/etc/os-release")
|
|
defer func(f *os.File) {
|
|
err := f.Close()
|
|
if err != nil {
|
|
fmt.Println("Error closing file:", err)
|
|
}
|
|
}(f)
|
|
s := bufio.NewScanner(f)
|
|
for s.Scan() {
|
|
t := s.Text()
|
|
if strings.HasPrefix(t, "ID=") {
|
|
id = strings.TrimPrefix(t, "ID=")
|
|
}
|
|
if strings.HasPrefix(t, "PRETTY_NAME=") {
|
|
prettyName = strings.TrimPrefix(t, "PRETTY_NAME=")
|
|
prettyName = strings.Trim(prettyName, "\"")
|
|
}
|
|
}
|
|
if id == "" && prettyName == "" {
|
|
return "unknown", "unknown"
|
|
}
|
|
return id, prettyName
|
|
}
|
|
|
|
func GetRam() string {
|
|
f, err := os.Open("/proc/meminfo")
|
|
if err != nil {
|
|
return "error"
|
|
}
|
|
|
|
var total, available int
|
|
s := bufio.NewScanner(f)
|
|
for s.Scan() {
|
|
line := s.Text()
|
|
if strings.HasPrefix(line, "MemTotal:") {
|
|
_, err2 := fmt.Sscanf(line, "MemTotal: %d kB", &total)
|
|
if err2 != nil {
|
|
return ""
|
|
}
|
|
}
|
|
if strings.HasPrefix(line, "MemAvailable:") {
|
|
_, err := fmt.Sscanf(line, "MemAvailable: %d kB", &available)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
}
|
|
}
|
|
totalMB := total / 1024
|
|
availableMB := available / 1024
|
|
usedMB := totalMB - availableMB
|
|
|
|
ram := fmt.Sprintf("%d / %d MiB", usedMB, totalMB)
|
|
ram = strings.TrimSpace(ram)
|
|
return ram
|
|
|
|
}
|
|
|
|
func GetCpu() string {
|
|
f, err := os.Open("/proc/cpuinfo")
|
|
if err != nil {
|
|
return "unknown"
|
|
}
|
|
|
|
var cpu string
|
|
s := bufio.NewScanner(f)
|
|
for s.Scan() {
|
|
line := s.Text()
|
|
if strings.HasPrefix(line, "model name") {
|
|
parts := strings.SplitN(line, ":", 2)
|
|
if len(parts) > 1 {
|
|
cpu := strings.TrimSpace(parts[1])
|
|
return cpu
|
|
}
|
|
}
|
|
}
|
|
|
|
return strings.TrimSpace(cpu)
|
|
}
|
|
|
|
func GetGpu() string {
|
|
out, err := exec.Command("sh", "-c", `lspci -mm | awk -F'"' '$2=="VGA compatible controller" || $2=="3D controller" || $2=="Display controller"'`).Output()
|
|
if err != nil || len(out) == 0 {
|
|
return "unknown GPU"
|
|
}
|
|
|
|
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
|
|
var gpus []string
|
|
|
|
for _, line := range lines {
|
|
re := regexp.MustCompile(`"([^"]+)"`)
|
|
matches := re.FindAllStringSubmatch(line, -1)
|
|
|
|
if len(matches) >= 3 {
|
|
vendor := matches[1][1]
|
|
device := matches[2][1]
|
|
|
|
cleaned := cleanGpuString(vendor + " " + device)
|
|
gpus = append(gpus, cleaned)
|
|
}
|
|
}
|
|
|
|
if len(gpus) > 0 {
|
|
return strings.Join(gpus, " / ")
|
|
}
|
|
return "GPU not found"
|
|
}
|
|
|
|
func cleanGpuString(raw string) string {
|
|
prettyNameRe := regexp.MustCompile(`\[(.*?)]`)
|
|
match := prettyNameRe.FindStringSubmatch(raw)
|
|
|
|
res := raw
|
|
if len(match) > 1 {
|
|
vendor := ""
|
|
if strings.Contains(strings.ToLower(raw), "nvidia") {
|
|
vendor = "NVIDIA "
|
|
}
|
|
if strings.Contains(strings.ToLower(raw), "intel") {
|
|
vendor = "Intel "
|
|
}
|
|
if strings.Contains(strings.ToLower(raw), "amd") {
|
|
vendor = "AMD "
|
|
}
|
|
|
|
res = vendor + match[1]
|
|
}
|
|
|
|
re := regexp.MustCompile(`\(.*?\)|\[.*?]`)
|
|
res = re.ReplaceAllString(res, "")
|
|
|
|
fluff := []string{"Corporation", "Controller", "VGA compatible", "3D", "Graphics", "Device"}
|
|
for _, word := range fluff {
|
|
res = strings.ReplaceAll(res, word, "")
|
|
}
|
|
|
|
return strings.Join(strings.Fields(res), " ")
|
|
}
|
|
|
|
func GetKernel() string {
|
|
out, err := os.ReadFile("/proc/version")
|
|
if err != nil {
|
|
return "unknown"
|
|
}
|
|
str := strings.TrimSpace(string(out))
|
|
str = strings.ReplaceAll(str, " version ", " ")
|
|
if idx := strings.Index(str, "("); idx != -1 {
|
|
str = str[:idx]
|
|
}
|
|
return strings.TrimSpace(str)
|
|
}
|
|
|
|
func GetHostname() string {
|
|
hostname, err := os.ReadFile("/etc/hostname")
|
|
if err != nil {
|
|
return "unknown"
|
|
}
|
|
username := os.Getenv("USER")
|
|
if username == "" {
|
|
username = os.Getenv("LOGNAME")
|
|
}
|
|
if username == "" {
|
|
return "unknown"
|
|
}
|
|
return fmt.Sprintf("%s@%s", username, strings.TrimSpace(string(hostname)))
|
|
}
|
|
|
|
func GetTerminal() string {
|
|
shellPID := os.Getppid()
|
|
out, err := exec.Command("ps", "-p", fmt.Sprint(shellPID), "-o", "ppid=").Output()
|
|
if err != nil {
|
|
return os.Getenv("TERM")
|
|
}
|
|
|
|
terminalPID := strings.TrimSpace(string(out))
|
|
nameOut, err := exec.Command("ps", "-p", terminalPID, "-o", "comm=").Output()
|
|
if err != nil {
|
|
return os.Getenv("TERM")
|
|
}
|
|
// those subprocess ARE NOT SLOWING DOWN THE FETCH MELVI, execution time is the same, you can check it
|
|
|
|
return strings.TrimSpace(string(nameOut))
|
|
}
|
|
|
|
func GetDE() string {
|
|
de := os.Getenv("XDG_CURRENT_DESKTOP")
|
|
if de == "" {
|
|
return "unknown or w/o GUI"
|
|
}
|
|
return strings.TrimSpace(de)
|
|
}
|
|
|
|
func GetUptime() string {
|
|
data, err := os.ReadFile("/proc/uptime")
|
|
if err != nil {
|
|
return "0"
|
|
}
|
|
uptimeStr := strings.Fields(string(data))[0]
|
|
seconds, err := strconv.ParseFloat(uptimeStr, 64)
|
|
if err != nil {
|
|
_, err := fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
if err != nil {
|
|
return "error printing uptime"
|
|
}
|
|
return ""
|
|
}
|
|
d := time.Duration(seconds) * time.Second
|
|
formatted := d.Round(time.Second).String()
|
|
spaced := strings.NewReplacer("h", "h ", "m", "m ", "s", "s ").Replace(formatted)
|
|
return spaced
|
|
}
|
|
|
|
func GetShell() string {
|
|
out, err := exec.Command("ps", "-p", strconv.Itoa(os.Getppid()), "-o", "comm=").Output()
|
|
if err != nil {
|
|
return path.Base(os.Getenv("SHELL"))
|
|
}
|
|
return strings.TrimSpace(string(out))
|
|
}
|
|
|
|
func GetAge() string {
|
|
out, err := exec.Command("stat", "-c", "%W", "/").Output()
|
|
if err != nil {
|
|
fmt.Printf("Error executing command: %v\n", err)
|
|
return "unknown"
|
|
}
|
|
birthTime := strings.TrimSpace(string(out))
|
|
if birthTime == "0" || birthTime == "-" {
|
|
return "unknown"
|
|
}
|
|
age, _ := strconv.Atoi(birthTime)
|
|
age = int(time.Now().Unix() - int64(age))
|
|
birth := age / 86400
|
|
return fmt.Sprintf("%d days", birth)
|
|
}
|