// Countdown is a plugin to do tasks on various milestones. package countdown import ( "fmt" bh "github.com/timshannon/bolthold" "github.com/velour/catbase/plugins/babbler" "github.com/velour/catbase/plugins/counter" "time" "github.com/rs/zerolog/log" "github.com/velour/catbase/bot" "github.com/velour/catbase/config" ) var nextYear = time.Date(time.Now().Year()+1, time.January, 1, 0, 0, 0, 1, time.Local) var thisYear = time.Now().Year() type CountdownPlugin struct { b bot.Bot store *bh.Store c *config.Config } func New(b bot.Bot) *CountdownPlugin { p := &CountdownPlugin{ b: b, store: b.Store(), 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!") if err := p.clearBabblers(); err != nil { log.Error().Err(err).Msgf("error clearing babblers") } if err := p.archiveCounters(); err != nil { log.Error().Err(err).Msgf("error clearing babblers") } } 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) } } func (p *CountdownPlugin) clearBabblers() error { if err := p.store.DeleteMatching(babbler.Babbler{}, &bh.Query{}); err != nil { return err } if err := p.store.DeleteMatching(babbler.BabblerArc{}, &bh.Query{}); err != nil { return err } if err := p.store.DeleteMatching(babbler.BabblerNode{}, &bh.Query{}); err != nil { return err } if err := p.store.DeleteMatching(babbler.BabblerWord{}, &bh.Query{}); err != nil { return err } return nil } type counterArchive struct { counter.Item Year int } func (ca counterArchive) Key() string { return fmt.Sprintf("%d-%d", ca.Year, ca.ID) } func (p *CountdownPlugin) archiveCounters() error { year := time.Now().Year() allCounters := []counter.Item{} if err := p.store.Find(&allCounters, &bh.Query{}); err != nil { return err } for _, c := range allCounters { ca := counterArchive{c, year} err := p.store.Insert(ca.Key(), ca) if err != nil { return err } } if err := p.store.DeleteMatching(counter.Item{}, &bh.Query{}); err != nil { return err } return nil }