Less hard-coding, more "database"

Signed-off-by: Martyn Ranyard <m@rtyn.berlin>
This commit is contained in:
Martyn 2020-02-15 12:56:17 +01:00
parent a9dc6db0a4
commit a85052a41a
2 changed files with 142 additions and 26 deletions

3
configs/config.json Executable file
View File

@ -0,0 +1,3 @@
{
"channels": ["iMartynOnTwitch"]
}

165
main.go
View File

@ -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{