src

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

config.go (3943B)


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