This commit is contained in:
2026-02-27 21:20:08 -07:00
commit 2f35c9dd34
12 changed files with 203 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
bin/

5
Makefile Normal file
View File

@@ -0,0 +1,5 @@
build:
go build -o bin/gobar ./cmd/gobar
test:
go test ./...

2
README.md Normal file
View File

@@ -0,0 +1,2 @@
# gobar
A shitty program to update dwlb and other dwm/dwl status bars by writing to a file or stdout. While not as extensible as something like someblocks, this program aims to be easy to run as a userspace daemon. It's extremely lightweight and extensible.

26
cmd/gobar/main.go Normal file
View File

@@ -0,0 +1,26 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
"git.jthan.io/jonathan/gobar/internal/config"
"git.jthan.io/jonathan/gobar/internal/daemon"
)
func main() {
ctx, stop := signal.NotifyContext(
context.Background(),
os.Interrupt,
syscall.SIGTERM,
)
defer stop()
cfg := config.Default()
if err := daemon.Run(ctx, cfg); err != nil {
os.Exit(1)
}
}

3
go.mod Normal file
View File

@@ -0,0 +1,3 @@
module git.jthan.io/jonathan/gobar
go 1.25.0

View File

@@ -0,0 +1 @@
package collectors

View File

@@ -0,0 +1,33 @@
package collectors
type StatusInfo struct {
CPULoad1 float32
CPULoad5 float32
CPULoad15 float32
Year int
Month int
Day int
Hour int
Minute int
Second int
BatteryPercent int
BatteryStatus string
}
func Collect() (*StatusInfo, error) {
year, month, day, hour, minute, second := datetime()
cpuLoad1, cpuLoad5, cpuLoad15 := cpuLoad()
return &StatusInfo{
CPULoad1: cpuLoad1,
CPULoad5: cpuLoad5,
CPULoad15: cpuLoad15,
Year: year,
Month: int(month),
Day: day,
Hour: hour,
Minute: minute,
Second: second,
BatteryPercent: 100,
BatteryStatus: "Charging",
}, nil
}

View File

@@ -0,0 +1,45 @@
package collectors
import (
"bufio"
"log"
"os"
"strconv"
"strings"
)
func strToFloat32(input string) (float32) {
f64, err := strconv.ParseFloat(input, 32)
if err != nil {
log.Fatal(err)
}
f32 := float32(f64)
return f32
}
func cpuLoad() (load1, load5, load15 float32) {
const filePath string = "/proc/loadavg"
var firstLine string
file, err := os.Open(filePath)
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
if scanner.Scan() {
firstLine = scanner.Text()
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
loadAverages := strings.Fields(firstLine)
load1 = strToFloat32(loadAverages[0])
load5 = strToFloat32(loadAverages[1])
load15 = strToFloat32(loadAverages[2])
return load1, load5, load15
}

View File

@@ -0,0 +1,12 @@
package collectors
import (
"time"
)
func datetime() (year int, month time.Month, day, hour, minute, second int){
currentTime := time.Now()
year, month, day = currentTime.Date()
hour, minute, second = currentTime.Clock()
return year, month, day, hour, minute, second
}

15
internal/config/config.go Normal file
View File

@@ -0,0 +1,15 @@
package config
import (
"time"
)
type Config struct {
Interval time.Duration
}
func Default() Config {
return Config{
Interval: 30 * time.Second,
}
}

40
internal/daemon/daemon.go Normal file
View File

@@ -0,0 +1,40 @@
package daemon
import (
"context"
"log"
"time"
"git.jthan.io/jonathan/gobar/internal/config"
"git.jthan.io/jonathan/gobar/internal/collectors"
"git.jthan.io/jonathan/gobar/internal/output"
)
func Run(ctx context.Context, cfg config.Config) error {
ticker := time.NewTicker(cfg.Interval)
defer ticker.Stop()
log.Printf("daemon started (interval=%s)", cfg.Interval)
for {
select {
case <-ctx.Done():
log.Println("daemon shutting down")
return nil
case <-ticker.C:
runOnce(ctx)
}
}
}
func runOnce(ctx context.Context) {
m, err := collectors.Collect()
if err != nil {
log.Println("collect error:", err)
return
}
output.Print(m)
}

20
internal/output/stdout.go Normal file
View File

@@ -0,0 +1,20 @@
package output
import (
"fmt"
"git.jthan.io/jonathan/gobar/internal/collectors"
)
func Print(c *collectors.StatusInfo) {
fmt.Printf(
"LOAD: %.2f %.2f %.2f | %d-%d-%d %d:%d\n",
c.CPULoad1,
c.CPULoad5,
c.CPULoad15,
c.Year,
c.Month,
c.Day,
c.Hour,
c.Minute,
)
}