src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

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 }