rum-goggles/internal/config/config.go

244 lines
5.3 KiB
Go
Raw Normal View History

package config
import (
"encoding/json"
"fmt"
"os"
2023-12-24 21:18:42 +00:00
"path/filepath"
"runtime"
"time"
"github.com/tylertravisty/go-utils/random"
)
const (
CIDLen = 8
DefaultInterval = 10
2023-12-24 21:18:42 +00:00
configDir = ".rum-goggles"
configDirWin = "RumGoggles"
configFile = "config.json"
logFile = "logs.txt"
)
2023-12-26 16:30:29 +00:00
func LogFile() (*os.File, error) {
2023-12-24 21:18:42 +00:00
dir, err := buildConfigDir()
if err != nil {
2023-12-26 16:30:29 +00:00
return nil, fmt.Errorf("config: error getting config directory: %v", err)
2023-12-24 21:18:42 +00:00
}
2023-12-26 16:30:29 +00:00
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
2023-12-24 21:18:42 +00:00
}
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 {
ID string `json:"id"`
2023-12-24 21:18:42 +00:00
AsChannel bool `json:"as_channel"`
2024-01-30 17:24:07 +00:00
Command string `json:"command"`
2023-12-24 21:18:42 +00:00
Interval time.Duration `json:"interval"`
2024-01-30 17:24:07 +00:00
OnCommand bool `json:"on_command"`
Text string `json:"text"`
2024-01-30 17:24:07 +00:00
TextFile string `json:"text_file"`
2023-12-24 21:18:42 +00:00
}
type ChatBot struct {
Messages map[string]ChatMessage `json:"messages"`
2023-12-24 21:18:42 +00:00
// Commands []ChatCommand
}
type Channel struct {
ID string `json:"id"`
ApiUrl string `json:"api_url"`
Name string `json:"name"`
Interval time.Duration `json:"interval"`
2023-12-24 21:18:42 +00:00
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{map[string]ChatMessage{}}}
return id, nil
}
}
}
func (a *App) DeleteChatMessage(id string, cid string) error {
channel, exists := a.Channels[cid]
if !exists {
return fmt.Errorf("config: channel does not exist")
}
_, exists = channel.ChatBot.Messages[id]
if !exists {
return fmt.Errorf("config: message does not exist")
}
delete(channel.ChatBot.Messages, id)
return nil
}
2024-01-30 17:24:07 +00:00
func (a *App) NewChatMessage(cid string, asChannel bool, command string, interval time.Duration, onCommand bool, text string, textFile string) (string, error) {
if _, exists := a.Channels[cid]; !exists {
return "", fmt.Errorf("config: channel does not exist")
}
for {
id, err := random.String(CIDLen)
if err != nil {
return "", fmt.Errorf("config: error generating ID: %v", err)
}
if _, exists := a.Channels[cid].ChatBot.Messages[id]; !exists {
2024-01-30 17:24:07 +00:00
a.Channels[cid].ChatBot.Messages[id] = ChatMessage{
ID: id,
AsChannel: asChannel,
Command: command,
Interval: interval,
OnCommand: onCommand,
Text: text,
TextFile: textFile,
}
return id, nil
}
}
}
2024-01-30 17:24:07 +00:00
func (a *App) UpdateChatMessage(id string, cid string, asChannel bool, command string, interval time.Duration, onCommand bool, text string, textFile string) (string, error) {
channel, exists := a.Channels[cid]
if !exists {
return "", fmt.Errorf("config: channel does not exist")
}
2024-01-30 17:24:07 +00:00
cm, exists := channel.ChatBot.Messages[id]
if !exists {
return "", fmt.Errorf("config: message does not exist")
}
2024-01-30 17:24:07 +00:00
cm.AsChannel = asChannel
cm.Command = command
cm.Interval = interval
cm.OnCommand = onCommand
cm.Text = text
cm.TextFile = textFile
channel.ChatBot.Messages[id] = cm
return id, nil
}
type App struct {
Channels map[string]Channel `json:"channels"`
}
2023-12-24 21:18:42 +00:00
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 {
2023-12-24 21:18:42 +00:00
return nil, fmt.Errorf("error opening file: %w", err)
}
var app App
decoder := json.NewDecoder(f)
err = decoder.Decode(&app)
if err != nil {
2023-12-24 21:18:42 +00:00
return nil, fmt.Errorf("error decoding file into json: %v", err)
}
return &app, nil
}
2023-12-24 21:18:42 +00:00
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 {
2023-12-24 21:18:42 +00:00
return fmt.Errorf("error encoding config into json: %v", err)
}
err = os.WriteFile(filepath, b, 0666)
if err != nil {
2023-12-24 21:18:42 +00:00
return fmt.Errorf("error writing config file: %v", err)
}
return nil
}