mirror of
https://github.com/Luzifer/twitch-bot.git
synced 2024-11-09 08:40:01 +00:00
Extract template functions into registry
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
29fd5f25f5
commit
024980ee14
5 changed files with 155 additions and 71 deletions
64
functions.go
Normal file
64
functions.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
|
||||
korvike "github.com/Luzifer/korvike/functions"
|
||||
"github.com/go-irc/irc"
|
||||
)
|
||||
|
||||
var tplFuncs = newTemplateFuncProvider()
|
||||
|
||||
type (
|
||||
templateFuncGetter func(*irc.Message, *rule, map[string]interface{}) interface{}
|
||||
templateFuncProvider struct {
|
||||
funcs map[string]templateFuncGetter
|
||||
lock *sync.RWMutex
|
||||
}
|
||||
)
|
||||
|
||||
func newTemplateFuncProvider() *templateFuncProvider {
|
||||
out := &templateFuncProvider{
|
||||
funcs: map[string]templateFuncGetter{},
|
||||
lock: new(sync.RWMutex),
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (t *templateFuncProvider) GetFuncMap(m *irc.Message, r *rule, fields map[string]interface{}) template.FuncMap {
|
||||
t.lock.RLock()
|
||||
defer t.lock.RUnlock()
|
||||
|
||||
out := make(template.FuncMap)
|
||||
|
||||
for n, fg := range t.funcs {
|
||||
out[n] = fg(m, r, fields)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (t *templateFuncProvider) Register(name string, fg templateFuncGetter) {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
|
||||
t.funcs[name] = fg
|
||||
}
|
||||
|
||||
func genericTemplateFunctionGetter(f interface{}) templateFuncGetter {
|
||||
return func(*irc.Message, *rule, map[string]interface{}) interface{} { return f }
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Register Korvike functions
|
||||
for n, f := range korvike.GetFunctionMap() {
|
||||
tplFuncs.Register(n, genericTemplateFunctionGetter(f))
|
||||
}
|
||||
|
||||
tplFuncs.Register("toLower", genericTemplateFunctionGetter(strings.ToLower))
|
||||
tplFuncs.Register("toUpper", genericTemplateFunctionGetter(strings.ToUpper))
|
||||
tplFuncs.Register("followDate", genericTemplateFunctionGetter(twitch.GetFollowDate))
|
||||
}
|
25
functions_counter.go
Normal file
25
functions_counter.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-irc/irc"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
tplFuncs.Register("channelCounter", func(m *irc.Message, r *rule, fields map[string]interface{}) interface{} {
|
||||
return func(name string) (string, error) {
|
||||
channel, ok := fields["channel"].(string)
|
||||
if !ok {
|
||||
return "", errors.New("channel not available")
|
||||
}
|
||||
|
||||
return strings.Join([]string{channel, name}, ":"), nil
|
||||
}
|
||||
})
|
||||
|
||||
tplFuncs.Register("counterValue", genericTemplateFunctionGetter(func(name string, _ ...string) int64 {
|
||||
return store.GetCounterValue(name)
|
||||
}))
|
||||
}
|
41
functions_irc.go
Normal file
41
functions_irc.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-irc/irc"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
tplFuncs.Register("arg", func(m *irc.Message, r *rule, fields map[string]interface{}) interface{} {
|
||||
return func(arg int) (string, error) {
|
||||
msgParts := strings.Split(m.Trailing(), " ")
|
||||
if len(msgParts) <= arg {
|
||||
return "", errors.New("argument not found")
|
||||
}
|
||||
|
||||
return msgParts[arg], nil
|
||||
}
|
||||
})
|
||||
|
||||
tplFuncs.Register("fixUsername", genericTemplateFunctionGetter(func(username string) string { return strings.TrimLeft(username, "@#") }))
|
||||
|
||||
tplFuncs.Register("group", func(m *irc.Message, r *rule, fields map[string]interface{}) interface{} {
|
||||
return func(idx int) (string, error) {
|
||||
fields := r.matchMessage.FindStringSubmatch(m.Trailing())
|
||||
if len(fields) <= idx {
|
||||
return "", errors.New("group not found")
|
||||
}
|
||||
|
||||
return fields[idx], nil
|
||||
}
|
||||
})
|
||||
|
||||
tplFuncs.Register("tag", func(m *irc.Message, r *rule, fields map[string]interface{}) interface{} {
|
||||
return func(tag string) string {
|
||||
s, _ := m.GetTag(tag)
|
||||
return s
|
||||
}
|
||||
})
|
||||
}
|
16
functions_twitch.go
Normal file
16
functions_twitch.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func init() {
|
||||
tplFuncs.Register("recentGame", genericTemplateFunctionGetter(func(username string, v ...string) (string, error) {
|
||||
game, _, err := twitch.GetRecentStreamInfo(strings.TrimLeft(username, "#"))
|
||||
if err != nil && len(v) > 0 {
|
||||
return v[0], nil
|
||||
}
|
||||
|
||||
return game, err
|
||||
}))
|
||||
}
|
|
@ -2,85 +2,14 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
korvike "github.com/Luzifer/korvike/functions"
|
||||
|
||||
"github.com/go-irc/irc"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func formatMessage(tplString string, m *irc.Message, r *rule, fields map[string]interface{}) (string, error) {
|
||||
// Create anonymous functions in current context in order to access function variables
|
||||
messageFunctions := make(template.FuncMap)
|
||||
for n, f := range korvike.GetFunctionMap() {
|
||||
messageFunctions[n] = f
|
||||
}
|
||||
|
||||
// Generic functions
|
||||
messageFunctions["toLower"] = strings.ToLower
|
||||
messageFunctions["toUpper"] = strings.ToUpper
|
||||
messageFunctions["followDate"] = twitch.GetFollowDate
|
||||
|
||||
// Message specific functions
|
||||
messageFunctions["arg"] = func(arg int) (string, error) {
|
||||
msgParts := strings.Split(m.Trailing(), " ")
|
||||
if len(msgParts) <= arg {
|
||||
return "", errors.New("argument not found")
|
||||
}
|
||||
|
||||
return msgParts[arg], nil
|
||||
}
|
||||
|
||||
messageFunctions["channelCounter"] = func(name string) (string, error) {
|
||||
channel, ok := fields["channel"].(string)
|
||||
if !ok {
|
||||
return "", errors.New("channel not available")
|
||||
}
|
||||
|
||||
return strings.Join([]string{channel, name}, ":"), nil
|
||||
}
|
||||
|
||||
messageFunctions["counterValue"] = func(name string, _ ...string) int64 {
|
||||
return store.GetCounterValue(name)
|
||||
}
|
||||
|
||||
messageFunctions["fixUsername"] = func(username string) string { return strings.TrimLeft(username, "@#") }
|
||||
|
||||
messageFunctions["group"] = func(idx int) (string, error) {
|
||||
fields := r.matchMessage.FindStringSubmatch(m.Trailing())
|
||||
if len(fields) <= idx {
|
||||
return "", errors.New("group not found")
|
||||
}
|
||||
|
||||
return fields[idx], nil
|
||||
}
|
||||
|
||||
messageFunctions["recentGame"] = func(username string, v ...string) (string, error) {
|
||||
game, _, err := twitch.GetRecentStreamInfo(strings.TrimLeft(username, "#"))
|
||||
if err != nil && len(v) > 0 {
|
||||
return v[0], nil
|
||||
}
|
||||
|
||||
return game, err
|
||||
}
|
||||
|
||||
messageFunctions["tag"] = func(tag string) string {
|
||||
s, _ := m.GetTag(tag)
|
||||
return s
|
||||
}
|
||||
|
||||
// Parse and execute template
|
||||
tpl, err := template.
|
||||
New(tplString).
|
||||
Funcs(messageFunctions).
|
||||
Parse(tplString)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "parse template")
|
||||
}
|
||||
|
||||
if fields == nil {
|
||||
fields = map[string]interface{}{}
|
||||
}
|
||||
|
@ -93,6 +22,15 @@ func formatMessage(tplString string, m *irc.Message, r *rule, fields map[string]
|
|||
fields["channel"] = m.Params[0]
|
||||
}
|
||||
|
||||
// Parse and execute template
|
||||
tpl, err := template.
|
||||
New(tplString).
|
||||
Funcs(tplFuncs.GetFuncMap(m, r, fields)).
|
||||
Parse(tplString)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "parse template")
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
err = tpl.Execute(buf, fields)
|
||||
|
||||
|
|
Loading…
Reference in a new issue