diff --git a/plugins/reminder/reminder.go b/plugins/reminder/reminder.go index f2ac29c..7c87371 100644 --- a/plugins/reminder/reminder.go +++ b/plugins/reminder/reminder.go @@ -5,6 +5,7 @@ package reminder import ( "fmt" "sort" + "strconv" "strings" "sync" "time" @@ -15,14 +16,16 @@ import ( ) type ReminderPlugin struct { - Bot bot.Bot - reminders []*Reminder - mutex *sync.Mutex - timer *time.Timer - config *config.Config + Bot bot.Bot + reminders []*Reminder + mutex *sync.Mutex + timer *time.Timer + config *config.Config + nextReminderId int } type Reminder struct { + id int from string who string what string @@ -50,11 +53,12 @@ func New(bot bot.Bot) *ReminderPlugin { timer.Stop() plugin := &ReminderPlugin{ - Bot: bot, - reminders: []*Reminder{}, - mutex: &sync.Mutex{}, - timer: timer, - config: bot.Config(), + Bot: bot, + reminders: []*Reminder{}, + mutex: &sync.Mutex{}, + timer: timer, + config: bot.Config(), + nextReminderId: 0, } go reminderer(plugin) @@ -119,7 +123,11 @@ func (p *ReminderPlugin) Message(message msg.Message) bool { when := time.Now().Add(dur) what := strings.Join(parts[4:], " ") + id := p.nextReminderId + p.nextReminderId++ + reminders = append(reminders, &Reminder{ + id: id, from: from, who: who, what: what, @@ -146,7 +154,11 @@ func (p *ReminderPlugin) Message(message msg.Message) bool { break } + id := p.nextReminderId + p.nextReminderId++ + reminders = append(reminders, &Reminder{ + id: id, from: from, who: who, what: what, @@ -191,7 +203,7 @@ func (p *ReminderPlugin) Message(message msg.Message) bool { counter := 1 for _, reminder := range p.reminders { if reminder.channel == channel { - response += fmt.Sprintf("%d) %s -> %s :: %s @ %s\n", counter, reminder.from, reminder.who, reminder.what, reminder.when) + response += fmt.Sprintf("%d) %s -> %s :: %s @ %s (id=%d)\n", counter, reminder.from, reminder.who, reminder.what, reminder.when, reminder.id) counter++ } } @@ -199,6 +211,32 @@ func (p *ReminderPlugin) Message(message msg.Message) bool { p.mutex.Unlock() p.Bot.SendMessage(channel, response) return true + } else if len(parts) == 3 && strings.ToLower(parts[0]) == "cancel" && strings.ToLower(parts[1]) == "reminder" { + id, err := strconv.Atoi(parts[2]) + if err != nil { + p.Bot.SendMessage(channel, fmt.Sprintf("couldn't parse id: %s", parts[2])) + + } else { + p.mutex.Lock() + deleted := false + for i, reminder := range p.reminders { + if reminder.id == id { + copy(p.reminders[i:], p.reminders[i+1:]) + p.reminders[len(p.reminders)-1] = nil + p.reminders = p.reminders[:len(p.reminders)-1] + deleted = true + break + } + } + p.mutex.Unlock() + + if deleted { + p.Bot.SendMessage(channel, fmt.Sprintf("successfully canceled reminder: %s", parts[2])) + } else { + p.Bot.SendMessage(channel, fmt.Sprintf("failed to find and cancel reminder: %s", parts[2])) + } + } + return true } return false diff --git a/plugins/reminder/reminder_test.go b/plugins/reminder/reminder_test.go index 453445f..841d1ce 100644 --- a/plugins/reminder/reminder_test.go +++ b/plugins/reminder/reminder_test.go @@ -122,6 +122,32 @@ func TestBatchMax(t *testing.T) { } } +func TestCancel(t *testing.T) { + mb := bot.NewMockBot() + c := New(mb) + assert.NotNil(t, c) + res := c.Message(makeMessage("!remind testuser in 1m don't fail this test")) + assert.True(t, res) + res = c.Message(makeMessage("!cancel reminder 0")) + assert.True(t, res) + res = c.Message(makeMessage("!list reminders")) + assert.True(t, res) + assert.Len(t, mb.Messages, 3) + assert.Contains(t, mb.Messages[0], "Sure tester, I'll remind testuser.") + assert.Contains(t, mb.Messages[1], "successfully canceled reminder: 0") + assert.Contains(t, mb.Messages[2], "no pending reminders") +} + +func TestCancelMiss(t *testing.T) { + mb := bot.NewMockBot() + c := New(mb) + assert.NotNil(t, c) + res := c.Message(makeMessage("!cancel reminder 0")) + assert.True(t, res) + assert.Len(t, mb.Messages, 1) + assert.Contains(t, mb.Messages[0], "failed to find and cancel reminder: 0") +} + func TestHelp(t *testing.T) { mb := bot.NewMockBot() c := New(mb)