package config import ( "errors" "github.com/BurntSushi/toml" "strconv" ) const MaxBufferSize = 10 type Config struct { Api struct { Host string `toml:"host"` Port int `toml:"port"` } `toml:"api"` Queue struct { RandomSongApi string `toml:"random_song_api"` SongFetchUrl string `toml:"song_fetch_url"` NowPlaying string `toml:"np"` NowRandom string `toml:"nr"` FallbackPath string `toml:"fallback"` BufferLengthInKiB int `toml:"buffer_len"` BufferSeconds int `toml:"buffer_size"` ReplayGain bool `toml:"replaygain"` Length int `toml:"length"` SampleRate int `toml:"samplerate"` SampleFormat string `toml:"sampleformat"` BitDepth int `toml:"bitdepth"` } `toml:"queue"` Radio struct { Host string `toml:"host"` Port int `toml:"port"` Name string `toml:"name"` Description string `toml:"description"` URL string `toml:"url"` Logo string `toml:"logo"` Private bool `toml:"private"` } `toml:"radio"` Streams []*StreamConfig `toml:"streams"` } type StreamConfig struct { MountPath string Container string Codec string Options map[string]interface{} } func (s *StreamConfig) GetIntOption(name string, defaultValue int) int { if v, ok := s.Options[name].(int); ok { return v } if v, ok := s.Options[name].(int64); ok { return int(v) } if v, ok := s.Options[name].(string); ok { if val, err := strconv.Atoi(v); err == nil { return val } } return defaultValue } func (s *StreamConfig) GetStringOption(name string, defaultValue string) string { if v, ok := s.Options[name].(string); ok { return v } if v, ok := s.Options[name].(int); ok { return strconv.Itoa(v) } if v, ok := s.Options[name].(int64); ok { return strconv.Itoa(int(v)) } return defaultValue } func (s *StreamConfig) GetBoolOption(name string, defaultValue bool) bool { if v, ok := s.Options[name].(bool); ok { return v } if v, ok := s.Options[name].(string); ok { return v == "true" } return defaultValue } func (s *StreamConfig) GetOption(name string, defaultValue interface{}) interface{} { if v, ok := s.Options[name]; ok { return v } return defaultValue } func (s *StreamConfig) UnmarshalTOML(value interface{}) error { if v, ok := value.(map[string]interface{}); ok { if mount, ok := v["mount"].(string); ok { s.MountPath = mount } else { return errors.New("could not find mount path") } if container, ok := v["container"].(string); ok { s.Container = container } if codec, ok := v["codec"].(string); ok { s.Codec = codec } s.Options = make(map[string]interface{}) for k, val := range v { if k == "mount" || k == "container" || k == "codec" { continue } s.Options[k] = val } return nil } return errors.New("could not decode") } func GetConfig(pathName string) (*Config, error) { config := &Config{} if _, err := toml.DecodeFile(pathName, config); err != nil { return nil, err } return config, nil }