112 lines
2.4 KiB
Go
112 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"net/url"
|
|
"os"
|
|
"strconv"
|
|
"text/template"
|
|
"time"
|
|
|
|
"github.com/Masterminds/sprig"
|
|
"github.com/pelletier/go-toml/v2"
|
|
"go.elara.ws/logger/log"
|
|
"go.elara.ws/pcre"
|
|
)
|
|
|
|
type ConfigFile struct {
|
|
Lemmy struct {
|
|
InstanceURL string `toml:"instanceURL"`
|
|
Account struct {
|
|
UserOrEmail string `toml:"userOrEmail"`
|
|
Password string `toml:"password"`
|
|
} `toml:"account"`
|
|
} `toml:"lemmy"`
|
|
Replies []Reply `toml:"reply"`
|
|
}
|
|
|
|
type Reply struct {
|
|
Regex string `toml:"regex"`
|
|
Msg string `toml:"msg"`
|
|
}
|
|
|
|
type Config struct {
|
|
ConfigFile *ConfigFile
|
|
Regexes map[string]*pcre.Regexp
|
|
Tmpls map[string]*template.Template
|
|
PollInterval time.Duration
|
|
}
|
|
|
|
func loadConfig(path string) (Config, error) {
|
|
fi, err := os.Stat(path)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
|
|
if fi.Mode().Perm() != 0o600 {
|
|
log.Fatal("Your config file's permissions are insecure. Please use chmod to set them to 600. Refusing to start.").Send()
|
|
}
|
|
|
|
fl, err := os.Open(path)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
|
|
cfgFile := &ConfigFile{}
|
|
err = toml.NewDecoder(fl).Decode(cfgFile)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
|
|
compiledRegexes, compiledTmpls, err := compileReplies(cfgFile.Replies)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
|
|
cfg := Config{cfgFile, compiledRegexes, compiledTmpls, 15 * time.Second}
|
|
validateConfig(cfg)
|
|
return cfg, nil
|
|
}
|
|
|
|
func compileReplies(replies []Reply) (map[string]*pcre.Regexp, map[string]*template.Template, error) {
|
|
compiledRegexes := map[string]*pcre.Regexp{}
|
|
compiledTmpls := map[string]*template.Template{}
|
|
|
|
for i, reply := range replies {
|
|
if _, ok := compiledRegexes[reply.Regex]; ok {
|
|
continue
|
|
}
|
|
|
|
re, err := pcre.Compile(reply.Regex)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
compiledRegexes[reply.Regex] = re
|
|
|
|
tmpl, err := template.
|
|
New(strconv.Itoa(i)).
|
|
Funcs(sprig.TxtFuncMap()).
|
|
Parse(reply.Msg)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
compiledTmpls[reply.Regex] = tmpl
|
|
}
|
|
|
|
return compiledRegexes, compiledTmpls, nil
|
|
}
|
|
|
|
func validateConfig(cfg Config) {
|
|
_, err := url.Parse(cfg.ConfigFile.Lemmy.InstanceURL)
|
|
if err != nil {
|
|
log.Fatal("Lemmy instance URL is not valid").Err(err).Send()
|
|
}
|
|
|
|
for i, reply := range cfg.ConfigFile.Replies {
|
|
re := cfg.Regexes[reply.Regex]
|
|
|
|
if re.MatchString(reply.Msg) {
|
|
log.Fatal("Regular expression matches message. This may create an infinite loop. Refusing to start.").Int("reply-index", i).Send()
|
|
}
|
|
}
|
|
}
|