pcgamedb/config/config.go

158 lines
4.0 KiB
Go

package config
import (
"bytes"
"encoding/json"
"os"
"os/exec"
"reflect"
"strconv"
"strings"
"time"
)
type config struct {
LogLevel string `env:"LOG_LEVEL" json:"log_level"`
Server server `json:"server"`
Database database `json:"database"`
Redis redis `json:"redis"`
OnlineFix onlinefix `json:"online_fix"`
Twitch twitch `json:"twitch"`
Webhooks webhooks `json:"webhooks"`
CFClearanceScraper cfClearanceScraper `json:"cf_clearance_scraper"`
MegaAvaliable bool
}
type cfClearanceScraper struct {
Url string `env:"CF_CLEARANCE_SCRAPER_URL" json:"url"`
}
type webhooks struct {
CrawlTask []string `env:"WEBHOOKS_CRAWL_TASK" json:"crawl_task"`
}
type server struct {
Port string `env:"SERVER_PORT" json:"port"`
SecretKey string `env:"SERVER_SECRET_KEY" json:"secret_key"`
AutoCrawl bool `env:"SERVER_AUTO_CRAWL" json:"auto_crawl"`
AutoCrawlCron string `env:"SERVER_AUTO_CRAWL_CRON" json:"auto_crawl_cron"`
}
type database struct {
Host string `env:"DATABASE_HOST" json:"host"`
Port int `env:"DATABASE_PORT" json:"port"`
User string `env:"DATABASE_USER" json:"user"`
Password string `env:"DATABASE_PASSWORD" json:"password"`
Database string `env:"DATABASE_NAME" json:"database"`
}
type twitch struct {
ClientID string `env:"TWITCH_CLIENT_ID" json:"client_id"`
ClientSecret string `env:"TWITCH_CLIENT_SECRET" json:"client_secret"`
}
type redis struct {
Host string `env:"REDIS_HOST" json:"host"`
Port int `env:"REDIS_PORT" json:"port"`
Password string `env:"REDIS_PASSWORD" json:"password"`
DBIndex int `env:"REDIS_DB" json:"db_index"`
}
type onlinefix struct {
User string `env:"ONLINEFIX_USER" json:"user"`
Password string `env:"ONLINEFIX_PASSWORD" json:"password"`
}
type runtimeConfig struct {
ServerStartTime time.Time
}
var Config config
var Runtime runtimeConfig
func init() {
Config = config{
LogLevel: "info",
Database: database{
Port: 27017,
User: "root",
Password: "password",
},
MegaAvaliable: TestMega(),
Server: server{
AutoCrawlCron: "0 */3 * * *",
},
}
if _, err := os.Stat("config.json"); err == nil {
configData, err := os.ReadFile("config.json")
if err != nil {
panic(err)
}
err = json.Unmarshal(configData, &Config)
if err != nil {
panic(err)
}
}
loadEnvVariables(&Config)
if Config.OnlineFix.User == "" || Config.OnlineFix.Password == "" {
panic("Need OnlineFix User and Password")
}
if Config.Redis.Host == "" {
panic("Need Redis Host")
}
if Config.Database.Database == "" || Config.Database.Host == "" {
panic("Need Database Name and Host")
}
if Config.CFClearanceScraper.Url == "" {
panic("Need CF Clearance Scraper URL")
}
if !strings.HasSuffix(Config.CFClearanceScraper.Url, "/cf-clearance-scraper") {
Config.CFClearanceScraper.Url += "/cf-clearance-scraper"
}
}
func loadEnvVariables(cfg interface{}) {
v := reflect.ValueOf(cfg).Elem()
t := v.Type()
for i := 0; i < v.NumField(); i++ {
field := t.Field(i)
envTag := field.Tag.Get("env")
if envTag == "" || envTag == "-" {
if field.Type.Kind() == reflect.Struct {
loadEnvVariables(v.Field(i).Addr().Interface())
}
continue
}
envValue := os.Getenv(envTag)
if envValue == "" {
continue
}
switch field.Type.Kind() {
case reflect.String:
v.Field(i).SetString(envValue)
case reflect.Int:
if value, err := strconv.Atoi(envValue); err == nil {
v.Field(i).SetInt(int64(value))
}
case reflect.Bool:
if value, err := strconv.ParseBool(envValue); err == nil {
v.Field(i).SetBool(value)
}
case reflect.Slice:
if field.Type.Elem().Kind() == reflect.String {
envValueSlice := strings.Split(envValue, ",")
v.Field(i).Set(reflect.ValueOf(envValueSlice))
}
}
}
}
func TestMega() bool {
cmd := exec.Command("mega-get", "--help")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
return err == nil
}