recur for period

This commit is contained in:
Erik Winter 2025-01-04 08:54:13 +01:00
parent 8539271026
commit c1698a9ec3
4 changed files with 36 additions and 20 deletions

BIN
dist/plannersync vendored

Binary file not shown.

View File

@ -11,6 +11,7 @@ import (
type Recur struct { type Recur struct {
repoSync Syncer repoSync Syncer
repoRecur Recurrer repoRecur Recurrer
days int
logger *slog.Logger logger *slog.Logger
} }
@ -24,28 +25,38 @@ func NewRecur(repoRecur Recurrer, repoSync Syncer, logger *slog.Logger) *Recur {
return r return r
} }
func (r *Recur) Run(interval time.Duration) { func (r *Recur) Run(days int, interval time.Duration) {
r.days = days
ticker := time.NewTicker(interval) ticker := time.NewTicker(interval)
for range ticker.C { for range ticker.C {
if err := r.Recur(); err != nil { today := item.NewDateFromString(time.Now().Format(item.DateFormat))
last := today.Add(r.days)
if err := r.Recur(last); err != nil {
r.logger.Error("could not recur", "error", err) r.logger.Error("could not recur", "error", err)
} }
} }
} }
func (r *Recur) Recur() error { func (r *Recur) Recur(until item.Date) error {
r.logger.Info("start looking for recurring items") r.logger.Info("start looking for recurring items", "until", until.String())
today := item.NewDateFromString(time.Now().Format(item.DateFormat))
items, err := r.repoRecur.ShouldRecur(today) items, err := r.repoRecur.ShouldRecur(until)
if err != nil { if err != nil {
return err return err
} }
r.logger.Info("found recurring items", "count", len(items)) r.logger.Info("found recurring items", "count", len(items))
for _, i := range items { for _, i := range items {
r.logger.Info("processing recurring item", "id", i.ID) r.logger.Info("processing recurring item", "id", i.ID)
// spawn instance
newRecurNext := item.FirstRecurAfter(i.Recurrer, i.RecurNext) newRecurNext := item.FirstRecurAfter(i.Recurrer, i.RecurNext)
for {
if newRecurNext.After(until) {
break
}
// spawn instance
newItem := i newItem := i
newItem.ID = uuid.New().String() newItem.ID = uuid.New().String()
newItem.Date = newRecurNext newItem.Date = newRecurNext
@ -56,6 +67,9 @@ func (r *Recur) Recur() error {
} }
r.logger.Info("spawned instance", "newID", newItem.ID, "date", newItem.Date) r.logger.Info("spawned instance", "newID", newItem.ID, "date", newItem.Date)
newRecurNext = item.FirstRecurAfter(i.Recurrer, newRecurNext)
}
// update recurrer // update recurrer
i.RecurNext = newRecurNext i.RecurNext = newRecurNext
if err := r.repoSync.Update(i, time.Now()); err != nil { if err := r.repoSync.Update(i, time.Now()); err != nil {

View File

@ -14,6 +14,7 @@ func TestRecur(t *testing.T) {
now := time.Now() now := time.Now()
today := item.NewDate(2024, 1, 1) today := item.NewDate(2024, 1, 1)
until := today.Add(3)
mem := NewMemory() mem := NewMemory()
rec := NewRecur(mem, mem, slog.New(slog.NewTextHandler(io.Discard, nil))) rec := NewRecur(mem, mem, slog.New(slog.NewTextHandler(io.Discard, nil)))
@ -33,7 +34,7 @@ func TestRecur(t *testing.T) {
} }
// Run recurrence // Run recurrence
if err := rec.Recur(); err != nil { if err := rec.Recur(until); err != nil {
t.Errorf("Recur failed: %v", err) t.Errorf("Recur failed: %v", err)
} }
@ -43,14 +44,14 @@ func TestRecur(t *testing.T) {
t.Errorf("failed to get updated items: %v", err) t.Errorf("failed to get updated items: %v", err)
} }
if len(items) != 2 { // Original + new instance if len(items) != 4 { // Original + 3 new instances
t.Errorf("expected 2 items, got %d", len(items)) t.Errorf("expected 2 items, got %d", len(items))
} }
// Check that RecurNext was updated // Check that RecurNext was updated
recurItems, err := mem.ShouldRecur(today.Add(1)) recurItems, err := mem.ShouldRecur(until.Add(1))
if err != nil { if err != nil {
t.Fatal(err) t.Errorf("exp nil, got %v", err)
} }
if len(recurItems) != 1 { if len(recurItems) != 1 {
t.Errorf("expected 1 recur item, got %d", len(recurItems)) t.Errorf("expected 1 recur item, got %d", len(recurItems))

View File

@ -19,6 +19,7 @@ var (
dbName = flag.String("dbname", "planner", "database name") dbName = flag.String("dbname", "planner", "database name")
dbUser = flag.String("dbuser", "test", "database user") dbUser = flag.String("dbuser", "test", "database user")
dbPassword = flag.String("dbpassword", "test", "database password") dbPassword = flag.String("dbpassword", "test", "database password")
recurDays = flag.Int("recurdays", 8, "amount of days ahead to recur")
) )
func main() { func main() {
@ -39,7 +40,7 @@ func main() {
"dbUser": *dbUser, "dbUser": *dbUser,
}) })
recurrer := NewRecur(repo, repo, logger) recurrer := NewRecur(repo, repo, logger)
go recurrer.Run(6 * time.Hour) go recurrer.Run(*recurDays, 6*time.Hour)
srv := NewServer(repo, *apiKey, logger) srv := NewServer(repo, *apiKey, logger)
go http.ListenAndServe(fmt.Sprintf(":%s", *apiPort), srv) go http.ListenAndServe(fmt.Sprintf(":%s", *apiPort), srv)