Allow plugins to register template functions

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2021-08-19 16:40:34 +02:00
parent b47ffbfff7
commit 89de50d035
Signed by: luzifer
GPG key ID: 0066F03ED215AD7D
6 changed files with 37 additions and 27 deletions

View file

@ -33,9 +33,10 @@ func init() {
func getRegistrationArguments() plugins.RegistrationArguments {
return plugins.RegistrationArguments{
FormatMessage: formatMessage,
GetLogger: func(moduleName string) *log.Entry { return log.WithField("module", moduleName) },
RegisterActor: registerAction,
SendMessage: sendMessage,
FormatMessage: formatMessage,
GetLogger: func(moduleName string) *log.Entry { return log.WithField("module", moduleName) },
RegisterActor: registerAction,
RegisterTemplateFunction: tplFuncs.Register,
SendMessage: sendMessage,
}
}

View file

@ -9,21 +9,19 @@ import (
korvike "github.com/Luzifer/korvike/functions"
"github.com/Luzifer/twitch-bot/plugins"
"github.com/go-irc/irc"
log "github.com/sirupsen/logrus"
)
var tplFuncs = newTemplateFuncProvider()
type (
templateFuncGetter func(*irc.Message, *plugins.Rule, map[string]interface{}) interface{}
templateFuncProvider struct {
funcs map[string]templateFuncGetter
lock *sync.RWMutex
}
)
type templateFuncProvider struct {
funcs map[string]plugins.TemplateFuncGetter
lock *sync.RWMutex
}
func newTemplateFuncProvider() *templateFuncProvider {
out := &templateFuncProvider{
funcs: map[string]templateFuncGetter{},
funcs: map[string]plugins.TemplateFuncGetter{},
lock: new(sync.RWMutex),
}
@ -43,28 +41,28 @@ func (t *templateFuncProvider) GetFuncMap(m *irc.Message, r *plugins.Rule, field
return out
}
func (t *templateFuncProvider) Register(name string, fg templateFuncGetter) {
func (t *templateFuncProvider) Register(name string, fg plugins.TemplateFuncGetter) {
t.lock.Lock()
defer t.lock.Unlock()
t.funcs[name] = fg
}
if _, ok := t.funcs[name]; ok {
log.Fatalf("Duplicate registration of %q template function", name)
}
func genericTemplateFunctionGetter(f interface{}) templateFuncGetter {
return func(*irc.Message, *plugins.Rule, map[string]interface{}) interface{} { return f }
t.funcs[name] = fg
}
func init() {
// Register Korvike functions
for n, f := range korvike.GetFunctionMap() {
tplFuncs.Register(n, genericTemplateFunctionGetter(f))
tplFuncs.Register(n, plugins.GenericTemplateFunctionGetter(f))
}
tplFuncs.Register("toLower", genericTemplateFunctionGetter(strings.ToLower))
tplFuncs.Register("toUpper", genericTemplateFunctionGetter(strings.ToUpper))
tplFuncs.Register("followDate", genericTemplateFunctionGetter(func(from, to string) (time.Time, error) { return twitchClient.GetFollowDate(from, to) }))
tplFuncs.Register("concat", genericTemplateFunctionGetter(func(delim string, parts ...string) string { return strings.Join(parts, delim) }))
tplFuncs.Register("variable", genericTemplateFunctionGetter(func(name string, defVal ...string) string {
tplFuncs.Register("toLower", plugins.GenericTemplateFunctionGetter(strings.ToLower))
tplFuncs.Register("toUpper", plugins.GenericTemplateFunctionGetter(strings.ToUpper))
tplFuncs.Register("followDate", plugins.GenericTemplateFunctionGetter(func(from, to string) (time.Time, error) { return twitchClient.GetFollowDate(from, to) }))
tplFuncs.Register("concat", plugins.GenericTemplateFunctionGetter(func(delim string, parts ...string) string { return strings.Join(parts, delim) }))
tplFuncs.Register("variable", plugins.GenericTemplateFunctionGetter(func(name string, defVal ...string) string {
value := store.GetVariable(name)
if value == "" && len(defVal) > 0 {
return defVal[0]

View file

@ -20,7 +20,7 @@ func init() {
}
})
tplFuncs.Register("counterValue", genericTemplateFunctionGetter(func(name string, _ ...string) int64 {
tplFuncs.Register("counterValue", plugins.GenericTemplateFunctionGetter(func(name string, _ ...string) int64 {
return store.GetCounterValue(name)
}))
}

View file

@ -20,7 +20,7 @@ func init() {
}
})
tplFuncs.Register("fixUsername", genericTemplateFunctionGetter(func(username string) string { return strings.TrimLeft(username, "@#") }))
tplFuncs.Register("fixUsername", plugins.GenericTemplateFunctionGetter(func(username string) string { return strings.TrimLeft(username, "@#") }))
tplFuncs.Register("group", func(m *irc.Message, r *plugins.Rule, fields map[string]interface{}) interface{} {
return func(idx int) (string, error) {

View file

@ -2,10 +2,12 @@ package main
import (
"strings"
"github.com/Luzifer/twitch-bot/plugins"
)
func init() {
tplFuncs.Register("displayName", genericTemplateFunctionGetter(func(username string, v ...string) (string, error) {
tplFuncs.Register("displayName", plugins.GenericTemplateFunctionGetter(func(username string, v ...string) (string, error) {
displayName, err := twitchClient.GetDisplayNameForUser(strings.TrimLeft(username, "#"))
if len(v) > 0 && (err != nil || displayName == "") {
return v[0], nil
@ -14,7 +16,7 @@ func init() {
return displayName, err
}))
tplFuncs.Register("recentGame", genericTemplateFunctionGetter(func(username string, v ...string) (string, error) {
tplFuncs.Register("recentGame", plugins.GenericTemplateFunctionGetter(func(username string, v ...string) (string, error) {
game, _, err := twitchClient.GetRecentStreamInfo(strings.TrimLeft(username, "#"))
if len(v) > 0 && (err != nil || game == "") {
return v[0], nil

View file

@ -36,9 +36,18 @@ type (
GetLogger LoggerCreationFunc
// RegisterActor is used to register a new IRC rule-actor implementing the Actor interface
RegisterActor ActorRegistrationFunc
// RegisterTemplateFunction can be used to register a new template functions
RegisterTemplateFunction TemplateFuncRegister
// SendMessage can be used to send a message not triggered by an event
SendMessage SendMessageFunc
}
SendMessageFunc func(*irc.Message) error
TemplateFuncGetter func(*irc.Message, *Rule, map[string]interface{}) interface{}
TemplateFuncRegister func(name string, fg TemplateFuncGetter)
)
func GenericTemplateFunctionGetter(f interface{}) TemplateFuncGetter {
return func(*irc.Message, *Rule, map[string]interface{}) interface{} { return f }
}