Merge pull request #48 from velour/batch_reminders

batch adding of reminders for msherms
This commit is contained in:
Chris Sexton 2017-05-02 07:58:14 -04:00 committed by GitHub
commit 167b8db82b
4 changed files with 103 additions and 12 deletions

View File

@ -72,6 +72,9 @@ type Config struct {
Babbler struct { Babbler struct {
DefaultUsers []string DefaultUsers []string
} }
Reminder struct {
MaxBatchAdd int
}
} }
// 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

@ -64,5 +64,8 @@
"DefaultUsers": [ "DefaultUsers": [
"seabass" "seabass"
] ]
},
"Reminder": {
"MaxBatchAdd" : 10
} }
} }

View File

@ -11,6 +11,7 @@ import (
"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/config"
) )
type ReminderPlugin struct { type ReminderPlugin struct {
@ -18,6 +19,7 @@ type ReminderPlugin struct {
reminders []*Reminder reminders []*Reminder
mutex *sync.Mutex mutex *sync.Mutex
timer *time.Timer timer *time.Timer
config *config.Config
} }
type Reminder struct { type Reminder struct {
@ -52,6 +54,7 @@ func New(bot bot.Bot) *ReminderPlugin {
reminders: []*Reminder{}, reminders: []*Reminder{},
mutex: &sync.Mutex{}, mutex: &sync.Mutex{},
timer: timer, timer: timer,
config: bot.Config(),
} }
go reminderer(plugin) go reminderer(plugin)
@ -97,23 +100,53 @@ func (p *ReminderPlugin) Message(message msg.Message) bool {
if who == "me" { if who == "me" {
who = from who = from
} }
dur, err := time.ParseDuration(parts[3]) dur, err := time.ParseDuration(parts[3])
if err != nil { if err != nil {
p.Bot.SendMessage(channel, "Easy cowboy, not sure I can parse that duration.") p.Bot.SendMessage(channel, "Easy cowboy, not sure I can parse that duration.")
return true return true
} }
when := time.Now().Add(dur)
reminders := []*Reminder{}
operator := strings.ToLower(parts[2])
doConfirm := true
if operator == "in" {
//one off reminder
//remind who in dur blah
when := time.Now().Add(dur)
what := strings.Join(parts[4:], " ") what := strings.Join(parts[4:], " ")
response := fmt.Sprintf("Sure %s, I'll remind %s.", from, who) reminders = append(reminders, &Reminder{
p.Bot.SendMessage(channel, response) from: from,
who: who,
what: what,
when: when,
channel: channel,
})
} else if operator == "every" && strings.ToLower(parts[4]) == "for" {
//batch add, especially for reminding msherms to buy a kit
//remind who every dur for dur2 blah
dur2, err := time.ParseDuration(parts[5])
if err != nil {
p.Bot.SendMessage(channel, "Easy cowboy, not sure I can parse that duration.")
return true
}
p.mutex.Lock() when := time.Now().Add(dur)
endTime := time.Now().Add(dur2)
what := strings.Join(parts[6:], " ")
p.timer.Stop() for i := 0; when.Before(endTime); i++ {
if i >= p.config.Reminder.MaxBatchAdd {
p.Bot.SendMessage(channel, "Easy cowboy, that's a lot of reminders. I'll add some of them.")
doConfirm = false
break
}
p.reminders = append(p.reminders, &Reminder{ reminders = append(reminders, &Reminder{
from: from, from: from,
who: who, who: who,
what: what, what: what,
@ -121,9 +154,29 @@ func (p *ReminderPlugin) Message(message msg.Message) bool {
channel: channel, channel: channel,
}) })
when = when.Add(dur)
}
} else {
p.Bot.SendMessage(channel, "Easy cowboy, not sure I comprehend what you're asking.")
return true
}
if doConfirm {
response := fmt.Sprintf("Sure %s, I'll remind %s.", from, who)
p.Bot.SendMessage(channel, response)
}
p.mutex.Lock()
p.timer.Stop()
p.reminders = append(p.reminders, reminders...)
sort.Sort(reminderSlice(p.reminders)) sort.Sort(reminderSlice(p.reminders))
if len(p.reminders) > 0 {
p.timer.Reset(p.reminders[0].when.Sub(time.Now())) p.timer.Reset(p.reminders[0].when.Sub(time.Now()))
}
p.mutex.Unlock() p.mutex.Unlock()

View File

@ -3,6 +3,7 @@
package reminder package reminder
import ( import (
"fmt"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -89,6 +90,37 @@ func TestList(t *testing.T) {
assert.Contains(t, mb.Messages[2], "2) tester -> testuser :: don't fail this test 2 @ ") assert.Contains(t, mb.Messages[2], "2) tester -> testuser :: don't fail this test 2 @ ")
} }
func TestBatch(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
c.config.Reminder.MaxBatchAdd = 50
assert.NotNil(t, c)
res := c.Message(makeMessage("!remind testuser every 1s for 5s yikes"))
assert.True(t, res)
time.Sleep(6 * time.Second)
assert.Len(t, mb.Messages, 6)
for i := 0; i < 5; i++ {
assert.Contains(t, mb.Messages[i+1], "Hey testuser, tester wanted you to be reminded: yikes")
}
}
func TestBatchMax(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
c.config.Reminder.MaxBatchAdd = 10
assert.NotNil(t, c)
res := c.Message(makeMessage("!remind testuser every 1h for 24h yikes"))
assert.True(t, res)
res = c.Message(makeMessage("!list reminders"))
assert.True(t, res)
time.Sleep(6 * time.Second)
assert.Len(t, mb.Messages, 2)
assert.Contains(t, mb.Messages[0], "Easy cowboy, that's a lot of reminders. I'll add some of them.")
for i := 0; i < 10; i++ {
assert.Contains(t, mb.Messages[1], fmt.Sprintf("%d) tester -> testuser :: yikes", i+1))
}
}
func TestHelp(t *testing.T) { func TestHelp(t *testing.T) {
mb := bot.NewMockBot() mb := bot.NewMockBot()