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

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

View file

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

View file

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

View file

@ -36,9 +36,18 @@ type (
GetLogger LoggerCreationFunc GetLogger LoggerCreationFunc
// RegisterActor is used to register a new IRC rule-actor implementing the Actor interface // RegisterActor is used to register a new IRC rule-actor implementing the Actor interface
RegisterActor ActorRegistrationFunc 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 can be used to send a message not triggered by an event
SendMessage SendMessageFunc SendMessage SendMessageFunc
} }
SendMessageFunc func(*irc.Message) error 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 }
}