From ffbc5ac02e8e934ccfbcc4825c12ea618673688f Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 5 Apr 2017 23:14:56 +0200 Subject: Initial import --- LICENSE | 13 ++++++++ README.md | 0 main.go | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 main.go diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9863fd4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2017 Dimitri Sokolyuk + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/main.go b/main.go new file mode 100644 index 0000000..b85198a --- /dev/null +++ b/main.go @@ -0,0 +1,101 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "time" +) + +type Opt struct { + Work time.Duration + Short time.Duration + Long time.Duration + Day time.Duration + Runs int + run int +} + +type stateFn func(context.Context, chan string) stateFn + +func (o *Opt) doWork(ctx context.Context, c chan string) stateFn { + t := time.NewTimer(o.Work) + defer t.Stop() + c <- fmt.Sprintf("Work %v run #%v", o.Work, o.run+1) + select { + case <-ctx.Done(): + return nil + case <-t.C: + return o.doBreak + } +} + +func (o *Opt) doBreak(_ context.Context, _ chan string) stateFn { + if o.run++; o.run%o.Runs == 0 { + return o.longBreak + } + return o.shortBreak +} + +func (o *Opt) shortBreak(ctx context.Context, c chan string) stateFn { + t := time.NewTimer(o.Short) + defer t.Stop() + c <- fmt.Sprintf("Short %v", o.Short) + select { + case <-ctx.Done(): + return nil + case <-t.C: + return o.doWork + } +} + +func (o *Opt) longBreak(ctx context.Context, c chan string) stateFn { + t := time.NewTimer(o.Long) + defer t.Stop() + c <- fmt.Sprintf("Long %v", o.Long) + select { + case <-ctx.Done(): + return nil + case <-t.C: + return o.doWork + } +} + +func notifier(ctx context.Context) chan string { + c := make(chan string) + go func() { + defer close(c) + for v := range c { + select { + case <-ctx.Done(): + return + default: + log.Println(v) + } + } + }() + return c +} + +func (o *Opt) pomodoro() { + defer func(t time.Time) { log.Printf("total %v", time.Since(t)) }(time.Now()) + ctx, cancel := context.WithTimeout(context.Background(), o.Day) + defer cancel() + c := notifier(ctx) + for s := o.doWork; s != nil; s = s(ctx, c) { + } +} + +const timeBase = time.Second + +func main() { + var o Opt + flag.DurationVar(&o.Work, "work", 25*timeBase, "work time") + flag.DurationVar(&o.Short, "short", 5*timeBase, "short break") + flag.DurationVar(&o.Long, "long", 15*timeBase, "long break") + flag.DurationVar(&o.Day, "day", 600*timeBase, "work day") + flag.IntVar(&o.Runs, "runs", 4, "work runs") + flag.Parse() + o.pomodoro() +} -- cgit v1.2.3