Switch from variable expansion to templates

This commit is contained in:
Elara 2023-01-09 16:10:05 -08:00
parent b6fb1a06e2
commit ad5b753f50
5 changed files with 77 additions and 31 deletions

View File

@ -3,7 +3,10 @@ package main
import ( import (
"net/url" "net/url"
"os" "os"
"strconv"
"text/template"
"github.com/Masterminds/sprig"
"github.com/pelletier/go-toml/v2" "github.com/pelletier/go-toml/v2"
"go.arsenm.dev/logger/log" "go.arsenm.dev/logger/log"
"go.arsenm.dev/pcre" "go.arsenm.dev/pcre"
@ -28,6 +31,7 @@ type Reply struct {
var ( var (
cfg = Config{} cfg = Config{}
compiledRegexes = map[string]*pcre.Regexp{} compiledRegexes = map[string]*pcre.Regexp{}
compiledTmpls = map[string]*template.Template{}
) )
func loadConfig(path string) error { func loadConfig(path string) error {
@ -50,7 +54,7 @@ func loadConfig(path string) error {
return err return err
} }
err = compileRegexes(cfg.Replies) err = compileReplies(cfg.Replies)
if err != nil { if err != nil {
return err return err
} }
@ -59,8 +63,8 @@ func loadConfig(path string) error {
return nil return nil
} }
func compileRegexes(replies []Reply) error { func compileReplies(replies []Reply) error {
for _, reply := range replies { for i, reply := range replies {
if _, ok := compiledRegexes[reply.Regex]; ok { if _, ok := compiledRegexes[reply.Regex]; ok {
continue continue
} }
@ -70,6 +74,16 @@ func compileRegexes(replies []Reply) error {
return err return err
} }
compiledRegexes[reply.Regex] = re compiledRegexes[reply.Regex] = re
tmpl, err := template.
New(strconv.Itoa(i)).
Funcs(tmplFuncs).
Funcs(sprig.TxtFuncMap()).
Parse(reply.Msg)
if err != nil {
return err
}
compiledTmpls[reply.Regex] = tmpl
} }
return nil return nil
} }

10
go.mod
View File

@ -2,9 +2,10 @@ module go.arsenm.dev/lemmy-reply-bot
go 1.19 go 1.19
replace go.arsenm.dev/go-lemmy => /home/arsen/Code/go-lemmy //replace go.arsenm.dev/go-lemmy => /home/arsen/Code/go-lemmy
require ( require (
github.com/Masterminds/sprig v2.22.0+incompatible
github.com/pelletier/go-toml/v2 v2.0.6 github.com/pelletier/go-toml/v2 v2.0.6
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/vmihailenco/msgpack/v5 v5.3.5 github.com/vmihailenco/msgpack/v5 v5.3.5
@ -14,15 +15,22 @@ require (
) )
require ( require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/cenkalti/backoff/v4 v4.2.0 // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/gookit/color v1.5.1 // indirect github.com/gookit/color v1.5.1 // indirect
github.com/gorilla/websocket v1.4.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/sys v0.1.0 // indirect golang.org/x/sys v0.1.0 // indirect
modernc.org/libc v1.16.8 // indirect modernc.org/libc v1.16.8 // indirect
modernc.org/mathutil v1.4.1 // indirect modernc.org/mathutil v1.4.1 // indirect

16
go.sum
View File

@ -1,3 +1,9 @@
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -15,10 +21,18 @@ github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ=
github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM= github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -49,6 +63,7 @@ go.arsenm.dev/pcre v0.0.0-20220530205550-74594f6c8b0e h1:4XwLmFDvAKt7ZvS3E3hD2R+
go.arsenm.dev/pcre v0.0.0-20220530205550-74594f6c8b0e/go.mod h1:c/E0D60A6rRLoDLh6mLUdFV9gxyth+CnXnqGHos2CAQ= go.arsenm.dev/pcre v0.0.0-20220530205550-74594f6c8b0e/go.mod h1:c/E0D60A6rRLoDLh6mLUdFV9gxyth+CnXnqGHos2CAQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -76,6 +91,7 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=

38
main.go
View File

@ -2,12 +2,11 @@ package main
import ( import (
"context" "context"
"fmt"
"os" "os"
"os/signal" "os/signal"
"strconv"
"strings" "strings"
"syscall" "syscall"
"text/template"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/vmihailenco/msgpack/v5" "github.com/vmihailenco/msgpack/v5"
@ -104,22 +103,12 @@ func commentWorker(ctx context.Context, c *lemmy.WSClient, replyCh chan<- replyJ
PostID: cr.CommentView.Comment.PostID, PostID: cr.CommentView.Comment.PostID,
} }
matches := re.FindStringSubmatch(cr.CommentView.Comment.Content) matches := re.FindAllStringSubmatch(cr.CommentView.Comment.Content, -1)
job.Content = expandStr(reply.Msg, func(s string) string { job.Content, err = executeTmpl(compiledTmpls[reply.Regex], matches)
i, err := strconv.Atoi(s) if err != nil {
if err != nil { log.Warn("Error while executing template").Err(err).Send()
log.Debug("Message variable is not an integer, returning empty string").Str("var", s).Send() continue
return "" }
}
if i+1 > len(matches) {
log.Debug("Message variable exceeds match length").Int("length", len(matches)).Int("var", i).Send()
return ""
}
log.Debug("Message variable found, returning").Int("var", i).Str("found", matches[i]).Send()
return matches[i]
})
replyCh <- job replyCh <- job
@ -127,7 +116,6 @@ func commentWorker(ctx context.Context, c *lemmy.WSClient, replyCh chan<- replyJ
} }
} }
case err := <-c.Errors(): case err := <-c.Errors():
fmt.Printf("%T\n", err)
log.Warn("Lemmy client error").Err(err).Send() log.Warn("Lemmy client error").Err(err).Send()
case <-ctx.Done(): case <-ctx.Done():
repliedStore, err := os.Create("replied.bin") repliedStore, err := os.Create("replied.bin")
@ -176,14 +164,10 @@ func commentReplyWorker(ctx context.Context, c *lemmy.WSClient, ch <-chan replyJ
} }
} }
func expandStr(s string, mapping func(string) string) string { func executeTmpl(tmpl *template.Template, matches [][]string) (string, error) {
s = strings.ReplaceAll(s, "$$", "${_escaped_dollar_symbol}") sb := &strings.Builder{}
return os.Expand(s, func(s string) string { err := tmpl.Execute(sb, matches)
if s == "_escaped_dollar_symbol" { return sb.String(), err
return "$"
}
return mapping(s)
})
} }
func joinAll(c *lemmy.WSClient) { func joinAll(c *lemmy.WSClient) {

24
tmpl.go Normal file
View File

@ -0,0 +1,24 @@
package main
import "text/template"
var tmplFuncs = template.FuncMap{
"match": func(matches [][]string, i int, j int) string {
if len(matches) <= i {
return ""
}
if len(matches[i]) <= j {
return ""
}
return matches[i][j]
},
"item": func(items []string, i int) string {
if len(items) <= i {
return ""
}
return items[i]
},
}