commit 09ce597cdaf2d6f759004b258538df3a8c2d2904 Author: Kevin Schoon Date: Tue Jan 16 17:50:08 2018 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dde85ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +*.swp diff --git a/README.md b/README.md new file mode 100644 index 0000000..e479334 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# pomo + +`pomo` is a simple CLI implementation of the [Pomodoro Technique](https://en.wikipedia.org/wiki/Pomodoro_Technique). It integrates with [i3](i3wm.org) and might support other environments later on. diff --git a/main.go b/main.go new file mode 100644 index 0000000..dfdfa46 --- /dev/null +++ b/main.go @@ -0,0 +1,71 @@ +package main + +import ( + "fmt" + "github.com/jawher/mow.cli" + "os" + "time" +) + +func maybe(err error) { + if err != nil { + fmt.Printf("Error: %s", err) + os.Exit(1) + } +} + +func startTask(task Task, prompter Prompter, db *Store) { + taskID, err := db.AddTask(task) + maybe(err) + for i := 0; i < task.count; i++ { + // Create a new "Pomo" to represent + // this particular stent of work + pomo := &Pomo{TaskID: taskID} + // Prompt the client + maybe(prompter.Prompt("Begin Working!")) + pomo.Start = time.Now() + // Wait the specified interval + time.Sleep(task.duration) + maybe(prompter.Prompt("Take a Break!")) + // Record how long the user waited + // until closing the notification + pomo.End = time.Now() + maybe(db.AddPomo(*pomo)) + } + +} + +func start(cmd *cli.Cmd) { + cmd.Spec = "[OPTIONS] NAME" + var ( + duration = cmd.StringOpt("d duration", "25m", "duration of each stent") + count = cmd.IntOpt("c count", 4, "number of working stents") + name = cmd.StringArg("NAME", "", "descriptive name of the given task") + path = cmd.StringOpt("d db", "~/.pomo/state.db", "path to the pomo sqlite database") + ) + cmd.Action = func() { + parsed, err := time.ParseDuration(*duration) + maybe(err) + db, err := NewStore(*path) + maybe(err) + task := Task{ + Name: *name, + count: *count, + duration: parsed, + } + startTask(task, &I3{}, db) + } +} + +func initialize(cmd *cli.Cmd) {} + +func list(cmd *cli.Cmd) {} + +func main() { + app := cli.App("pomo", "Pomodoro CLI") + app.Spec = "[OPTIONS]" + app.Command("start", "start a new task", start) + app.Command("init", "initialize the sqlite database", initialize) + app.Command("ls", "list historical tasks", list) + app.Run(os.Args) +} diff --git a/store.go b/store.go new file mode 100644 index 0000000..48c0ae1 --- /dev/null +++ b/store.go @@ -0,0 +1,11 @@ +package main + +type Store struct{} + +func NewStore(path string) (*Store, error) { + return &Store{}, nil +} + +func (s Store) AddTask(task Task) (int, error) { return 0, nil } + +func (s Store) AddPomo(pomo Pomo) error { return nil } diff --git a/types.go b/types.go new file mode 100644 index 0000000..2054ede --- /dev/null +++ b/types.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "os/exec" + "time" +) + +// Task describes some activity +type Task struct { + ID int `json:"id"` + Name string `json:"name"` + count int + duration time.Duration +} + +// Pomo is a stetch of work performed on a +// specific task. +type Pomo struct { + TaskID int `json:"task_id"` + Start time.Time `json:"start"` + End time.Time `json:"end"` +} + +// Prompter prompts a user with a message. +type Prompter interface { + Prompt(string) error +} + +// I3 implements a prompter for i3 +type I3 struct{} + +func (i *I3) Prompt(message string) error { + raw, err := exec.Command( + "/bin/i3-nagbar", + "-m", + message, + ).Output() + if err != nil { + return err + } + fmt.Println(string(raw)) + return nil +}