Improve config handling and move types to types.go
This commit is contained in:
parent
bc91986e6c
commit
53cc18e382
52
config.go
52
config.go
@ -12,7 +12,7 @@ import (
|
|||||||
"go.elara.ws/pcre"
|
"go.elara.ws/pcre"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type ConfigFile struct {
|
||||||
Lemmy struct {
|
Lemmy struct {
|
||||||
InstanceURL string `toml:"instanceURL"`
|
InstanceURL string `toml:"instanceURL"`
|
||||||
Account struct {
|
Account struct {
|
||||||
@ -28,16 +28,16 @@ type Reply struct {
|
|||||||
Msg string `toml:"msg"`
|
Msg string `toml:"msg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
type Config struct {
|
||||||
cfg = Config{}
|
ConfigFile *ConfigFile
|
||||||
compiledRegexes = map[string]*pcre.Regexp{}
|
Regexes map[string]*pcre.Regexp
|
||||||
compiledTmpls = map[string]*template.Template{}
|
Tmpls map[string]*template.Template
|
||||||
)
|
}
|
||||||
|
|
||||||
func loadConfig(path string) error {
|
func loadConfig(path string) (Config, error) {
|
||||||
fi, err := os.Stat(path)
|
fi, err := os.Stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return Config{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.Mode().Perm() != 0o600 {
|
if fi.Mode().Perm() != 0o600 {
|
||||||
@ -46,24 +46,29 @@ func loadConfig(path string) error {
|
|||||||
|
|
||||||
fl, err := os.Open(path)
|
fl, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return Config{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = toml.NewDecoder(fl).Decode(&cfg)
|
cfgFile := &ConfigFile{}
|
||||||
|
err = toml.NewDecoder(fl).Decode(cfgFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return Config{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = compileReplies(cfg.Replies)
|
compiledRegexes, compiledTmpls, err := compileReplies(cfgFile.Replies)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return Config{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
validateConfig()
|
cfg := Config{cfgFile, compiledRegexes, compiledTmpls}
|
||||||
return nil
|
validateConfig(cfg)
|
||||||
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileReplies(replies []Reply) error {
|
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 {
|
for i, reply := range replies {
|
||||||
if _, ok := compiledRegexes[reply.Regex]; ok {
|
if _, ok := compiledRegexes[reply.Regex]; ok {
|
||||||
continue
|
continue
|
||||||
@ -71,7 +76,7 @@ func compileReplies(replies []Reply) error {
|
|||||||
|
|
||||||
re, err := pcre.Compile(reply.Regex)
|
re, err := pcre.Compile(reply.Regex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
compiledRegexes[reply.Regex] = re
|
compiledRegexes[reply.Regex] = re
|
||||||
|
|
||||||
@ -80,21 +85,22 @@ func compileReplies(replies []Reply) error {
|
|||||||
Funcs(sprig.TxtFuncMap()).
|
Funcs(sprig.TxtFuncMap()).
|
||||||
Parse(reply.Msg)
|
Parse(reply.Msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
compiledTmpls[reply.Regex] = tmpl
|
compiledTmpls[reply.Regex] = tmpl
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
return compiledRegexes, compiledTmpls, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateConfig() {
|
func validateConfig(cfg Config) {
|
||||||
_, err := url.Parse(cfg.Lemmy.InstanceURL)
|
_, err := url.Parse(cfg.ConfigFile.Lemmy.InstanceURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Lemmy instance URL is not valid").Err(err).Send()
|
log.Fatal("Lemmy instance URL is not valid").Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, reply := range cfg.Replies {
|
for i, reply := range cfg.ConfigFile.Replies {
|
||||||
re := compiledRegexes[reply.Regex]
|
re := cfg.Regexes[reply.Regex]
|
||||||
|
|
||||||
if re.MatchString(reply.Msg) {
|
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()
|
log.Fatal("Regular expression matches message. This may create an infinite loop. Refusing to start.").Int("reply-index", i).Send()
|
||||||
|
39
main.go
39
main.go
@ -19,21 +19,6 @@ import (
|
|||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Submatches []string
|
|
||||||
|
|
||||||
func (sm Submatches) Item(i int) string {
|
|
||||||
return sm[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
type TmplContext struct {
|
|
||||||
Matches []Submatches
|
|
||||||
Type string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tc TmplContext) Match(i, j int) string {
|
|
||||||
return tc.Matches[i][j]
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:embed sql/schema.sql
|
//go:embed sql/schema.sql
|
||||||
var schema string
|
var schema string
|
||||||
|
|
||||||
@ -61,19 +46,19 @@ func main() {
|
|||||||
ctx, cancel := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
|
ctx, cancel := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
err := loadConfig(*configPath)
|
cfg, err := loadConfig(*configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error loading config file").Err(err).Send()
|
log.Fatal("Error loading config file").Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := lemmy.New(cfg.Lemmy.InstanceURL)
|
c, err := lemmy.New(cfg.ConfigFile.Lemmy.InstanceURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error creating new Lemmy API client").Err(err).Send()
|
log.Fatal("Error creating new Lemmy API client").Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.ClientLogin(ctx, types.Login{
|
err = c.ClientLogin(ctx, types.Login{
|
||||||
UsernameOrEmail: cfg.Lemmy.Account.UserOrEmail,
|
UsernameOrEmail: cfg.ConfigFile.Lemmy.Account.UserOrEmail,
|
||||||
Password: cfg.Lemmy.Account.Password,
|
Password: cfg.ConfigFile.Lemmy.Account.Password,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error logging in to Lemmy instance").Err(err).Send()
|
log.Fatal("Error logging in to Lemmy instance").Err(err).Send()
|
||||||
@ -87,10 +72,10 @@ func main() {
|
|||||||
go commentReplyWorker(ctx, c, replyCh)
|
go commentReplyWorker(ctx, c, replyCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
commentWorker(ctx, c, replyCh)
|
commentWorker(ctx, c, cfg, replyCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
func commentWorker(ctx context.Context, c *lemmy.Client, replyCh chan<- replyJob) {
|
func commentWorker(ctx context.Context, c *lemmy.Client, cfg Config, replyCh chan<- replyJob) {
|
||||||
db, err := sql.Open("sqlite", "replied.db")
|
db, err := sql.Open("sqlite", "replied.db")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error opening reply database").Err(err).Send()
|
log.Fatal("Error opening reply database").Err(err).Send()
|
||||||
@ -128,8 +113,8 @@ func commentWorker(ctx context.Context, c *lemmy.Client, replyCh chan<- replyJob
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, reply := range cfg.Replies {
|
for i, reply := range cfg.ConfigFile.Replies {
|
||||||
re := compiledRegexes[reply.Regex]
|
re := cfg.Regexes[reply.Regex]
|
||||||
if !re.MatchString(c.Comment.Content) {
|
if !re.MatchString(c.Comment.Content) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -145,7 +130,7 @@ func commentWorker(ctx context.Context, c *lemmy.Client, replyCh chan<- replyJob
|
|||||||
}
|
}
|
||||||
|
|
||||||
matches := re.FindAllStringSubmatch(c.Comment.Content, -1)
|
matches := re.FindAllStringSubmatch(c.Comment.Content, -1)
|
||||||
job.Content, err = executeTmpl(compiledTmpls[reply.Regex], TmplContext{
|
job.Content, err = executeTmpl(cfg.Tmpls[reply.Regex], TmplContext{
|
||||||
Matches: toSubmatches(matches),
|
Matches: toSubmatches(matches),
|
||||||
Type: "comment",
|
Type: "comment",
|
||||||
})
|
})
|
||||||
@ -197,8 +182,8 @@ func commentWorker(ctx context.Context, c *lemmy.Client, replyCh chan<- replyJob
|
|||||||
}
|
}
|
||||||
|
|
||||||
body := p.Post.URL.ValueOr("") + "\n\n" + p.Post.Body.ValueOr("")
|
body := p.Post.URL.ValueOr("") + "\n\n" + p.Post.Body.ValueOr("")
|
||||||
for i, reply := range cfg.Replies {
|
for i, reply := range cfg.ConfigFile.Replies {
|
||||||
re := compiledRegexes[reply.Regex]
|
re := cfg.Regexes[reply.Regex]
|
||||||
if !re.MatchString(body) {
|
if !re.MatchString(body) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -211,7 +196,7 @@ func commentWorker(ctx context.Context, c *lemmy.Client, replyCh chan<- replyJob
|
|||||||
job := replyJob{PostID: p.Post.ID}
|
job := replyJob{PostID: p.Post.ID}
|
||||||
|
|
||||||
matches := re.FindAllStringSubmatch(body, -1)
|
matches := re.FindAllStringSubmatch(body, -1)
|
||||||
job.Content, err = executeTmpl(compiledTmpls[reply.Regex], TmplContext{
|
job.Content, err = executeTmpl(cfg.Tmpls[reply.Regex], TmplContext{
|
||||||
Matches: toSubmatches(matches),
|
Matches: toSubmatches(matches),
|
||||||
Type: "post",
|
Type: "post",
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user