rum-goggles/internal/config/config.go
2023-12-26 11:30:29 -05:00

176 lines
3.5 KiB
Go

package config
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"runtime"
"time"
"github.com/tylertravisty/go-utils/random"
)
const (
CIDLen = 8
DefaultInterval = 10
configDir = ".rum-goggles"
configDirWin = "RumGoggles"
configFile = "config.json"
logFile = "logs.txt"
)
func LogFile() (*os.File, error) {
dir, err := buildConfigDir()
if err != nil {
return nil, fmt.Errorf("config: error getting config directory: %v", err)
}
err = os.MkdirAll(dir, 0750)
if err != nil {
return nil, fmt.Errorf("config: error making config directory: %v", err)
}
fp := filepath.Join(dir, logFile)
f, err := os.OpenFile(fp, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
if err != nil {
return nil, fmt.Errorf("config: error opening log file: %v", err)
}
return f, nil
}
func buildConfigDir() (string, error) {
userDir, err := userDir()
if err != nil {
return "", fmt.Errorf("error getting user directory: %v", err)
}
var dir string
switch runtime.GOOS {
case "windows":
dir = filepath.Join(userDir, configDirWin)
default:
dir = filepath.Join(userDir, configDir)
}
return dir, nil
}
func userDir() (string, error) {
var dir string
var err error
switch runtime.GOOS {
case "windows":
dir, err = os.UserCacheDir()
default:
dir, err = os.UserHomeDir()
}
return dir, err
}
type ChatMessage struct {
AsChannel bool `json:"as_channel"`
Text string `json:"text"`
Interval time.Duration `json:"interval"`
}
type ChatBot struct {
Messages []ChatMessage `json:"messages"`
// Commands []ChatCommand
}
type Channel struct {
ID string `json:"id"`
ApiUrl string `json:"api_url"`
Name string `json:"name"`
Interval time.Duration `json:"interval"`
ChatBot ChatBot `json:"chat_bot"`
}
func (a *App) NewChannel(url string, name string) (string, error) {
for {
id, err := random.String(CIDLen)
if err != nil {
return "", fmt.Errorf("config: error generating ID: %v", err)
}
if _, exists := a.Channels[id]; !exists {
a.Channels[id] = Channel{id, url, name, DefaultInterval, ChatBot{[]ChatMessage{}}}
return id, nil
}
}
}
type App struct {
Channels map[string]Channel `json:"channels"`
}
func Load() (*App, error) {
dir, err := buildConfigDir()
if err != nil {
return nil, fmt.Errorf("config: error getting config directory: %v", err)
}
fp := filepath.Join(dir, configFile)
app, err := load(fp)
if err != nil {
return nil, fmt.Errorf("config: error loading config: %w", err)
}
return app, nil
}
func load(filepath string) (*App, error) {
f, err := os.Open(filepath)
if err != nil {
return nil, fmt.Errorf("error opening file: %w", err)
}
var app App
decoder := json.NewDecoder(f)
err = decoder.Decode(&app)
if err != nil {
return nil, fmt.Errorf("error decoding file into json: %v", err)
}
return &app, nil
}
func (a *App) Save() error {
dir, err := buildConfigDir()
if err != nil {
return fmt.Errorf("config: error getting config directory: %v", err)
}
err = os.MkdirAll(dir, 0750)
if err != nil {
return fmt.Errorf("config: error making config directory: %v", err)
}
fp := filepath.Join(dir, configFile)
err = a.save(fp)
if err != nil {
return fmt.Errorf("config: error saving config: %v", err)
}
return nil
}
func (app *App) save(filepath string) error {
b, err := json.MarshalIndent(app, "", "\t")
if err != nil {
return fmt.Errorf("error encoding config into json: %v", err)
}
err = os.WriteFile(filepath, b, 0666)
if err != nil {
return fmt.Errorf("error writing config file: %v", err)
}
return nil
}