remind: parse times with a nice date parser

This commit is contained in:
Chris Sexton 2019-03-09 21:26:11 -05:00
parent 578722cd19
commit 83815324bf
4 changed files with 58 additions and 17 deletions

11
go.mod
View File

@ -2,27 +2,24 @@ module github.com/velour/catbase
require (
github.com/PuerkitoBio/goquery v1.5.0 // indirect
github.com/boltdb/bolt v1.3.1
github.com/chrissexton/leftpad v0.0.0-20181207133115-1e93189d2fff
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-sql-driver/mysql v1.4.1 // indirect
github.com/gorilla/websocket v1.4.0 // indirect
github.com/jmoiron/sqlx v1.2.0
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 // indirect
github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6 // indirect
github.com/mattn/go-sqlite3 v1.10.0
github.com/mitchellh/mapstructure v1.1.2 // indirect
github.com/mmcdole/gofeed v1.0.0-beta2
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf // indirect
github.com/nlopes/slack v0.5.0
github.com/pkg/errors v0.8.1 // indirect
github.com/olebedev/when v0.0.0-20190131080308-164b69386514
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d // indirect
github.com/rs/zerolog v1.12.0
github.com/stretchr/objx v0.1.1 // indirect
github.com/stretchr/testify v1.3.0
github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89
github.com/velour/velour v0.0.0-20160303155839-8e090e68d158
github.com/yuin/gluamapper v0.0.0-20150323120927-d836955830e7
github.com/yuin/gopher-lua v0.0.0-20190125051437-7b9317363aa9
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 // indirect
golang.org/x/text v0.3.0 // indirect
google.golang.org/appengine v1.4.0 // indirect
gopkg.in/sourcemap.v1 v1.0.5 // indirect
)

19
go.sum
View File

@ -1,31 +1,39 @@
github.com/AlekSi/pointer v1.0.0 h1:KWCWzsvFxNLcmM5XmiqHsGTTsuwZMsLFwWF9Y+//bNE=
github.com/AlekSi/pointer v1.0.0/go.mod h1:1kjywbfcPFCmncIxtk6fIEub6LKrfMz3gc5QKVOSOA8=
github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/chrissexton/leftpad v0.0.0-20181207133115-1e93189d2fff h1:+TEqaP0eO1unI7XHHFeMDhsxhLDIb0x8KYuZbqbAmxA=
github.com/chrissexton/leftpad v0.0.0-20181207133115-1e93189d2fff/go.mod h1:QCRjR0b4qiJiNjuP7RFM89bh4UExGJalcWmYeSvlnRc=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 h1:AsEBgzv3DhuYHI/GiQh2HxvTP71HCCE9E/tzGUzGdtU=
github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5/go.mod h1:c2mYKRyMb1BPkO5St0c/ps62L4S0W2NAkaTXj9qEI+0=
github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6 h1:iOAVXzZyXtW408TMYejlUPo6BIn92HmOacWtIfNyYns=
github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mmcdole/gofeed v1.0.0-beta2 h1:CjQ0ADhAwNSb08zknAkGOEYqr8zfZKfrzgk9BxpWP2E=
github.com/mmcdole/gofeed v1.0.0-beta2/go.mod h1:/BF9JneEL2/flujm8XHoxUcghdTV6vvb3xx/vKyChFU=
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf h1:sWGE2v+hO0Nd4yFU/S/mDBM5plIU8v/Qhfz41hkDIAI=
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf/go.mod h1:pasqhqstspkosTneA62Nc+2p9SOBBYAPbnmRRWPQ0V8=
github.com/nlopes/slack v0.5.0 h1:NbIae8Kd0NpqaEI3iUrsuS0KbcEDhzhc939jLW5fNm0=
github.com/nlopes/slack v0.5.0/go.mod h1:jVI4BBK3lSktibKahxBF74txcK2vyvkza1z/+rRnVAM=
github.com/olebedev/when v0.0.0-20190131080308-164b69386514 h1:xpZutaUgtGPKT2JFaH72/yby908QS9ORlnrAkkdJ4m0=
github.com/olebedev/when v0.0.0-20190131080308-164b69386514/go.mod h1:DPucAeQGDPUzYUt+NaWw6qsF5SFapWWToxEiVDh2aV0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -43,13 +51,14 @@ github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89 h1:3D3M900hEBJJAqyKl70
github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89/go.mod h1:ejwOYCjnDMyO5LXFXRARQJGBZ6xQJZ3rgAHE5drSuMM=
github.com/velour/velour v0.0.0-20160303155839-8e090e68d158 h1:p3rTUXxzuKsBOsHlkly7+rj9wagFBKeIsCDKkDII9sw=
github.com/velour/velour v0.0.0-20160303155839-8e090e68d158/go.mod h1:Ojy3BTOiOTwpHpw7/HNi+TVTFppao191PQs+Qc3sqpE=
github.com/yuin/gluamapper v0.0.0-20150323120927-d836955830e7/go.mod h1:bbMEM6aU1WDF1ErA5YJ0p91652pGv140gGw4Ww3RGp8=
github.com/yuin/gopher-lua v0.0.0-20190125051437-7b9317363aa9/go.mod h1:fFiAh+CowNFr0NK5VASokuwKwkbacRmHsVA7Yb1Tqac=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=

