You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
superhighway84/config/config.go

243 lines
6.4 KiB
Go

package config
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/BurntSushi/toml"
"github.com/gdamore/tcell/v2"
)
type ConfigProfile struct {
From string
Organization string
}
type ConfigShortcuts struct {
Refresh int64
Quit int64
FocusGroups int64
FocusArticles int64
FocusPreviews int64
NewArticle int64
ReplyToArticle int64
}
type Config struct {
ConfigFile string `toml:"-"`
ConnectionString string
CachePath string // Deprecated, should be removed soon
DatabaseCachePath string
ProgramCachePath string
Logfile string
Profile ConfigProfile
Shortcuts map[string]string
ShortcutsReference string
ArticlesListView int8
}
func LoadConfig() (*Config, error) {
configDir, exist := os.LookupEnv("XDG_CONFIG_HOME")
if exist == false {
configDir, exist = os.LookupEnv("HOME")
if exist == false {
return nil, errors.New("No XDG_CONFIG_HOME or HOME set!")
}
configDir = filepath.Join(configDir, ".config")
}
os.MkdirAll(configDir, 0755)
configFile := filepath.Join(configDir, "superhighway84.toml")
f, err := os.OpenFile(configFile, os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
return nil, err
}
defer f.Close()
configFileContent, err := ioutil.ReadAll(f)
if err != nil {
return nil, err
}
cfg := new(Config)
cfg.Shortcuts = make(map[string]string)
_, err = toml.Decode(string(configFileContent), &cfg)
if err != nil {
return nil, errors.New("The config could not be parsed, make sure it is valid TOML and you don't have double assignments.")
}
cfg.ConfigFile = configFile
err = cfg.LoadDefaults()
if err != nil {
return nil, err
}
return cfg, nil
}
func (cfg *Config) LoadDefaults() (error) {
shortcutDefaults := []struct{
key tcell.Key
command string
keyAltText string
} {
{tcell.KeyCtrlQ, "quit", "C-q"},
{tcell.KeyCtrlR, "refresh", "C-r"},
{tcell.KeyCtrlH, "focus-groups", "C-h"},
{tcell.KeyCtrlL, "focus-articles", "C-l"},
{tcell.KeyCtrlK, "focus-articles", "C-k"},
{tcell.KeyCtrlJ, "focus-preview", "C-j"},
{tcell.KeyCtrlA, "article-mark-all-read", "C-a"},
{tcell.Key('n'), "article-new", ""},
{tcell.Key('r'), "article-reply", ""},
{tcell.Key('h'), "additional-key-left", ""},
{tcell.Key('j'), "additional-key-down", ""},
{tcell.Key('k'), "additional-key-up", ""},
{tcell.Key('l'), "additional-key-right", ""},
{tcell.Key('g'), "additional-key-home", ""},
{tcell.Key('G'), "additional-key-end", ""},
{tcell.KeyF8, "play", "F8"},
{tcell.Key('?'), "help", ""},
}
var sb strings.Builder
for _, shortcut := range shortcutDefaults {
keyText := string(shortcut.key)
if shortcut.keyAltText != "" {
keyText = shortcut.keyAltText
}
sb.WriteString(fmt.Sprintf("%s - %s\n", keyText, shortcut.command))
}
cfg.ShortcutsReference = sb.String()
if len(cfg.Shortcuts) == 0 {
for _, shortcut := range shortcutDefaults {
cfg.Shortcuts[strconv.FormatInt(int64(shortcut.key), 10)] = shortcut.command
}
}
return cfg.Persist()
}
func (cfg *Config) Persist() (error) {
buf := new(bytes.Buffer)
if err := toml.NewEncoder(buf).Encode(cfg); err != nil {
return err
}
if err := ioutil.WriteFile(cfg.ConfigFile, buf.Bytes(), 0644); err != nil {
return err
}
return nil
}
func (cfg *Config) WasSetup() (bool) {
if cfg.DatabaseCachePath == "" ||
cfg.ProgramCachePath == "" ||
cfg.ConnectionString == "" ||
cfg.Logfile == "" ||
cfg.Profile.From == "" {
return false
}
return true
}
func (cfg *Config) Setup() (error) {
fmt.Printf("\nSUPERHIGHWAY84\n\nInitial Setup\n-------------\n\n")
defaultConnectionString := "/orbitdb/bafyreifdpagppa7ve45odxuvudz5snbzcybwyfer777huckl4li4zbc5k4/superhighway84"
if cfg.ConnectionString != "" {
defaultConnectionString = cfg.ConnectionString
}
fmt.Printf("Database connection string [%s]: ", defaultConnectionString)
fmt.Scanln(&cfg.ConnectionString)
if strings.TrimSpace(cfg.ConnectionString) == "" {
cfg.ConnectionString = defaultConnectionString
}
cacheDir, exist := os.LookupEnv("XDG_CACHE_HOME")
if exist == false {
cacheDir = filepath.Join(os.Getenv("HOME"), ".cache")
}
defaultDatabaseCachePath := filepath.Join(cacheDir, "superhighway84", "database")
// Migration step from old CachePath to new DatabaseCachePath
if cfg.CachePath != "" {
defaultDatabaseCachePath = cfg.CachePath
}
fmt.Printf("Database cache path [%s]: ", defaultDatabaseCachePath)
fmt.Scanln(&cfg.DatabaseCachePath)
if strings.TrimSpace(cfg.DatabaseCachePath) == "" {
cfg.DatabaseCachePath = defaultDatabaseCachePath
}
os.MkdirAll(filepath.Dir(cfg.DatabaseCachePath), 0755)
defaultProgramCachePath := filepath.Join(cacheDir, "superhighway84", "program")
// Migration step from old CachePath to new DatabaseCachePath
if cfg.CachePath != "" {
// If the previous CachePath was used, the folder already contains the
// OrbitDB, hence we need to find a different place
defaultProgramCachePath = filepath.Join(cacheDir, "superhighway84.program")
}
fmt.Printf("Program cache path [%s]: ", defaultProgramCachePath)
fmt.Scanln(&cfg.ProgramCachePath)
if strings.TrimSpace(cfg.ProgramCachePath) == "" {
cfg.ProgramCachePath = defaultProgramCachePath
}
os.MkdirAll(filepath.Dir(cfg.ProgramCachePath), 0755)
defaultLogfile := filepath.Join(cacheDir, "superhighway84.log")
if cfg.Logfile != "" {
defaultLogfile = cfg.Logfile
}
fmt.Printf("Logfile path [%s]: ", defaultLogfile)
fmt.Scanln(&cfg.Logfile)
if strings.TrimSpace(cfg.Logfile) == "" {
cfg.Logfile = defaultLogfile
}
fmt.Printf("\nProfile information\n-------------------\n\n")
defaultProfileFrom := fmt.Sprintf("%s@localhost", os.Getenv("USER"))
if cfg.Profile.From != "" {
defaultProfileFrom = cfg.Profile.From
}
fmt.Printf("From [%s]: ", defaultProfileFrom)
fmt.Scanln(&cfg.Profile.From)
if strings.TrimSpace(cfg.Profile.From) == "" {
cfg.Profile.From = defaultProfileFrom
}
defaultProfileOrganization := ""
if cfg.Profile.Organization != "" {
defaultProfileOrganization = cfg.Profile.Organization
}
fmt.Printf("Organization [%s]: ", defaultProfileOrganization)
fmt.Scanln(&cfg.Profile.Organization)
return cfg.Persist()
}