From 030d0371f99a0a4e182749ee646c0880be6b705e Mon Sep 17 00:00:00 2001 From: Chris Sexton Date: Mon, 13 Jul 2020 16:58:44 -0400 Subject: [PATCH] countdown: add NYE countdown --- main.go | 2 + plugins/countdown/countdown.go | 87 +++++++++++++++++++++++++++++ plugins/countdown/countdown_test.go | 26 +++++++++ 3 files changed, 115 insertions(+) create mode 100644 plugins/countdown/countdown.go create mode 100644 plugins/countdown/countdown_test.go diff --git a/main.go b/main.go index 44e4508..38570ed 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( "github.com/velour/catbase/plugins/achievements" "github.com/velour/catbase/plugins/aoc" + "github.com/velour/catbase/plugins/countdown" "github.com/velour/catbase/plugins/goals" "github.com/velour/catbase/plugins/meme" "github.com/velour/catbase/plugins/sms" @@ -146,6 +147,7 @@ func main() { b.AddPlugin(meme.New(b)) b.AddPlugin(achievements.New(b)) b.AddPlugin(sms.New(b)) + b.AddPlugin(countdown.New(b)) // catches anything left, will always return true b.AddPlugin(fact.New(b)) diff --git a/plugins/countdown/countdown.go b/plugins/countdown/countdown.go new file mode 100644 index 0000000..a5bc721 --- /dev/null +++ b/plugins/countdown/countdown.go @@ -0,0 +1,87 @@ +// Countdown is a plugin to do tasks on various milestones. +package countdown + +import ( + "fmt" + "time" + + "github.com/jmoiron/sqlx" + "github.com/rs/zerolog/log" + + "github.com/velour/catbase/bot" + "github.com/velour/catbase/config" +) + +var nextYear = time.Date(time.Now().Year()+1, 0, 0, 0, 0, 0, 0, time.Local) + +type CountdownPlugin struct { + b bot.Bot + db *sqlx.DB + c *config.Config +} + +func New(b bot.Bot) *CountdownPlugin { + p := &CountdownPlugin{ + b: b, + db: b.DB(), + c: b.Config(), + } + + p.scheduleNYE(p.newYearRollover) + + return p +} + +func (p *CountdownPlugin) scheduleNYE(f func()) { + time.AfterFunc(nextYear.Sub(time.Now()), f) + for i := 10; i > 0; i-- { + mkFunc := func(i int) func() { + return func() { + p.nyeCountdown(i) + } + } + time.AfterFunc(nextYear.Add(time.Duration(10-i)*time.Second).Sub(time.Now()), mkFunc(i)) + } +} + +func (p *CountdownPlugin) newYearRollover() { + log.Debug().Msgf("Happy new year!") + + tx, err := p.db.Beginx() + if err != nil { + logError(err, "error getting transaction") + return + } + year := time.Now().Year() - 1 + q := fmt.Sprintf(`insert into counter_%d select * from counter`, year) + _, err = tx.Exec(q) + if err != nil { + logError(err, "error running insert into") + logError(tx.Rollback(), "error with insert rollback") + return + } + q = `delete from counter` + _, err = tx.Exec(q) + if err != nil { + logError(err, "error running delete") + logError(tx.Rollback(), "error with delete rollback") + return + } + err = tx.Commit() + logError(err, "error committing transaction") +} + +func logError(err error, msg string) { + if err == nil { + return + } + log.Error().Err(err).Msgf(msg) +} + +func (p *CountdownPlugin) nyeCountdown(i int) { + chs := p.c.GetArray("channels", []string{}) + for _, ch := range chs { + msg := fmt.Sprintf("%d!", i) + p.b.Send(p.b.DefaultConnector(), bot.Message, ch, msg, msg) + } +} diff --git a/plugins/countdown/countdown_test.go b/plugins/countdown/countdown_test.go new file mode 100644 index 0000000..3212848 --- /dev/null +++ b/plugins/countdown/countdown_test.go @@ -0,0 +1,26 @@ +package countdown + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/velour/catbase/bot" +) + +func TestScheduleNewYears(t *testing.T) { + mb := bot.NewMockBot() + p := New(mb) + functionTripped := false + f := func() { + functionTripped = true + } + + // this is lazy, but I don't feel like fixing it + nextYear = time.Now().Add(time.Millisecond * 5) + p.scheduleNYE(f) + time.Sleep(time.Millisecond * 10) + + assert.True(t, functionTripped) +}