config.go (3858B)
1 package config 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 "path/filepath" 8 "time" 9 10 "code.dwrz.net/src/pkg/statusbar" 11 "code.dwrz.net/src/pkg/statusbar/cpu" 12 "code.dwrz.net/src/pkg/statusbar/datetime" 13 "code.dwrz.net/src/pkg/statusbar/disk" 14 "code.dwrz.net/src/pkg/statusbar/eth" 15 "code.dwrz.net/src/pkg/statusbar/light" 16 "code.dwrz.net/src/pkg/statusbar/memory" 17 "code.dwrz.net/src/pkg/statusbar/mic" 18 "code.dwrz.net/src/pkg/statusbar/power" 19 "code.dwrz.net/src/pkg/statusbar/temp" 20 "code.dwrz.net/src/pkg/statusbar/volume" 21 "code.dwrz.net/src/pkg/statusbar/wlan" 22 "code.dwrz.net/src/pkg/statusbar/wwan" 23 ) 24 25 // Config corresponds to the top-level JSON object. 26 type Config struct { 27 Separator string `json:"separator"` 28 Timezone string `json:"timezone"` 29 Blocks []BlockConfig `json:"blocks"` 30 } 31 32 // BlockConfig holds the configuration for a single block. 33 // Params are kept as raw JSON to be parsed into a specific struct later. 34 type BlockConfig struct { 35 Datetime *datetime.Config `json:"datetime,omitempty"` 36 Disk *disk.Config `json:"disk,omitempty"` 37 Eth *eth.Config `json:"eth,omitempty"` 38 Name string `json:"name,omitempty"` 39 Power *power.Config `json:"power,omitempty"` 40 Temp *temp.Config `json:"temp,omitempty"` 41 WLAN *wlan.Config `json:"wlan,omitempty"` 42 WWAN *wwan.Config `json:"wwan,omitempty"` 43 } 44 45 // Load reads the config file and returns the Config and an instantiated slice 46 // of Blocks. 47 func Load() (*Config, []statusbar.Block, error) { 48 configDir, err := os.UserConfigDir() 49 if err != nil { 50 return nil, nil, fmt.Errorf( 51 "failed to get user config dir: %v", err, 52 ) 53 } 54 confPath := filepath.Join(configDir, "statusbar", "config.json") 55 confBytes, err := os.ReadFile(confPath) 56 if err != nil { 57 return nil, nil, fmt.Errorf( 58 "failed to read config file %s: %v", confPath, err, 59 ) 60 } 61 62 var cfg Config 63 if err := json.Unmarshal(confBytes, &cfg); err != nil { 64 return nil, nil, fmt.Errorf( 65 "failed to parse config json: %v", err, 66 ) 67 } 68 69 var blocks = make([]statusbar.Block, 0, len(cfg.Blocks)) 70 for _, bconf := range cfg.Blocks { 71 block, err := CreateBlock(bconf, &cfg) 72 if err != nil { 73 return nil, nil, fmt.Errorf( 74 "failed to instantiate block '%s': %v", 75 bconf.Name, err, 76 ) 77 } 78 if block != nil { 79 blocks = append(blocks, block) 80 } 81 } 82 83 return &cfg, blocks, nil 84 } 85 86 // CreateBlock creates a single block based on its configuration. 87 func CreateBlock(bconf BlockConfig, cfg *Config) (statusbar.Block, error) { 88 switch bconf.Name { 89 case "cpu": 90 return cpu.New(), nil 91 case "datetime": 92 var conf datetime.Config 93 if bconf.Datetime != nil { 94 conf = *bconf.Datetime 95 } 96 97 if conf.Timezone == "" { 98 conf.Timezone = cfg.Timezone 99 } 100 101 if conf.Format == "" { 102 now := time.Now() 103 yearEnd := time.Date( 104 now.Year()+1, 1, 1, 0, 0, 0, 0, time.UTC, 105 ).AddDate(0, 0, -1) 106 conf.Format = fmt.Sprintf( 107 "+%%Y-%%m-%%d %%u/7 %%W/52 %%j/%d %%H:%%M %%Z", 108 yearEnd.YearDay(), 109 ) 110 } 111 return datetime.New(conf), nil 112 case "disk": 113 return disk.New(bconf.Disk.Mounts...), nil 114 case "eth": 115 return eth.New(bconf.Eth.Iface), nil 116 case "light": 117 return light.New(), nil 118 case "memory": 119 return memory.New(), nil 120 case "mic": 121 return mic.New(), nil 122 case "power": 123 var path = power.Path 124 if bconf.Power != nil && bconf.Power.Path != "" { 125 path = bconf.Power.Path 126 } 127 return power.New(path), nil 128 case "temp": 129 var tconf temp.Config 130 if bconf.Temp != nil { 131 tconf = *bconf.Temp 132 } 133 return temp.New(tconf), nil 134 case "volume": 135 return volume.New(), nil 136 case "wlan": 137 var iface = "wlan0" 138 if bconf.WLAN != nil && bconf.WLAN.Iface != "" { 139 iface = bconf.WLAN.Iface 140 } 141 return wlan.New(iface), nil 142 case "wwan": 143 return wwan.New(bconf.WWAN.Iface), nil 144 145 default: 146 return nil, fmt.Errorf("unknown block type") 147 } 148 }