Add statusbar config

This commit is contained in:
dwrz
2026-10-26 22:26:21 +00:00
parent 22e6c5f676
commit b2a1b4fe2a
+159
View File
@@ -0,0 +1,159 @@
package config
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"time"
"code.chimeric.al/dwrz/statusbar/internal/statusbar"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/cpu"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/datetime"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/disk"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/eth"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/light"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/memory"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/mic"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/mlight"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/power"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/temp"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/volume"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/wlan"
"code.chimeric.al/dwrz/statusbar/internal/statusbar/wwan"
)
// Config corresponds to the top-level JSON object.
type Config struct {
Separator string `json:"separator"`
Timezone string `json:"timezone"`
Blocks []BlockConfig `json:"blocks"`
}
// BlockConfig holds the configuration for a single block.
type BlockConfig struct {
Datetime *datetime.Config `json:"datetime,omitempty"`
Disk *disk.Config `json:"disk,omitempty"`
Eth *eth.Config `json:"eth,omitempty"`
Name string `json:"name,omitempty"`
Power *power.Config `json:"power,omitempty"`
Temp *temp.Config `json:"temp,omitempty"`
WLAN *wlan.Config `json:"wlan,omitempty"`
WWAN *wwan.Config `json:"wwan,omitempty"`
}
// Load reads the config file and returns the Config and an instantiated slice
// of Blocks.
func Load() (*Config, []statusbar.Block, error) {
cfgDir, err := os.UserConfigDir()
if err != nil {
return nil, nil, fmt.Errorf(
"failed to get user config dir: %w", err,
)
}
cfgPath := filepath.Join(cfgDir, "statusbar", "config.json")
cfgBytes, err := os.ReadFile(cfgPath)
if err != nil {
return nil, nil, fmt.Errorf(
"failed to read config file %s: %w", cfgPath, err,
)
}
var cfg Config
if err := json.Unmarshal(cfgBytes, &cfg); err != nil {
return nil, nil, fmt.Errorf(
"failed to parse config json: %w", err,
)
}
var blocks = make([]statusbar.Block, 0, len(cfg.Blocks))
for _, bconf := range cfg.Blocks {
block, err := CreateBlock(bconf, &cfg)
if err != nil {
return nil, nil, fmt.Errorf(
"failed to instantiate block '%s': %w",
bconf.Name, err,
)
}
if block != nil {
blocks = append(blocks, block)
}
}
return &cfg, blocks, nil
}
// CreateBlock creates a single block based on its configuration.
func CreateBlock(bconf BlockConfig, cfg *Config) (statusbar.Block, error) {
switch bconf.Name {
case "cpu":
return cpu.New(), nil
case "datetime":
var conf datetime.Config
if bconf.Datetime != nil {
conf = *bconf.Datetime
}
if conf.Timezone == "" {
conf.Timezone = cfg.Timezone
}
if conf.Format == "" {
now := time.Now()
yearEnd := time.Date(
now.Year()+1, 1, 1, 0, 0, 0, 0, time.UTC,
).AddDate(0, 0, -1)
conf.Format = fmt.Sprintf(
"+%%Y-%%m-%%d %%u/7 %%W/52 %%j/%d %%H:%%M %%Z",
yearEnd.YearDay(),
)
}
return datetime.New(conf), nil
case "disk":
if bconf.Disk == nil || len(bconf.Disk.Mounts) == 0 {
return nil, fmt.Errorf("missing disk mounts")
}
return disk.New(bconf.Disk.Mounts...), nil
case "eth":
if bconf.Eth == nil || bconf.Eth.Iface == "" {
return nil, fmt.Errorf("missing eth interface")
}
return eth.New(bconf.Eth.Iface), nil
case "light":
return light.New(), nil
case "mlight":
return mlight.New(), nil
case "memory":
return memory.New(), nil
case "mic":
return mic.New(), nil
case "power":
var path = power.Path
if bconf.Power != nil && bconf.Power.Path != "" {
path = bconf.Power.Path
}
return power.New(path), nil
case "temp":
var tconf temp.Config
if bconf.Temp != nil {
tconf = *bconf.Temp
}
return temp.New(tconf), nil
case "volume":
return volume.New(), nil
case "wlan":
var iface = "wlan0"
if bconf.WLAN != nil && bconf.WLAN.Iface != "" {
iface = bconf.WLAN.Iface
}
return wlan.New(iface), nil
case "wwan":
if bconf.WWAN == nil || bconf.WWAN.Iface == "" {
return nil, fmt.Errorf("missing wwan interface")
}
return wwan.New(bconf.WWAN.Iface), nil
default:
return nil, fmt.Errorf("unknown block type")
}
}