mirror of https://github.com/velour/catbase.git
Added "what was that?", merged remember and factoid a bit, added fields to factoids, todo: stats on factoids, documentation.
This commit is contained in:
parent
0970ee980f
commit
89072fafb4
|
@ -14,18 +14,24 @@ import (
|
|||
// This is a factoid plugin to serve as an example and quick copy/paste for new plugins.
|
||||
|
||||
// factoid stores info about our factoid for lookup and later interaction
|
||||
type factoid struct {
|
||||
type Factoid struct {
|
||||
_id bson.ObjectId `bson:"_id"`
|
||||
Id int
|
||||
Trigger string
|
||||
Operator string
|
||||
FullText string
|
||||
Action string
|
||||
CreatedBy string
|
||||
DateCreated time.Time
|
||||
LastAccessed time.Time
|
||||
AccessCount int
|
||||
}
|
||||
|
||||
type FactoidPlugin struct {
|
||||
Bot *bot.Bot
|
||||
Coll *mgo.Collection
|
||||
NotFound []string
|
||||
LastFact Factoid
|
||||
}
|
||||
|
||||
// NewFactoidPlugin creates a new FactoidPlugin with the Plugin interface
|
||||
|
@ -43,6 +49,9 @@ func NewFactoidPlugin(bot *bot.Bot) *FactoidPlugin {
|
|||
},
|
||||
}
|
||||
p.LoadData()
|
||||
for _, channel := range bot.Config.Channels {
|
||||
go p.factTimer(channel)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
|
@ -68,19 +77,28 @@ func (p *FactoidPlugin) learnFact(message bot.Message, trigger, operator, fact s
|
|||
return false
|
||||
}
|
||||
|
||||
newfact := factoid{
|
||||
Id: 0,
|
||||
var funcres bson.M
|
||||
err := p.Bot.Db.Run(bson.M{"eval": "return counter(\"factoid\");"}, &funcres)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
id := int(funcres["retval"].(float64))
|
||||
|
||||
newfact := Factoid{
|
||||
_id: bson.NewObjectId(),
|
||||
Id: id,
|
||||
Trigger: trigger,
|
||||
Operator: operator,
|
||||
FullText: full,
|
||||
Action: fact,
|
||||
CreatedBy: message.User.Name,
|
||||
}
|
||||
p.Coll.Insert(newfact)
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *FactoidPlugin) findTrigger(message string) (bool, *factoid) {
|
||||
var results []factoid
|
||||
func (p *FactoidPlugin) findTrigger(message string) (bool, *Factoid) {
|
||||
var results []Factoid
|
||||
iter := p.Coll.Find(bson.M{"trigger": strings.ToLower(message)}).Iter()
|
||||
err := iter.All(&results)
|
||||
if err != nil {
|
||||
|
@ -96,9 +114,7 @@ func (p *FactoidPlugin) findTrigger(message string) (bool, *factoid) {
|
|||
return true, &fact
|
||||
}
|
||||
|
||||
func (p *FactoidPlugin) trigger(message bot.Message) bool {
|
||||
if len(message.Body) > 4 || message.Command {
|
||||
if ok, fact := p.findTrigger(message.Body); ok {
|
||||
func (p *FactoidPlugin) sayFact(message bot.Message, fact Factoid) {
|
||||
msg := p.Bot.Filter(message, fact.FullText)
|
||||
for i, m := 0, strings.Split(msg, "$and"); i < len(m) && i < 4; i++ {
|
||||
msg := strings.TrimSpace(m[i])
|
||||
|
@ -112,6 +128,14 @@ func (p *FactoidPlugin) trigger(message bot.Message) bool {
|
|||
p.Bot.SendMessage(message.Channel, msg)
|
||||
}
|
||||
}
|
||||
|
||||
p.LastFact = fact
|
||||
}
|
||||
|
||||
func (p *FactoidPlugin) trigger(message bot.Message) bool {
|
||||
if len(message.Body) > 4 || message.Command || message.Body == "..." {
|
||||
if ok, fact := p.findTrigger(message.Body); ok {
|
||||
p.sayFact(message, *fact)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -126,6 +150,13 @@ func (p *FactoidPlugin) Message(message bot.Message) bool {
|
|||
// This bot does not reply to anything
|
||||
body := strings.TrimSpace(message.Body)
|
||||
|
||||
if strings.ToLower(message.Body) == "what was that?" {
|
||||
fact := p.LastFact
|
||||
msg := fmt.Sprintf("That was (#%d) '%s <%s> %s'", fact.Id, fact.Trigger, fact.Operator, fact.Action)
|
||||
p.Bot.SendMessage(message.Channel, msg)
|
||||
return true
|
||||
}
|
||||
|
||||
// This plugin has no business with normal messages
|
||||
if !message.Command {
|
||||
// look for any triggers in the db matching this message
|
||||
|
@ -193,3 +224,40 @@ func (p *FactoidPlugin) Help(channel string, parts []string) {
|
|||
func (p *FactoidPlugin) Event(kind string, message bot.Message) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *FactoidPlugin) randomFact() *Factoid {
|
||||
var results []Factoid
|
||||
iter := p.Coll.Find(bson.M{}).Iter()
|
||||
err := iter.All(&results)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
nfacts := len(results)
|
||||
if nfacts == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
fact := results[rand.Intn(nfacts)]
|
||||
return &fact
|
||||
}
|
||||
|
||||
func (p *FactoidPlugin) factTimer(channel string) {
|
||||
for {
|
||||
time.Sleep(time.Duration(p.Bot.Config.QuoteTime) * time.Minute)
|
||||
chance := 1.0 / p.Bot.Config.QuoteChance
|
||||
if rand.Intn(int(chance)) == 0 {
|
||||
fact := p.randomFact()
|
||||
if fact == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// we need to fabricate a message so that bot.Filter can operate
|
||||
message := bot.Message{
|
||||
User: &p.Bot.Users[rand.Intn(len(p.Bot.Users))],
|
||||
Channel: channel,
|
||||
}
|
||||
p.sayFact(message, *fact)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,6 @@ import (
|
|||
|
||||
// This is a skeleton plugin to serve as an example and quick copy/paste for new plugins.
|
||||
|
||||
type userRemember struct {
|
||||
Nick string
|
||||
Message string
|
||||
Date time.Time
|
||||
}
|
||||
|
||||
type RememberPlugin struct {
|
||||
Bot *bot.Bot
|
||||
Coll *mgo.Collection
|
||||
|
@ -31,9 +25,9 @@ func NewRememberPlugin(b *bot.Bot) *RememberPlugin {
|
|||
Log: make(map[string][]bot.Message),
|
||||
}
|
||||
p.LoadData()
|
||||
for _, channel := range b.Config.Channels {
|
||||
go p.quoteTimer(channel)
|
||||
}
|
||||
// for _, channel := range b.Config.Channels {
|
||||
// go p.quoteTimer(channel)
|
||||
// }
|
||||
return &p
|
||||
}
|
||||
|
||||
|
@ -51,6 +45,7 @@ func (p *RememberPlugin) Message(message bot.Message) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
user := message.User
|
||||
parts := strings.Fields(message.Body)
|
||||
if message.Command && len(parts) >= 3 && parts[0] == "remember" {
|
||||
// we have a remember!
|
||||
|
@ -58,7 +53,7 @@ func (p *RememberPlugin) Message(message bot.Message) bool {
|
|||
nick := parts[1]
|
||||
snip := strings.Join(parts[2:], " ")
|
||||
|
||||
if nick == message.User.Name {
|
||||
if nick == user.Name {
|
||||
msg := fmt.Sprintf("Don't try to quote yourself, %s.", nick)
|
||||
p.Bot.SendMessage(message.Channel, msg)
|
||||
return true
|
||||
|
@ -66,8 +61,6 @@ func (p *RememberPlugin) Message(message bot.Message) bool {
|
|||
|
||||
for i := len(p.Log[message.Channel]) - 1; i >= 0; i-- {
|
||||
entry := p.Log[message.Channel][i]
|
||||
// find the entry we want
|
||||
fmt.Printf("Comparing '%s' to '%s'\n", entry.Raw, snip)
|
||||
if entry.User.Name == nick && strings.Contains(entry.Body, snip) {
|
||||
// insert new remember entry
|
||||
var msg string
|
||||
|
@ -78,12 +71,20 @@ func (p *RememberPlugin) Message(message bot.Message) bool {
|
|||
} else {
|
||||
msg = fmt.Sprintf("<%s> %s", entry.User.Name, entry.Raw)
|
||||
}
|
||||
u := userRemember{
|
||||
Nick: entry.User.Name,
|
||||
Message: msg,
|
||||
Date: time.Now(),
|
||||
|
||||
trigger := fmt.Sprintf("%s quotes", entry.User.Name)
|
||||
|
||||
fact := Factoid{
|
||||
Trigger: trigger,
|
||||
Operator: "<reply>",
|
||||
FullText: msg,
|
||||
Action: msg,
|
||||
CreatedBy: user.Name,
|
||||
DateCreated: time.Now(),
|
||||
LastAccessed: time.Now(),
|
||||
AccessCount: 0,
|
||||
}
|
||||
p.Coll.Insert(u)
|
||||
p.Coll.Insert(fact)
|
||||
|
||||
// sorry, not creative with names so we're reusing msg
|
||||
msg = fmt.Sprintf("Okay, %s, remembering '%s'.",
|
||||
|
@ -103,7 +104,7 @@ func (p *RememberPlugin) Message(message bot.Message) bool {
|
|||
// than the fact that the Plugin interface demands it exist. This may be deprecated at a later
|
||||
// date.
|
||||
func (p *RememberPlugin) LoadData() {
|
||||
p.Coll = p.Bot.Db.C("remember")
|
||||
p.Coll = p.Bot.Db.C("factoid")
|
||||
rand.Seed(time.Now().Unix())
|
||||
}
|
||||
|
||||
|
@ -115,21 +116,18 @@ func (p *RememberPlugin) Help(channel string, parts []string) {
|
|||
p.Bot.SendMessage(channel, msg)
|
||||
}
|
||||
|
||||
func (p *RememberPlugin) record(nick, msg string) {
|
||||
message := userRemember{
|
||||
Nick: nick,
|
||||
Message: msg,
|
||||
Date: time.Now(),
|
||||
}
|
||||
p.Coll.Insert(message)
|
||||
}
|
||||
|
||||
// deliver a random quote out of the db.
|
||||
// Note: this is the same cache for all channels joined. This plugin needs to be expanded
|
||||
// to have this function execute a quote for a particular channel
|
||||
func (p *RememberPlugin) randQuote() string {
|
||||
var quotes []userRemember
|
||||
iter := p.Coll.Find(bson.M{}).Iter()
|
||||
var quotes []Factoid
|
||||
// todo: find anything with the word "quotes" in the trigger
|
||||
query := bson.M{
|
||||
"trigger": bson.M{
|
||||
"$regex": "quotes$",
|
||||
},
|
||||
}
|
||||
iter := p.Coll.Find(query).Iter()
|
||||
err := iter.All("es)
|
||||
if err != nil {
|
||||
panic(iter.Err())
|
||||
|
@ -141,7 +139,7 @@ func (p *RememberPlugin) randQuote() string {
|
|||
return "Sorry, I don't know any quotes."
|
||||
}
|
||||
quote := quotes[rand.Intn(nquotes)]
|
||||
return quote.Message
|
||||
return quote.FullText
|
||||
}
|
||||
|
||||
func (p *RememberPlugin) quoteTimer(channel string) {
|
||||
|
@ -152,7 +150,6 @@ func (p *RememberPlugin) quoteTimer(channel string) {
|
|||
chance := 1.0 / p.Bot.Config.QuoteChance
|
||||
if rand.Intn(int(chance)) == 0 {
|
||||
msg := p.randQuote()
|
||||
fmt.Println("Delivering quote.")
|
||||
p.Bot.SendMessage(channel, msg)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue