mirror of
https://github.com/EnumeratedDev/stormfetch.git
synced 2026-09-15 23:46:12 +00:00
369 lines
10 KiB
Go
369 lines
10 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"reflect"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Used to declare modules in config files
|
|
type stormfetchModuleConfig struct {
|
|
Name string `yaml:"name"`
|
|
Format string `yaml:"format"`
|
|
Data map[string]any `yaml:"data"`
|
|
}
|
|
|
|
type StormfetchModule struct {
|
|
Execute func(StormfetchModule) string
|
|
stormfetchModuleConfig
|
|
}
|
|
|
|
var Modules map[string]StormfetchModule = make(map[string]StormfetchModule)
|
|
|
|
func (sm StormfetchModule) GetData(key string, defaultValue any) (any, bool) {
|
|
if sm.Data == nil {
|
|
return defaultValue, false
|
|
}
|
|
|
|
data, ok := sm.Data[key]
|
|
if !ok {
|
|
return defaultValue, false
|
|
}
|
|
|
|
if reflect.ValueOf(data).Kind() != reflect.ValueOf(defaultValue).Kind() {
|
|
return defaultValue, false
|
|
}
|
|
|
|
return data, true
|
|
}
|
|
|
|
func RegisterModule(module StormfetchModule) bool {
|
|
if _, ok := Modules[module.Name]; ok {
|
|
return false
|
|
}
|
|
|
|
Modules[module.Name] = module
|
|
return true
|
|
}
|
|
|
|
func initializeModuleMap() {
|
|
// Distribution Module
|
|
distributionModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "distribution", Format: "%3Distribution: %4$DISTRO_SHORT ($ARCH)"}, Execute: func(sm StormfetchModule) string {
|
|
distroInfo := GetDistroInfo()
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "DISTRO_ID":
|
|
return distroInfo.ID
|
|
case "DISTRO_SHORT":
|
|
return distroInfo.ShortName
|
|
case "DISTRO_LONG":
|
|
return distroInfo.LongName
|
|
case "ARCH":
|
|
return GetArch()
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(distributionModule)
|
|
|
|
// Hostname module
|
|
hostnameModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "hostname", Format: "%3Hostname: %4$HOSTNAME"}, Execute: func(sm StormfetchModule) string {
|
|
hostname, _ := os.Hostname()
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "HOSTNAME":
|
|
return hostname
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(hostnameModule)
|
|
|
|
// Kernel module
|
|
kernelModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "kernel", Format: "%3Kernel: %4$KERNEL_NAME $KERNEL_RELEASE"}, Execute: func(sm StormfetchModule) string {
|
|
kernelName, kernelRelease := GetKernel()
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "KERNEL_NAME":
|
|
return kernelName
|
|
case "KERNEL_RELEASE":
|
|
return kernelRelease
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(kernelModule)
|
|
|
|
// Packages module
|
|
packagesModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "packages", Format: "%3Packages: %4$PACKAGES"}, Execute: func(sm StormfetchModule) string {
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "PACKAGES":
|
|
return GetInstalledPackages()
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(packagesModule)
|
|
|
|
// Shell module
|
|
shellModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "shell", Format: "%3Shell: %4$SHELL"}, Execute: func(sm StormfetchModule) string {
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "SHELL":
|
|
return GetShell()
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(shellModule)
|
|
|
|
// Init system module
|
|
initSystemModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "init_system", Format: "%3Init: %4$INIT"}, Execute: func(sm StormfetchModule) string {
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "INIT":
|
|
return GetInitSystem()
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(initSystemModule)
|
|
|
|
// Libc module
|
|
libcModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "libc", Format: "%3Libc: %4$LIBC"}, Execute: func(sm StormfetchModule) string {
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "LIBC":
|
|
return GetLibc()
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(libcModule)
|
|
|
|
// Motherboard module
|
|
MotherboardModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "motherboard", Format: "%3Motherboard: %4$MOTHERBOARD"}, Execute: func(sm StormfetchModule) string {
|
|
motherboard := GetMotherboardModel()
|
|
|
|
// Return empty string if can't detect motherboard model
|
|
if motherboard == "" {
|
|
return ""
|
|
}
|
|
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "MOTHERBOARD":
|
|
return motherboard
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(MotherboardModule)
|
|
|
|
// Motherboard module
|
|
cpuModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "cpu", Format: "%3CPU: %4$CPU_MODEL ($CPU_THREADS threads)"}, Execute: func(sm StormfetchModule) string {
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "CPU_MODEL":
|
|
return GetCPUModel()
|
|
case "CPU_THREADS":
|
|
return strconv.Itoa(GetCPUThreads())
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(cpuModule)
|
|
|
|
// GPUs module
|
|
gpusModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "gpus", Format: "%3GPU: %4$GPU_MODEL"}, Execute: func(sm StormfetchModule) string {
|
|
hiddenGPUsInterface, _ := sm.GetData("hidden_gpus", make([]any, 0))
|
|
|
|
// Convert interface slices to string slices
|
|
hiddenGPUs := make([]int, 0)
|
|
for _, value := range hiddenGPUsInterface.([]any) {
|
|
hiddenGPUs = append(hiddenGPUs, value.(int))
|
|
}
|
|
|
|
builder := strings.Builder{}
|
|
gpus := GetGPUModels(hiddenGPUs)
|
|
|
|
for i, gpu := range gpus {
|
|
expanded := os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "GPU_NUM":
|
|
return strconv.Itoa(i + 1)
|
|
case "GPU_MODEL":
|
|
return gpu
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
|
|
builder.WriteString(expanded + "\n")
|
|
}
|
|
|
|
return builder.String()
|
|
}}
|
|
RegisterModule(gpusModule)
|
|
|
|
// Memory module
|
|
memoryModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "memory", Format: "%3Memory: %4$MEM_USED MiB / $MEM_TOTAL MiB"}, Execute: func(sm StormfetchModule) string {
|
|
memoryInfo := GetMemoryInfo()
|
|
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "MEM_TOTAL":
|
|
return strconv.Itoa(memoryInfo.MemTotal)
|
|
case "MEM_AVAILABLE":
|
|
return strconv.Itoa(memoryInfo.MemAvailable)
|
|
case "MEM_FREE":
|
|
return strconv.Itoa(memoryInfo.MemFree)
|
|
case "MEM_USED":
|
|
return strconv.Itoa(memoryInfo.MemTotal - memoryInfo.MemAvailable)
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(memoryModule)
|
|
|
|
// Partitions module
|
|
partitionsModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "partitions", Format: "%3Partition $PART_AUTONAME: %4$PART_USED / $PART_TOTAL"}, Execute: func(sm StormfetchModule) string {
|
|
hiddenPartitionsInterface, _ := sm.GetData("hidden_partitions", make([]any, 0))
|
|
hiddenFilesystemsInterface, _ := sm.GetData("hidden_filesystems", make([]any, 0))
|
|
|
|
// Convert interface slices to string slices
|
|
hiddenPartitions := make([]string, 0)
|
|
for _, value := range hiddenPartitionsInterface.([]any) {
|
|
hiddenPartitions = append(hiddenPartitions, value.(string))
|
|
}
|
|
hiddenFilesystems := make([]string, 0)
|
|
for _, value := range hiddenFilesystemsInterface.([]any) {
|
|
hiddenFilesystems = append(hiddenFilesystems, value.(string))
|
|
}
|
|
|
|
builder := strings.Builder{}
|
|
partitions := GetMountedPartitions(hiddenPartitions, hiddenFilesystems)
|
|
|
|
for i, partition := range partitions {
|
|
partitionAutoname := partition.Label
|
|
if partitionAutoname == "" {
|
|
partitionAutoname = partition.MountPoint
|
|
}
|
|
|
|
expanded := os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "PART_NUM":
|
|
return strconv.Itoa(i + 1)
|
|
case "PART_FS":
|
|
return partition.FileystemType
|
|
case "PART_DEVICE":
|
|
return partition.Device
|
|
case "PART_AUTONAME":
|
|
return partitionAutoname
|
|
case "PART_LABEL":
|
|
return partition.Label
|
|
case "PART_MOUNTPOINT":
|
|
return partition.MountPoint
|
|
case "PART_FREE":
|
|
return FormatBytes(partition.FreeSize)
|
|
case "PART_USED":
|
|
return FormatBytes(partition.UsedSize)
|
|
case "PART_TOTAL":
|
|
return FormatBytes(partition.TotalSize)
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
|
|
builder.WriteString(expanded + "\n")
|
|
}
|
|
|
|
return builder.String()
|
|
}}
|
|
RegisterModule(partitionsModule)
|
|
|
|
// Local IP module
|
|
localIpModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "local_ip", Format: "%3Local IP: %4$LOCAL_IP"}, Execute: func(sm StormfetchModule) string {
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "LOCAL_IP":
|
|
return GetLocalIP()
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(localIpModule)
|
|
|
|
// DEWM module
|
|
dewmModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "de_wm", Format: "%3${DEWM_TYPE}: %4${DEWM_NAME} ${DEWM_VERSION} ($DISPLAY_PROTOCOL)"}, Execute: func(sm StormfetchModule) string {
|
|
// Return empty string if currently in TTY
|
|
if os.Getenv("XDG_SESSION_TYPE") == "" || os.Getenv("XDG_SESSION_TYPE") == "tty" {
|
|
return ""
|
|
}
|
|
|
|
dewm := GetDEWM()
|
|
|
|
// Return empty string if can't detect DE/WM
|
|
if dewm.Name == "Unknown" {
|
|
return ""
|
|
}
|
|
|
|
return os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "DEWM_NAME":
|
|
return dewm.Name
|
|
case "DEWM_TYPE":
|
|
return dewm.Type
|
|
case "DEWM_VERSION":
|
|
return dewm.Version
|
|
case "DISPLAY_PROTOCOL":
|
|
return GetDisplayProtocol()
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
}}
|
|
RegisterModule(dewmModule)
|
|
|
|
// Monitors module
|
|
monitorsModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "monitors", Format: "%3Monitor: %4${MONITOR_WIDTH}x${MONITOR_HEIGHT} ${MONITOR_REFRESH_RATE}Hz"}, Execute: func(sm StormfetchModule) string {
|
|
builder := strings.Builder{}
|
|
monitors := GetMonitors()
|
|
|
|
for i, monitor := range monitors {
|
|
expanded := os.Expand(sm.Format, func(s string) string {
|
|
switch s {
|
|
case "MONITOR_NUM":
|
|
return strconv.Itoa(i + 1)
|
|
case "MONITOR_WIDTH":
|
|
return strconv.Itoa(monitor.Width)
|
|
case "MONITOR_HEIGHT":
|
|
return strconv.Itoa(monitor.Height)
|
|
case "MONITOR_REFRESH_RATE":
|
|
return strconv.Itoa(monitor.RefreshRate)
|
|
default:
|
|
return ""
|
|
}
|
|
})
|
|
|
|
builder.WriteString(expanded + "\n")
|
|
}
|
|
|
|
return builder.String()
|
|
}}
|
|
RegisterModule(monitorsModule)
|
|
}
|