View File

@ -10,9 +10,13 @@ import (
"sync"
"time"
"github.com/jmoiron/sqlx"
"github.com/rs/zerolog/log"
"github.com/jmoiron/sqlx"
"github.com/olebedev/when"
"github.com/olebedev/when/rules/common"
"github.com/olebedev/when/rules/en"
"github.com/velour/catbase/bot"
"github.com/velour/catbase/bot/msg"
"github.com/velour/catbase/config"
@ -28,6 +32,7 @@ type ReminderPlugin struct {
mutex *sync.Mutex
timer *time.Timer
config *config.Config
when *when.Parser
}
type Reminder struct {
@ -55,12 +60,17 @@ func New(b bot.Bot) *ReminderPlugin {
timer := time.NewTimer(dur)
timer.Stop()
w := when.New(nil)
w.Add(en.All...)
w.Add(common.All...)
plugin := &ReminderPlugin{
Bot: b,
db: b.DB(),
mutex: &sync.Mutex{},
timer: timer,
config: b.Config(),
when: w,
}
plugin.queueUpNextReminder()
@ -77,6 +87,13 @@ func (p *ReminderPlugin) message(kind bot.Kind, message msg.Message, args ...int
channel := message.Channel
from := message.User.Name
var dur, dur2 time.Duration
t, err := p.when.Parse(message.Body, time.Now())
// Allowing err to fallthrough for other parsing
if t != nil && err == nil {
t2 := time.Now().Sub(t.Time).String()
message.Body = string(message.Body[0:t.Index]) + t2 + string(message.Body[t.Index+len(t.Text):])
}
parts := strings.Fields(message.Body)
if len(parts) >= 5 {
@ -86,17 +103,16 @@ func (p *ReminderPlugin) message(kind bot.Kind, message msg.Message, args ...int
who = from
}
dur, err := time.ParseDuration(parts[3])
dur, err = time.ParseDuration(parts[3])
if err != nil {
p.Bot.Send(bot.Message, channel, "Easy cowboy, not sure I can parse that duration. Try something like '1.5h' or '2h45m'.")
return true
}
operator := strings.ToLower(parts[2])
doConfirm := true
if operator == "in" {
if operator == "in" || operator == "at" || operator == "on" {
//one off reminder
//remind who in dur blah
when := time.Now().UTC().Add(dur)
@ -114,8 +130,9 @@ func (p *ReminderPlugin) message(kind bot.Kind, message msg.Message, args ...int
} 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])
dur2, err = time.ParseDuration(parts[5])
if err != nil {
log.Error().Err(err)
p.Bot.Send(bot.Message, channel, "Easy cowboy, not sure I can parse that duration. Try something like '1.5h' or '2h45m'.")
return true
}

View File

@ -58,6 +58,24 @@ func TestReminder(t *testing.T) {
assert.Contains(t, mb.Messages[1], "Hey testuser, tester wanted you to be reminded: don't fail this test")
}
func TestReminderDate(t *testing.T) {
c, mb := setup(t)
m0 := fmt.Sprintf("!remind testuser at %s don't fail this test 2",
time.Now().Add(3*time.Second).Format("15:04"))
res := c.message(makeMessage(m0))
assert.True(t, res)
m1 := fmt.Sprintf("!remind testuser at %s don't fail this test 1",
time.Now().Add(2*time.Second).Format("15:04"))
res = c.message(makeMessage(m1))
assert.True(t, res)
time.Sleep(5 * time.Second)
assert.Len(t, mb.Messages, 4)
assert.Contains(t, mb.Messages[0], "Sure tester, I'll remind testuser.")
assert.Contains(t, mb.Messages[1], "Hey testuser, tester wanted you to be reminded: don't fail this test 2")
assert.Contains(t, mb.Messages[2], "Sure tester, I'll remind testuser.")
assert.Contains(t, mb.Messages[3], "Hey testuser, tester wanted you to be reminded: don't fail this test 1")
}
func TestReminderReorder(t *testing.T) {
c, mb := setup(t)
res := c.message(makeMessage("!remind testuser in 2s don't fail this test 2"))