128 lines
2.7 KiB
Go
128 lines
2.7 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/pelletier/go-toml"
|
|
)
|
|
|
|
var ErrNotFound = errors.New("no config file found")
|
|
|
|
type Config struct {
|
|
RTMPListenAddr string `toml:"RTMPListenAddr"`
|
|
HTTPServerEnable bool `toml:"HTTPServerEnable"`
|
|
HTTPListenAddr string `toml:"HTTPListenAddr"`
|
|
HTTPAccessLogEnable bool `toml:"HTTPAccessLogEnable"`
|
|
LogLevel string `toml:"LogLevel"`
|
|
}
|
|
|
|
type InvalidValueError struct {
|
|
Key string
|
|
}
|
|
|
|
func (ive *InvalidValueError) Error() string {
|
|
return fmt.Sprintf("invalid value: config key %s has invalid value", ive.Key)
|
|
}
|
|
|
|
func FromReader(r io.Reader) (*Config, error) {
|
|
var c Config
|
|
// Set some defaults
|
|
c.RTMPListenAddr = ":5566"
|
|
c.HTTPServerEnable = false
|
|
c.HTTPListenAddr = ":8077"
|
|
c.LogLevel = "INFO"
|
|
|
|
decoder := toml.NewDecoder(r)
|
|
if err := decoder.Decode(&c); err != nil {
|
|
return nil, fmt.Errorf("error parsing config file: %w", err)
|
|
}
|
|
|
|
return &c, c.Verify()
|
|
}
|
|
|
|
func (c *Config) Verify() error {
|
|
// Check that LogLevel is valid
|
|
switch c.LogLevel {
|
|
case "DEBUG", "INFO", "WARN", "ERROR":
|
|
default:
|
|
return &InvalidValueError{Key: "LogLevel"}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Config) UpdateFromEnv() error {
|
|
if loglevel, found := os.LookupEnv("DOGTAMER_LOGLEVEL"); found {
|
|
c.LogLevel = loglevel
|
|
}
|
|
|
|
if listenAddr, found := os.LookupEnv("DOGTAMER_RTMPLISTENADDR"); found {
|
|
c.RTMPListenAddr = listenAddr
|
|
}
|
|
|
|
if httpEnable, found := os.LookupEnv("DOGTAMER_HTTPSERVERENABLE"); found {
|
|
switch strings.ToUpper(httpEnable) {
|
|
case "TRUE", "YES", "ENABLE":
|
|
c.HTTPServerEnable = true
|
|
}
|
|
}
|
|
|
|
if httpListenAddr, found := os.LookupEnv("DOGTAMER_HTTPLISTENADDR"); found {
|
|
c.HTTPListenAddr = httpListenAddr
|
|
}
|
|
|
|
if httpAccessLogEnable, found := os.LookupEnv("DOGTAMER_HTTPACCESSLOGENABLE"); found {
|
|
switch strings.ToUpper(httpAccessLogEnable) {
|
|
case "TRUE", "YES", "ENABLE":
|
|
c.HTTPAccessLogEnable = true
|
|
}
|
|
}
|
|
|
|
return c.Verify()
|
|
}
|
|
|
|
func FromFile(path string) (*Config, error) {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Error opening config file: %w", err)
|
|
}
|
|
|
|
return FromReader(f)
|
|
}
|
|
|
|
func FromDefaultLocations() (*Config, error) {
|
|
defaultLocations := []string{
|
|
"dogtamer.toml",
|
|
"/etc/dogtamer.toml",
|
|
}
|
|
baseConfigDir, err := os.UserConfigDir()
|
|
if err == nil {
|
|
userConfigFile := filepath.Join(baseConfigDir, "dogtamer", "dogtamer.toml")
|
|
defaultLocations = append(defaultLocations, userConfigFile)
|
|
}
|
|
|
|
for _, fname := range defaultLocations {
|
|
if _, err := os.Stat(fname); os.IsNotExist(err) {
|
|
continue
|
|
}
|
|
|
|
cfg, err := FromFile(fname)
|
|
if err != nil {
|
|
continue
|
|
|
|
}
|
|
|
|
return cfg, cfg.UpdateFromEnv()
|
|
}
|
|
|
|
cfg, err := FromReader(strings.NewReader(""))
|
|
if err == nil {
|
|
return cfg, ErrNotFound
|
|
}
|
|
return nil, ErrNotFound
|
|
}
|