2020-06-18 23:54:48 +03:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
2020-07-10 02:28:39 +03:00
|
|
|
"fmt"
|
2020-06-18 23:54:48 +03:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
2020-06-22 18:56:55 +03:00
|
|
|
"strings"
|
2020-06-18 23:54:48 +03:00
|
|
|
|
2020-07-28 23:58:32 +03:00
|
|
|
"github.com/gdamore/tcell"
|
2020-06-18 23:54:48 +03:00
|
|
|
"github.com/makeworld-the-better-one/amfora/cache"
|
|
|
|
homedir "github.com/mitchellh/go-homedir"
|
|
|
|
"github.com/spf13/viper"
|
2020-07-28 23:58:32 +03:00
|
|
|
"gitlab.com/tslocum/cview"
|
2020-06-18 23:54:48 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
var amforaAppData string // Where amfora files are stored on Windows - cached here
|
2020-06-22 00:35:19 +03:00
|
|
|
var configDir string
|
|
|
|
var configPath string
|
2020-06-18 23:54:48 +03:00
|
|
|
|
|
|
|
var TofuStore = viper.New()
|
2020-06-22 00:35:19 +03:00
|
|
|
var tofuDBDir string
|
|
|
|
var tofuDBPath string
|
2020-06-18 23:54:48 +03:00
|
|
|
|
2020-06-24 03:07:25 +03:00
|
|
|
// Bookmarks
|
|
|
|
var BkmkStore = viper.New()
|
|
|
|
var bkmkDir string
|
|
|
|
var bkmkPath string
|
|
|
|
|
2020-07-10 02:28:39 +03:00
|
|
|
// For other pkgs to use
|
|
|
|
var DownloadsDir string
|
|
|
|
|
2020-08-07 19:27:50 +03:00
|
|
|
// Feeds
|
|
|
|
var Feeds = viper.New()
|
|
|
|
var feedsDir string
|
|
|
|
var feedsPath string
|
|
|
|
|
2020-06-18 23:54:48 +03:00
|
|
|
func Init() error {
|
2020-08-07 19:27:50 +03:00
|
|
|
|
|
|
|
// *** Set paths ***
|
|
|
|
|
2020-06-18 23:54:48 +03:00
|
|
|
home, err := homedir.Dir()
|
|
|
|
if err != nil {
|
2020-07-10 02:28:39 +03:00
|
|
|
return err
|
2020-06-18 23:54:48 +03:00
|
|
|
}
|
2020-06-24 03:07:25 +03:00
|
|
|
// Store AppData path
|
2020-06-18 23:54:48 +03:00
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
appdata, ok := os.LookupEnv("APPDATA")
|
|
|
|
if ok {
|
|
|
|
amforaAppData = filepath.Join(appdata, "amfora")
|
|
|
|
} else {
|
|
|
|
amforaAppData = filepath.Join(home, filepath.FromSlash("AppData/Roaming/amfora/"))
|
|
|
|
}
|
|
|
|
}
|
2020-06-24 03:07:25 +03:00
|
|
|
|
|
|
|
// Store config directory and file paths
|
2020-06-22 00:35:19 +03:00
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
configDir = amforaAppData
|
|
|
|
} else {
|
|
|
|
// Unix / POSIX system
|
2020-06-22 18:56:55 +03:00
|
|
|
xdg_config, ok := os.LookupEnv("XDG_CONFIG_HOME")
|
|
|
|
if ok && strings.TrimSpace(xdg_config) != "" {
|
|
|
|
configDir = filepath.Join(xdg_config, "amfora")
|
|
|
|
} else {
|
|
|
|
// Default to ~/.config/amfora
|
|
|
|
configDir = filepath.Join(home, ".config", "amfora")
|
|
|
|
}
|
2020-06-22 00:35:19 +03:00
|
|
|
}
|
|
|
|
configPath = filepath.Join(configDir, "config.toml")
|
|
|
|
|
2020-06-24 03:07:25 +03:00
|
|
|
// Store TOFU db directory and file paths
|
2020-06-22 00:35:19 +03:00
|
|
|
if runtime.GOOS == "windows" {
|
2020-06-22 18:56:55 +03:00
|
|
|
// Windows just stores it in APPDATA along with other stuff
|
2020-06-22 00:35:19 +03:00
|
|
|
tofuDBDir = amforaAppData
|
|
|
|
} else {
|
|
|
|
// XDG cache dir on POSIX systems
|
2020-06-22 18:56:55 +03:00
|
|
|
xdg_cache, ok := os.LookupEnv("XDG_CACHE_HOME")
|
|
|
|
if ok && strings.TrimSpace(xdg_cache) != "" {
|
|
|
|
tofuDBDir = filepath.Join(xdg_cache, "amfora")
|
|
|
|
} else {
|
|
|
|
// Default to ~/.cache/amfora
|
|
|
|
tofuDBDir = filepath.Join(home, ".cache", "amfora")
|
|
|
|
}
|
2020-06-22 00:35:19 +03:00
|
|
|
}
|
|
|
|
tofuDBPath = filepath.Join(tofuDBDir, "tofu.toml")
|
2020-06-18 23:54:48 +03:00
|
|
|
|
2020-06-24 03:07:25 +03:00
|
|
|
// Store bookmarks dir and path
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
// Windows just keeps it in APPDATA along with other Amfora files
|
|
|
|
bkmkDir = amforaAppData
|
|
|
|
} else {
|
|
|
|
// XDG data dir on POSIX systems
|
|
|
|
xdg_data, ok := os.LookupEnv("XDG_DATA_HOME")
|
|
|
|
if ok && strings.TrimSpace(xdg_data) != "" {
|
|
|
|
bkmkDir = filepath.Join(xdg_data, "amfora")
|
|
|
|
} else {
|
|
|
|
// Default to ~/.local/share/amfora
|
|
|
|
bkmkDir = filepath.Join(home, ".local", "share", "amfora")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bkmkPath = filepath.Join(bkmkDir, "bookmarks.toml")
|
|
|
|
|
2020-08-07 19:27:50 +03:00
|
|
|
// *** Create necessary files and folders ***
|
2020-06-24 03:07:25 +03:00
|
|
|
|
|
|
|
// Config
|
2020-06-22 00:35:19 +03:00
|
|
|
err = os.MkdirAll(configDir, 0755)
|
2020-06-18 23:54:48 +03:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-06-22 00:35:19 +03:00
|
|
|
f, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
|
2020-06-18 23:54:48 +03:00
|
|
|
if err == nil {
|
|
|
|
// Config file doesn't exist yet, write the default one
|
|
|
|
_, err = f.Write(defaultConf)
|
|
|
|
if err != nil {
|
|
|
|
f.Close()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
f.Close()
|
|
|
|
}
|
2020-06-24 03:07:25 +03:00
|
|
|
// TOFU
|
2020-06-22 00:35:19 +03:00
|
|
|
err = os.MkdirAll(tofuDBDir, 0755)
|
2020-06-18 23:54:48 +03:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-08-07 19:27:50 +03:00
|
|
|
f, err = os.OpenFile(tofuDBPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
|
|
|
|
if err == nil {
|
|
|
|
f.Close()
|
|
|
|
}
|
2020-06-24 03:07:25 +03:00
|
|
|
// Bookmarks
|
|
|
|
err = os.MkdirAll(bkmkDir, 0755)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-08-07 19:27:50 +03:00
|
|
|
f, err = os.OpenFile(bkmkPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
|
|
|
|
if err == nil {
|
|
|
|
f.Close()
|
|
|
|
}
|
2020-06-24 03:07:25 +03:00
|
|
|
|
2020-08-07 19:27:50 +03:00
|
|
|
// *** Downloads paths, setup, and creation ***
|
|
|
|
|
|
|
|
// Setup downloads dir
|
|
|
|
if viper.GetString("a-general.downloads") == "" {
|
|
|
|
// Find default Downloads dir
|
|
|
|
// This seems to work for all OSes?
|
|
|
|
DownloadsDir = filepath.Join(home, "Downloads")
|
|
|
|
// Create it just in case
|
|
|
|
err = os.MkdirAll(DownloadsDir, 0755)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("downloads path could not be created: %s", DownloadsDir)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Validate path
|
|
|
|
dDir := viper.GetString("a-general.downloads")
|
|
|
|
di, err := os.Stat(dDir)
|
|
|
|
if err == nil {
|
|
|
|
if !di.IsDir() {
|
|
|
|
return fmt.Errorf("downloads path specified is not a directory: %s", dDir)
|
|
|
|
}
|
|
|
|
} else if os.IsNotExist(err) {
|
|
|
|
// Try to create path
|
|
|
|
err = os.MkdirAll(dDir, 0755)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("downloads path could not be created: %s", dDir)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Some other error
|
|
|
|
return fmt.Errorf("couldn't access downloads directory: %s", dDir)
|
|
|
|
}
|
|
|
|
DownloadsDir = dDir
|
|
|
|
}
|
|
|
|
|
|
|
|
// *** Setup vipers ***
|
2020-06-18 23:54:48 +03:00
|
|
|
|
2020-06-22 00:35:19 +03:00
|
|
|
TofuStore.SetConfigFile(tofuDBPath)
|
2020-06-18 23:54:48 +03:00
|
|
|
TofuStore.SetConfigType("toml")
|
|
|
|
err = TofuStore.ReadInConfig()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-06-24 03:07:25 +03:00
|
|
|
BkmkStore.SetConfigFile(bkmkPath)
|
|
|
|
BkmkStore.SetConfigType("toml")
|
|
|
|
err = BkmkStore.ReadInConfig()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
BkmkStore.Set("DO NOT TOUCH", true)
|
|
|
|
err = BkmkStore.WriteConfig()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-08-07 19:27:50 +03:00
|
|
|
// Setup main config
|
|
|
|
|
2020-06-18 23:54:48 +03:00
|
|
|
viper.SetDefault("a-general.home", "gemini.circumlunar.space")
|
|
|
|
viper.SetDefault("a-general.http", "default")
|
|
|
|
viper.SetDefault("a-general.search", "gus.guru/search")
|
|
|
|
viper.SetDefault("a-general.color", true)
|
|
|
|
viper.SetDefault("a-general.bullets", true)
|
2020-06-21 23:53:12 +03:00
|
|
|
viper.SetDefault("a-general.left_margin", 0.15)
|
|
|
|
viper.SetDefault("a-general.max_width", 100)
|
2020-07-10 02:28:39 +03:00
|
|
|
viper.SetDefault("a-general.downloads", "")
|
2020-07-10 22:33:39 +03:00
|
|
|
viper.SetDefault("a-general.page_max_size", 2097152)
|
|
|
|
viper.SetDefault("a-general.page_max_time", 10)
|
2020-08-05 20:31:59 +03:00
|
|
|
viper.SetDefault("a-general.emoji_favicons", false)
|
2020-08-06 20:55:43 +03:00
|
|
|
viper.SetDefault("keybindings.shift_numbers", "!@#$%^&*()")
|
2020-06-18 23:54:48 +03:00
|
|
|
viper.SetDefault("cache.max_size", 0)
|
|
|
|
viper.SetDefault("cache.max_pages", 20)
|
|
|
|
|
2020-06-22 00:35:19 +03:00
|
|
|
viper.SetConfigFile(configPath)
|
2020-06-18 23:54:48 +03:00
|
|
|
viper.SetConfigType("toml")
|
|
|
|
err = viper.ReadInConfig()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup cache from config
|
|
|
|
cache.SetMaxSize(viper.GetInt("cache.max_size"))
|
|
|
|
cache.SetMaxPages(viper.GetInt("cache.max_pages"))
|
|
|
|
|
2020-08-07 19:27:50 +03:00
|
|
|
// Setup theme
|
2020-07-28 23:58:32 +03:00
|
|
|
configTheme := viper.Sub("theme")
|
|
|
|
if configTheme != nil {
|
|
|
|
for k, v := range configTheme.AllSettings() {
|
|
|
|
colorStr, ok := v.(string)
|
|
|
|
if !ok {
|
|
|
|
return fmt.Errorf(`value for "%s" is not a string: %v`, k, v)
|
|
|
|
}
|
|
|
|
color := tcell.GetColor(strings.ToLower(colorStr))
|
|
|
|
if color == tcell.ColorDefault {
|
|
|
|
return fmt.Errorf(`invalid color format for "%s": %s`, k, colorStr)
|
|
|
|
}
|
|
|
|
SetColor(k, color)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if viper.GetBool("a-general.color") {
|
|
|
|
cview.Styles.PrimitiveBackgroundColor = GetColor("bg")
|
|
|
|
} // Otherwise it's black by default
|
|
|
|
|
2020-06-18 23:54:48 +03:00
|
|
|
return nil
|
|
|
|
}
|