babbler: Add all users in chan, add cfg'd users

Also misc small updates to the mock object for easier config usage
This commit is contained in:
Chris Sexton 2016-05-10 21:15:52 -04:00
parent 8c5a446b75
commit e6324ad5a2
6 changed files with 82 additions and 41 deletions

View File

@ -16,11 +16,13 @@ type MockBot struct {
mock.Mock mock.Mock
db *sqlx.DB db *sqlx.DB
Cfg config.Config
Messages []string Messages []string
Actions []string Actions []string
} }
func (mb *MockBot) Config() *config.Config { return &config.Config{} } func (mb *MockBot) Config() *config.Config { return &mb.Cfg }
func (mb *MockBot) DBVersion() int64 { return 1 } func (mb *MockBot) DBVersion() int64 { return 1 }
func (mb *MockBot) DB() *sqlx.DB { return mb.db } func (mb *MockBot) DB() *sqlx.DB { return mb.db }
func (mb *MockBot) Who(string) []user.User { return []user.User{} } func (mb *MockBot) Who(string) []user.User { return []user.User{} }

View File

@ -64,6 +64,9 @@ type Config struct {
QuoteTime int QuoteTime int
StartupFact string StartupFact string
} }
Babbler struct {
DefaultUsers []string
}
} }
// Readconfig loads the config data out of a JSON file located in cfile // Readconfig loads the config data out of a JSON file located in cfile

View File

@ -58,5 +58,10 @@
"QuoteTime": 1, "QuoteTime": 1,
"StartupFact": "speed test", "StartupFact": "speed test",
"MinLen": 5 "MinLen": 5
},
"Babbler": {
"DefaultUsers": [
"seabass"
]
} }
} }

View File

@ -8,15 +8,17 @@ import (
"math/rand" "math/rand"
"strings" "strings"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
"github.com/velour/catbase/bot" "github.com/velour/catbase/bot"
"github.com/velour/catbase/bot/msg" "github.com/velour/catbase/bot/msg"
"github.com/velour/catbase/bot/user"
"github.com/velour/catbase/config"
) )
type BabblerPlugin struct { type BabblerPlugin struct {
Bot bot.Bot Bot bot.Bot
db *sqlx.DB db *sqlx.DB
config *config.Config
babblers map[string]*babbler babblers map[string]*babbler
} }
@ -40,27 +42,45 @@ func New(bot bot.Bot) *BabblerPlugin {
plugin := &BabblerPlugin{ plugin := &BabblerPlugin{
Bot: bot, Bot: bot,
db: bot.DB(), db: bot.DB(),
config: bot.Config(),
babblers: map[string]*babbler{}, babblers: map[string]*babbler{},
} }
// this who string isn't escaped, just sooo, you know.
babbler, err := getMarkovChain(plugin.db, "seabass")
if err == nil {
plugin.babblers["seabass"] = babbler
} else {
plugin.babblers["seabass"] = newBabbler()
}
return plugin return plugin
} }
func (p *BabblerPlugin) makeBabbler(newUser user.User) {
name := newUser.Name
babbler, err := getMarkovChain(p.db, name)
if err == nil {
p.babblers[name] = babbler
} else {
p.babblers[name] = newBabbler()
}
}
func (p *BabblerPlugin) makeBabblers(newUser user.User) {
users := p.Bot.Who(p.config.MainChannel)
users = append(users, newUser)
for _, name := range p.config.Babbler.DefaultUsers {
users = append(users, user.New(name))
}
for _, u := range users {
p.makeBabbler(u)
}
}
func (p *BabblerPlugin) Message(message msg.Message) bool { func (p *BabblerPlugin) Message(message msg.Message) bool {
if len(p.babblers) == 0 {
p.makeBabblers(*message.User)
} else if _, ok := p.babblers[message.User.Name]; !ok {
p.makeBabbler(*message.User)
}
lowercase := strings.ToLower(message.Body) lowercase := strings.ToLower(message.Body)
tokens := strings.Fields(lowercase) tokens := strings.Fields(lowercase)
if _, ok := p.babblers[message.User.Name]; ok {
addToMarkovChain(p.babblers[message.User.Name], lowercase) addToMarkovChain(p.babblers[message.User.Name], lowercase)
}
if len(tokens) == 4 && strings.Contains(lowercase, "initialize babbler for ") { if len(tokens) == 4 && strings.Contains(lowercase, "initialize babbler for ") {
who := tokens[len(tokens)-1] who := tokens[len(tokens)-1]
@ -71,20 +91,24 @@ func (p *BabblerPlugin) Message(message msg.Message) bool {
} else { } else {
p.babblers[who] = newBabbler() p.babblers[who] = newBabbler()
} }
p.Bot.SendMessage(message.Channel, "Okay.")
return true
} }
} }
if len(tokens) == 2 && tokens[1] == "says" { if len(tokens) == 2 && tokens[1] == "says" {
if _, ok := p.babblers[tokens[0]]; ok { saying := p.babble(tokens[0])
p.Bot.SendMessage(message.Channel, p.babble(tokens[0])) if saying == "" {
return true p.Bot.SendMessage(message.Channel, "Ze ain't said nothin'")
} }
p.Bot.SendMessage(message.Channel, saying)
return true
} }
return false return false
} }
func (p *BabblerPlugin) Help(channel string, parts []string) { func (p *BabblerPlugin) Help(channel string, parts []string) {
p.Bot.SendMessage(channel, "seabass says") p.Bot.SendMessage(channel, "initialize babbler for seabass\n\nseabass says")
} }
func (p *BabblerPlugin) Event(kind string, message msg.Message) bool { func (p *BabblerPlugin) Event(kind string, message msg.Message) bool {

View File

@ -28,10 +28,12 @@ func makeMessage(payload string) msg.Message {
func TestBabbler(t *testing.T) { func TestBabbler(t *testing.T) {
mb := bot.NewMockBot() mb := bot.NewMockBot()
c := New(mb) c := New(mb)
c.config.Babbler.DefaultUsers = []string{"seabass"}
assert.NotNil(t, c) assert.NotNil(t, c)
seabass := makeMessage("This is a message") seabass := makeMessage("This is a message")
seabass.User = &user.User{Name: "seabass"} seabass.User = &user.User{Name: "seabass"}
res := c.Message(seabass) res := c.Message(seabass)
assert.Len(t, c.babblers, 1)
seabass.Body = "This is another message" seabass.Body = "This is another message"
res = c.Message(seabass) res = c.Message(seabass)
seabass.Body = "This is a long message" seabass.Body = "This is a long message"

View File

@ -258,9 +258,14 @@ func (s *Slack) Who(id string) []string {
u := s.url + "channels.info" u := s.url + "channels.info"
resp, err := http.PostForm(u, resp, err := http.PostForm(u,
url.Values{"token": {s.config.Slack.Token}, "channel": {id}}) url.Values{"token": {s.config.Slack.Token}, "channel": {id}})
if err != nil || resp.StatusCode != 200 { if err != nil {
log.Printf("Error posting user info request: %d %s", log.Printf("Error posting user info request: %s",
resp.StatusCode, err) err)
return []string{}
}
if resp.StatusCode != 200 {
log.Printf("Error posting user info request: %d",
resp.StatusCode)
return []string{} return []string{}
} }
defer resp.Body.Close() defer resp.Body.Close()