/ lib / config.go
config.go
  1  package lib
  2  
  3  import (
  4  	"fmt"
  5  	"net"
  6  	"net/url"
  7  	"os"
  8  	"strings"
  9  
 10  	"github.com/spf13/viper"
 11  )
 12  
 13  type Config struct {
 14  	Debug string
 15  
 16  	Admin struct {
 17  		Username string
 18  		Password string
 19  	}
 20  
 21  	Database struct {
 22  		Type       string
 23  		Connection string
 24  	}
 25  
 26  	Server struct {
 27  		BindIP   string
 28  		Port     string
 29  		Endpoint struct {
 30  			Api string
 31  			Web string
 32  		}
 33  	}
 34  
 35  	Feeds struct {
 36  		AutoRefresh string
 37  	}
 38  }
 39  
 40  func Cfg() (Config, error) {
 41  	viper.SetDefault("Debug", "false")
 42  
 43  	viper.SetDefault("Admin.Username", "admin")
 44  	viper.SetDefault("Admin.Password", "admin")
 45  
 46  	viper.SetDefault("Database.Type", "sqlite3")
 47  	viper.SetDefault("Database.Connection", "file:ent?mode=memory&cache=shared&_fk=1")
 48  
 49  	viper.SetDefault("Server.BindIP", "127.0.0.1")
 50  	viper.SetDefault("Server.Port", "8000")
 51  	viper.SetDefault("Server.Endpoint.Api", "http://127.0.0.1:8000/api")
 52  	viper.SetDefault("Server.Endpoint.Web", "http://127.0.0.1:8000/web")
 53  
 54  	viper.SetDefault("Feeds.AutoRefresh", "900")
 55  
 56  	viper.SetConfigName("journalist.toml")
 57  	viper.SetConfigType("toml")
 58  	viper.AddConfigPath("/etc/")
 59  	viper.AddConfigPath("$XDG_CONFIG_HOME/")
 60  	viper.AddConfigPath("$HOME/.config/")
 61  	viper.AddConfigPath("$HOME/")
 62  	viper.AddConfigPath(".")
 63  
 64  	viper.SetEnvPrefix("journalist")
 65  	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
 66  	viper.AutomaticEnv()
 67  
 68  	if err := viper.ReadInConfig(); err != nil {
 69  		if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
 70  			return Config{}, err
 71  		}
 72  	}
 73  
 74  	var config Config
 75  	if err := viper.Unmarshal(&config); err != nil {
 76  		return Config{}, err
 77  	}
 78  
 79  	config = *ParseDatabaseURL(&config)
 80  
 81  	return config, nil
 82  }
 83  
 84  func ParseDatabaseURL(config *Config) *Config {
 85  	databaseURL := os.Getenv("DATABASE_URL")
 86  	if databaseURL == "" {
 87  		return config
 88  	}
 89  
 90  	dbURL, err := url.Parse(databaseURL)
 91  	if err != nil {
 92  		return config
 93  	}
 94  
 95  	host, port, _ := net.SplitHostPort(dbURL.Host)
 96  	dbname := strings.TrimLeft(dbURL.Path, "/")
 97  	user := dbURL.User.Username()
 98  	password, _ := dbURL.User.Password()
 99  
100  	switch dbURL.Scheme {
101  	case "postgresql", "postgres":
102  		if port == "" {
103  			port = "5432"
104  		}
105  		config.Database.Type = "postgres"
106  		config.Database.Connection = fmt.Sprintf(
107  			"host=%s port=%s dbname=%s user=%s password=%s",
108  			host, port, dbname, user, password,
109  		)
110  	case "mysql":
111  		if port == "" {
112  			port = "3306"
113  		}
114  		config.Database.Type = "mysql"
115  		config.Database.Connection = fmt.Sprintf(
116  			"%s:%s@tcp(%s:%s)/%s?parseTime=True",
117  			user, password, host, port, dbname,
118  		)
119  	}
120  
121  	return config
122  }