From 89de50d035e25af10b82e4b1b183dd8e19fbe41a Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Thu, 19 Aug 2021 16:40:34 +0200 Subject: [PATCH] Allow plugins to register template functions Signed-off-by: Knut Ahlers --- action_core.go | 9 +++++---- functions.go | 36 +++++++++++++++++------------------- functions_counter.go | 2 +- functions_irc.go | 2 +- functions_twitch.go | 6 ++++-- plugins/interface.go | 9 +++++++++ 6 files changed, 37 insertions(+), 27 deletions(-) diff --git a/action_core.go b/action_core.go index 57c9676..4852f26 100644 --- a/action_core.go +++ b/action_core.go @@ -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, } } diff --git a/functions.go b/functions.go index 639a1d7..60178c7 100644 --- a/functions.go +++ b/functions.go @@ -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] diff --git a/functions_counter.go b/functions_counter.go index 1e4b1b0..2e441fc 100644 --- a/functions_counter.go +++ b/functions_counter.go @@ -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) })) } diff --git a/functions_irc.go b/functions_irc.go index f4a5828..381bd2a 100644 --- a/functions_irc.go +++ b/functions_irc.go @@ -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) { diff --git a/functions_twitch.go b/functions_twitch.go index fa37160..1b8cef4 100644 --- a/functions_twitch.go +++ b/functions_twitch.go @@ -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 diff --git a/plugins/interface.go b/plugins/interface.go index a4ea36c..dfd5c67 100644 --- a/plugins/interface.go +++ b/plugins/interface.go @@ -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 } +}