Big refactor to allow for multiple watchers, v2 configuration file with migration and new UI for configuration
This commit is contained in:
104
config/config.go
104
config/config.go
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
daulog "github.com/tardisx/discord-auto-upload/log"
|
||||
|
||||
@@ -21,62 +22,115 @@ type ConfigV1 struct {
|
||||
Exclude string
|
||||
}
|
||||
|
||||
type ConfigV2Watcher struct {
|
||||
type Watcher struct {
|
||||
WebHookURL string
|
||||
Path string
|
||||
Username string
|
||||
NoWatermark bool
|
||||
Exclude string
|
||||
Exclude []string
|
||||
}
|
||||
|
||||
type ConfigV2 struct {
|
||||
WatchInterval int
|
||||
Version int
|
||||
Watchers []ConfigV2Watcher
|
||||
Port int
|
||||
Watchers []Watcher
|
||||
}
|
||||
|
||||
var Config ConfigV2
|
||||
var configPath string
|
||||
type ConfigService struct {
|
||||
Config ConfigV2
|
||||
ConfigFilename string
|
||||
}
|
||||
|
||||
func Init() {
|
||||
configPath = defaultConfigPath()
|
||||
func DefaultConfigService() *ConfigService {
|
||||
c := ConfigService{
|
||||
ConfigFilename: defaultConfigPath(),
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
// LoadOrInit loads the current configuration from the config file, or creates
|
||||
// a new config file if none exists.
|
||||
func LoadOrInit() error {
|
||||
daulog.SendLog(fmt.Sprintf("Trying to load config from %s", configPath), daulog.LogTypeDebug)
|
||||
_, err := os.Stat(configPath)
|
||||
func (c *ConfigService) LoadOrInit() error {
|
||||
daulog.SendLog(fmt.Sprintf("Trying to load config from %s\n", c.ConfigFilename), daulog.LogTypeDebug)
|
||||
_, err := os.Stat(c.ConfigFilename)
|
||||
if os.IsNotExist(err) {
|
||||
daulog.SendLog("NOTE: No config file, writing out sample configuration", daulog.LogTypeInfo)
|
||||
daulog.SendLog("You need to set the configuration via the web interface", daulog.LogTypeInfo)
|
||||
Config.Version = 2
|
||||
Config.WatchInterval = 10
|
||||
return SaveConfig()
|
||||
c.Config = *DefaultConfig()
|
||||
return c.Save()
|
||||
} else {
|
||||
return LoadConfig()
|
||||
return c.Load()
|
||||
}
|
||||
}
|
||||
|
||||
// LoadConfig will load the configuration from a known-to-exist config file.
|
||||
func LoadConfig() error {
|
||||
data, err := ioutil.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot read config file %s: %s", configPath, err.Error())
|
||||
func DefaultConfig() *ConfigV2 {
|
||||
c := ConfigV2{}
|
||||
c.Version = 2
|
||||
c.WatchInterval = 10
|
||||
c.Port = 9090
|
||||
w := Watcher{
|
||||
WebHookURL: "abcedf",
|
||||
Path: "/Users/justin/tmp",
|
||||
Username: "",
|
||||
NoWatermark: false,
|
||||
Exclude: []string{},
|
||||
}
|
||||
err = json.Unmarshal([]byte(data), &Config)
|
||||
c.Watchers = []Watcher{w}
|
||||
return &c
|
||||
}
|
||||
|
||||
// Load will load the configuration from a known-to-exist config file.
|
||||
func (c *ConfigService) Load() error {
|
||||
fmt.Printf("Loading from %s\n\n", c.ConfigFilename)
|
||||
|
||||
data, err := ioutil.ReadFile(c.ConfigFilename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot decode config file %s: %s", configPath, err.Error())
|
||||
return fmt.Errorf("cannot read config file %s: %s", c.ConfigFilename, err.Error())
|
||||
}
|
||||
err = json.Unmarshal([]byte(data), &c.Config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot decode config file %s: %s", c.ConfigFilename, err.Error())
|
||||
}
|
||||
|
||||
fmt.Printf("Got config: %#v", c.Config)
|
||||
|
||||
// Version 0 predates config migrations
|
||||
if c.Config.Version == 0 {
|
||||
// need to migrate this
|
||||
daulog.SendLog("Migrating config to V2", daulog.LogTypeInfo)
|
||||
|
||||
configV1 := ConfigV1{}
|
||||
err = json.Unmarshal([]byte(data), &configV1)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot decode legacy config file as v1 %s: %s", c.ConfigFilename, err.Error())
|
||||
}
|
||||
|
||||
// copy stuff across
|
||||
c.Config.Version = 2
|
||||
c.Config.WatchInterval = configV1.Watch
|
||||
c.Config.Port = 9090 // this never used to be configurable
|
||||
|
||||
onlyWatcher := Watcher{
|
||||
WebHookURL: configV1.WebHookURL,
|
||||
Path: configV1.Path,
|
||||
Username: configV1.Username,
|
||||
NoWatermark: configV1.NoWatermark,
|
||||
Exclude: strings.Split(configV1.Exclude, " "),
|
||||
}
|
||||
|
||||
c.Config.Watchers = []Watcher{onlyWatcher}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SaveConfig() error {
|
||||
func (c *ConfigService) Save() error {
|
||||
daulog.SendLog("saving configuration", daulog.LogTypeInfo)
|
||||
jsonString, _ := json.Marshal(Config)
|
||||
err := ioutil.WriteFile(configPath, jsonString, os.ModePerm)
|
||||
jsonString, _ := json.Marshal(c.Config)
|
||||
err := ioutil.WriteFile(c.ConfigFilename, jsonString, os.ModePerm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot save config %s: %s", configPath, err.Error())
|
||||
return fmt.Errorf("cannot save config %s: %s", c.ConfigFilename, err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,39 +7,76 @@ import (
|
||||
)
|
||||
|
||||
func TestNoConfig(t *testing.T) {
|
||||
if Config.Version != 0 {
|
||||
t.Error("not 0 empty config")
|
||||
}
|
||||
c := ConfigService{}
|
||||
|
||||
configPath = emptyTempFile()
|
||||
os.Remove(configPath)
|
||||
c.ConfigFilename = emptyTempFile()
|
||||
os.Remove(c.ConfigFilename)
|
||||
defer os.Remove(c.ConfigFilename) // because we are about to create it
|
||||
|
||||
err := LoadOrInit()
|
||||
err := c.LoadOrInit()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected failure from load: %s", err)
|
||||
}
|
||||
|
||||
if Config.Version != 2 {
|
||||
if c.Config.Version != 2 {
|
||||
t.Error("not version 2 starting config")
|
||||
}
|
||||
|
||||
if fileSize(configPath) < 40 {
|
||||
t.Errorf("File is too small %d bytes", fileSize(configPath))
|
||||
if fileSize(c.ConfigFilename) < 40 {
|
||||
t.Errorf("File is too small %d bytes", fileSize(c.ConfigFilename))
|
||||
}
|
||||
|
||||
os.Remove(configPath)
|
||||
}
|
||||
|
||||
func TestEmptyFileConfig(t *testing.T) {
|
||||
c := ConfigService{}
|
||||
|
||||
configPath = emptyTempFile()
|
||||
c.ConfigFilename = emptyTempFile()
|
||||
defer os.Remove(c.ConfigFilename)
|
||||
|
||||
err := LoadOrInit()
|
||||
err := c.LoadOrInit()
|
||||
if err == nil {
|
||||
t.Error("unexpected success from LoadOrInit()")
|
||||
}
|
||||
|
||||
os.Remove(configPath)
|
||||
}
|
||||
|
||||
func TestMigrateFromV1toV2(t *testing.T) {
|
||||
c := ConfigService{}
|
||||
|
||||
c.ConfigFilename = v1Config()
|
||||
err := c.LoadOrInit()
|
||||
if err != nil {
|
||||
t.Error("unexpected error from LoadOrInit()")
|
||||
}
|
||||
if c.Config.Version != 2 {
|
||||
t.Errorf("Version %d not 2", c.Config.Version)
|
||||
}
|
||||
|
||||
if len(c.Config.Watchers) != 1 {
|
||||
t.Error("wrong amount of watchers")
|
||||
}
|
||||
|
||||
if c.Config.Watchers[0].Path != "/private/tmp" {
|
||||
t.Error("Wrong path")
|
||||
}
|
||||
if c.Config.WatchInterval != 69 {
|
||||
t.Error("Wrong watch interval")
|
||||
}
|
||||
if c.Config.Port != 9090 {
|
||||
t.Error("Wrong port")
|
||||
}
|
||||
}
|
||||
|
||||
func v1Config() string {
|
||||
f, err := ioutil.TempFile("", "dautest-*")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
config := `{"WebHookURL":"https://discord.com/api/webhooks/abc123","Path":"/private/tmp","Watch":69,"Username":"abcdedf","NoWatermark":true,"Exclude":"ab cd ef"}`
|
||||
f.Write([]byte(config))
|
||||
defer f.Close()
|
||||
return f.Name()
|
||||
}
|
||||
|
||||
func emptyTempFile() string {
|
||||
|
||||
Reference in New Issue
Block a user