From a85052a41a477aea7c04f06db6a6ec9bfaf6279e Mon Sep 17 00:00:00 2001 From: Martyn Ranyard Date: Sat, 15 Feb 2020 12:56:17 +0100 Subject: [PATCH] Less hard-coding, more "database" Signed-off-by: Martyn Ranyard --- configs/config.json | 3 + main.go | 165 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 142 insertions(+), 26 deletions(-) create mode 100755 configs/config.json diff --git a/configs/config.json b/configs/config.json new file mode 100755 index 0000000..a248a48 --- /dev/null +++ b/configs/config.json @@ -0,0 +1,3 @@ +{ + "channels": ["iMartynOnTwitch"] +} \ No newline at end of file diff --git a/main.go b/main.go index 4db57ae..bc47778 100755 --- a/main.go +++ b/main.go @@ -2,7 +2,6 @@ package main import ( "encoding/json" - "fmt" "io/ioutil" "math/rand" "os" @@ -13,8 +12,16 @@ import ( irc "git.martyn.berlin/martyn/karaokards/internal/irc" webserver "git.martyn.berlin/martyn/karaokards/internal/webserver" rgb "github.com/foresthoffman/rgblog" + scribble "github.com/nanobox-io/golang-scribble" ) +type configStruct struct { + InitialChannels []string `json:"channels"` + OAuthPath string `json:"oauthpath,omitempty"` + StringPath string `json:"authpath,omitempty"` + DataPath string `json:"datapath,omitempty"` +} + type customStringsStruct struct { Strings []string `json:"strings,omitempty"` } @@ -23,30 +30,125 @@ var selectablePrompts []string var customStrings customStringsStruct -func readBonusStrings() []string { +var config configStruct - ex, err := os.Executable() - if err != nil { - fmt.Println("Could not read `strings.json`, will only have builtin prompts. File reading error", err) - return []string{} +func readConfig() { + var data []byte + var err error + configFile := "" + if os.Getenv("KARAOKARDS_CONFIGFILE") != "" { + if _, err := os.Stat(os.Getenv("KARAOKARDS_CONFIGFILE")); os.IsNotExist(err) { + rgb.RPrintf("[%s] Error, KARAOKARDS_CONFIGFILE env var set and '%s' doesn't exist!\n", irc.TimeStamp(), os.Getenv("KARAOKARDS_CONFIGFILE")) + os.Exit(1) + } + configFile = os.Getenv("KARAOKARDS_CONFIGFILE") + } else { + ex, err := os.Executable() + if err != nil { + rgb.YPrintf("[%s] Warning, KARAOKARDS_CONFIGFILE env var unset and cannot find executable!\n", irc.TimeStamp()) + } + exPath := filepath.Dir(ex) + if _, err := os.Stat(exPath + "/config.json"); os.IsNotExist(err) { + rgb.YPrintf("[%s] Warning, KARAOKARDS_CONFIGFILE env var unset and `config.json` not alongside executable!\n", irc.TimeStamp()) + if _, err := os.Stat("/etc/karaokards/config.json"); os.IsNotExist(err) { + rgb.RPrintf("[%s] Error, KARAOKARDS_CONFIGFILE env var unset and neither '%s' nor '%s' exist!\n", irc.TimeStamp(), exPath + "/config.json", "/etc/karaokards/config.json") + os.Exit(1) + } else { + configFile = "/etc/karaokards/config.json" + } + } else { + configFile = exPath + "/config.json" + } } - exPath := filepath.Dir(ex) - data, err := ioutil.ReadFile(exPath + "/strings.json") + data, err = ioutil.ReadFile(configFile) if err != nil { - fmt.Println("Could not read `strings.json`, will only have builtin prompts. File reading error", err) - return []string{} + rgb.RPrintf("[%s] Could not read `%s`. File reading error: %s\n", irc.TimeStamp(), configFile, err) + os.Exit(1) } err = json.Unmarshal(data, &customStrings) if err != nil { - fmt.Println("Could not unmarshal `strings.json`, will only have builtin prompts. Unmarshal error", err) + rgb.RPrintf("[%s] Could not unmarshal `%s`. Unmarshal error: %s\n", irc.TimeStamp(), configFile, err) + os.Exit(1) + } + rgb.YPrintf("[%s] Read config file from `%s\n`", irc.TimeStamp(), configFile) + return +} + +//openDatabase "database" in this sense being a scribble db +func openDatabase() *scribble.Driver { + dataPath := "" + if config.DataPath == "" { + if os.Getenv("KARAOKARDS_DATA_FOLDER") != "" { + if _, err := os.Stat(os.Getenv("KARAOKARDS_DATA_FOLDER")); os.IsNotExist(err) { + rgb.RPrintf("[%s] Error, KARAOKARDS_DATA_FOLDER env var set and '%s' doesn't exist!\n", irc.TimeStamp(), os.Getenv("KARAOKARDS_DATA_FOLDER")) + os.Exit(1) + } + dataPath = os.Getenv("KARAOKARDS_DATA_FOLDER") + } else { + ex, err := os.Executable() + if err != nil { + rgb.RPrintf("[%s] Error, KARAOKARDS_DATA_FOLDER env var unset and cannot find executable!\n", irc.TimeStamp()) + os.Exit(1) + } + exPath := filepath.Dir(ex) + if _, err := os.Stat(exPath + "/data"); os.IsNotExist(err) { + rgb.YPrintf("[%s] Warning %s doesn't exist, trying to create it.\n", irc.TimeStamp(), exPath + "/data") + err = os.Mkdir(exPath + "/data", 0770) + if err != nil { + rgb.RPrintf("[%s] Error cannot create %s: %s!\n", irc.TimeStamp(), exPath + "/data", err) + os.Exit(1) + } + } + dataPath = exPath + "/data" + } + } else { + if _, err := os.Stat(config.OAuthPath); os.IsNotExist(err) { + rgb.RPrintf("[%s] Error, config-specified path '%s' doesn't exist!\n", irc.TimeStamp(), os.Getenv("KARAOKARDS_DATA_FOLDER")) + os.Exit(1) + } + dataPath = config.DataPath + } + db, err := scribble.New(dataPath, nil) + if err != nil { + rgb.RPrintf("[%s] Error opening database in '%s' : %s\n", irc.TimeStamp(), dataPath, err) + os.Exit(1) + } + return db +} + +func readBonusStrings() []string { + var data []byte + var err error + if config.StringPath == "" { + ex, err := os.Executable() + if err != nil { + rgb.YPrintf("[%s] Could not read `strings.json`, will only have builtin prompts. File reading error: %s\n", irc.TimeStamp(), err) + return []string{} + } + exPath := filepath.Dir(ex) + data, err = ioutil.ReadFile(exPath + "/strings.json") + if err != nil { + rgb.YPrintf("[%s] Could not read `strings.json`, will only have builtin prompts. File reading error: %s\n", irc.TimeStamp(), err) + return []string{} + } + } else { + data, err = ioutil.ReadFile(config.StringPath) + if err != nil { + rgb.YPrintf("[%s] Could not read `strings.json`, will only have builtin prompts. File reading error: %s\n", irc.TimeStamp(), err) + return []string{} + } + } + err = json.Unmarshal(data, &customStrings) + if err != nil { + rgb.YPrintf("[%s] Could not unmarshal `strings.json`, will only have builtin prompts. Unmarshal error: %s\n", irc.TimeStamp(), err) return []string{} } - fmt.Println("Read ", len(customStrings.Strings), " prompts from `strings.json`") + rgb.YPrintf("[%s] Read %d prompts from `strings.json`\n", irc.TimeStamp(), len(customStrings.Strings)) return customStrings.Strings } func main() { - + readConfig() rand.Seed(time.Now().UnixNano()) for _, val := range builtins.Karaokards { selectablePrompts = append(selectablePrompts, val) @@ -54,25 +156,36 @@ func main() { for _, val := range readBonusStrings() { selectablePrompts = append(selectablePrompts, val) } - fmt.Println(len(selectablePrompts), " prompts available.") + rgb.YPrintf("[%s] %d prompts available.\n", irc.TimeStamp(), len(selectablePrompts)) oauthPath := "" - if os.Getenv("TWITCH_OAUTH_JSON") != "" { - if _, err := os.Stat(os.Getenv("TWITCH_OAUTH_JSON")); os.IsNotExist(err) { - os.Exit(1) - } - oauthPath = os.Getenv("TWITCH_OAUTH_JSON") - } else { - if _, err := os.Stat(os.Getenv("HOME") + "/.twitch/oauth.json"); os.IsNotExist(err) { - rgb.YPrintf("[%s] Warning %s doesn't exist, trying %s next!\n", irc.TimeStamp(), os.Getenv("HOME")+"/.twitch/oauth.json", "/etc/twitch/oauth.json") - if _, err := os.Stat("/etc/twitch/oauth.json"); os.IsNotExist(err) { - rgb.YPrintf("[%s] Error %s doesn't exist either, bailing!\n", irc.TimeStamp(), "/etc/twitch/oauth.json") + if config.OAuthPath == "" { + if os.Getenv("TWITCH_OAUTH_JSON") != "" { + if _, err := os.Stat(os.Getenv("TWITCH_OAUTH_JSON")); os.IsNotExist(err) { os.Exit(1) } - oauthPath = "/etc/twitch/oauth.json" + oauthPath = os.Getenv("TWITCH_OAUTH_JSON") } else { - oauthPath = os.Getenv("HOME") + "/.twitch/oauth.json" + if _, err := os.Stat(os.Getenv("HOME") + "/.twitch/oauth.json"); os.IsNotExist(err) { + rgb.YPrintf("[%s] Warning %s doesn't exist, trying %s next!\n", irc.TimeStamp(), os.Getenv("HOME")+"/.twitch/oauth.json", "/etc/twitch/oauth.json") + if _, err := os.Stat("/etc/twitch/oauth.json"); os.IsNotExist(err) { + rgb.YPrintf("[%s] Error %s doesn't exist either, bailing!\n", irc.TimeStamp(), "/etc/twitch/oauth.json") + os.Exit(1) + } + oauthPath = "/etc/twitch/oauth.json" + } else { + oauthPath = os.Getenv("HOME") + "/.twitch/oauth.json" + } } + } else { + if _, err := os.Stat(config.OAuthPath); os.IsNotExist(err) { + rgb.YPrintf("[%s] Error config-specified oauth file %s doesn't exist, bailing!\n", irc.TimeStamp(), config.OAuthPath) + os.Exit(1) + } + oauthPath = config.OAuthPath } + persistentData := openDatabase() + persistentData.Write("prompts", "common", selectablePrompts) + // Replace the channel name, bot name, and the path to the private directory with your respective // values. myBot := irc.KardBot{