59 lines
1008 B
Go
59 lines
1008 B
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"log/slog"
|
||
|
"time"
|
||
|
|
||
|
"go-mod.ewintr.nl/planner/item"
|
||
|
)
|
||
|
|
||
|
type Recur struct {
|
||
|
repo Recurrer
|
||
|
logger *slog.Logger
|
||
|
}
|
||
|
|
||
|
func NewRecur(repo Recurrer, interval time.Duration, logger *slog.Logger) *Recur {
|
||
|
r := &Recur{
|
||
|
repo: repo,
|
||
|
logger: logger,
|
||
|
}
|
||
|
go r.run(interval)
|
||
|
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
func (r *Recur) run(interval time.Duration) {
|
||
|
ticker := time.NewTicker(interval)
|
||
|
|
||
|
for range ticker.C {
|
||
|
if err := r.recur(); err != nil {
|
||
|
r.logger.Error("could not recur", "error", err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (r *Recur) recur() error {
|
||
|
items, err := r.repo.RecursBefore(time.Now())
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
for _, i := range items {
|
||
|
if err := r.repo.RecursNext(i.ID, NewNext(i.Recurrer, i.RecurNext)); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func NewNext(r *item.Recur, old time.Time) time.Time {
|
||
|
day, _ := time.ParseDuration("1d")
|
||
|
test := old.Add(day)
|
||
|
for {
|
||
|
if r.On(test) || test.After(time.Date(2500, 1, 1, 0, 0, 0, 0, time.UTC)) {
|
||
|
return test
|
||
|
}
|
||
|
test.Add(day)
|
||
|
}
|
||
|
}
|