package config import ( "encoding/base64" "fmt" "io/fs" "os" "path" "strings" "github.com/creasty/defaults" "gopkg.in/yaml.v3" ) var configPath string type _config struct { Username string `yaml:"username"` Password string `yaml:"password"` URL string `yaml:"url"` EnableScrobble bool `default:"false" yaml:"enableScrobble"` MaxRadioSongs int `default:"50" yaml:"maxRadioSongs"` ExperimentalRadioAlgo bool `default:"false" yaml:"experimentalRadioAlgo"` } var configStruct *_config func init() { userConfigDir, err := os.UserConfigDir() configDir := path.Join(userConfigDir, "subsonictui") configPath = path.Join(configDir, "config.yaml") if err != nil { fmt.Printf("[ERROR] Failed to fetch user config directory. %e\n", err) os.Exit(1) } if _, err := os.Stat(configDir); os.IsNotExist(err) { var permissions fs.FileMode = 0o700 err := os.MkdirAll(configDir, permissions) if err != nil { panic(err) } } var configFile *os.File if _, err := os.Stat(configPath); os.IsNotExist(err) { configFile, err = os.Create(configPath) defer func() { err := configFile.Close() if err != nil { panic(err) } }() if err != nil { fmt.Printf("[ERROR] Failed to create config file @ %s. %e\n", configPath, err) panic("unable to create config file") } } configStruct, err = loadConfig() if err != nil { fmt.Printf("[ERROR] Failed to load config file @ %s. %e\n", configPath, err) panic("unable to load config file") } fmt.Printf("Init Config %s\n", configPath) } func URL() string { return configStruct.URL } func Username() string { return configStruct.Username } func Password() string { p, _ := base64.StdEncoding.DecodeString(configStruct.Password) return strings.TrimSpace(string(p)) } func ScrobbleEnabled() bool { return configStruct.EnableScrobble } func MaxRadioSongs() int { return configStruct.MaxRadioSongs } func ExperimentalRadioAlgo() bool { return configStruct.ExperimentalRadioAlgo } func SetPassword(p string) { configStruct.Password = base64.StdEncoding.EncodeToString([]byte(p)) } func SetUsername(u string) { configStruct.Username = u } func SetURL(u string) { configStruct.URL = u } func loadConfig() (*_config, error) { c := &_config{} err := defaults.Set(c) if err != nil { panic(err) } file, err := os.ReadFile(configPath) if err != nil { return nil, err } if err = yaml.Unmarshal(file, c); err != nil { return nil, err } return c, nil } func SaveConfig() { yml, err := yaml.Marshal(configStruct) if err != nil { fmt.Printf("[ERROR] Failed to convert config to yaml. %e\n", err) os.Exit(1) } var permissions fs.FileMode = 0o600 err = os.WriteFile(configPath, yml, permissions) if err != nil { fmt.Printf("[ERROR] Failed to save config file @ %s. %e\n", configPath, err) os.Exit(1) } }