From ffb14c8b1e0895b707f79c97c443d1b24f27a8ee Mon Sep 17 00:00:00 2001 From: Blake Knight Date: Tue, 26 May 2020 12:59:53 -0500 Subject: [PATCH 1/3] :construction: WIP - rewriting in Go Right now, most features work. The main thing is the notifications seem to only work randomly and do not have sound --- .gitignore | 6 -- Info.plist | 37 ++++++++++++ Makefile | 22 ------- README.md | 20 +------ go.mod | 8 +++ go.sum | 4 ++ notifier_mac/notifier_mac.v | 15 ----- pomodoro.go | 55 +++++++++++++++++ pomodoro.v | 115 ------------------------------------ 9 files changed, 105 insertions(+), 177 deletions(-) create mode 100644 Info.plist delete mode 100644 Makefile create mode 100644 go.mod create mode 100644 go.sum delete mode 100644 notifier_mac/notifier_mac.v create mode 100644 pomodoro.go delete mode 100644 pomodoro.v diff --git a/.gitignore b/.gitignore index 56c0e93..9b18729 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,2 @@ -*.dSYM -.vrepl* *.exe -*.o -.*.c -*.obj -*.pdb pomodoro diff --git a/Info.plist b/Info.plist new file mode 100644 index 0000000..9874b19 --- /dev/null +++ b/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleExecutable + pomodoro + CFBundleIconFile + Terminal + CFBundleIdentifier + blakek.pomodoro + CFBundleInfoDictionaryVersion + 2.0 + CFBundleName + pomodoro + CFBundlePackageType + APPL + CFBundleShortVersionString + 2.0.0 + CFBundleSignature + ???? + CFBundleVersion + 2 + LSMinimumSystemVersion + 10.9.0 + LSUIElement + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSHumanReadableCopyright + Copyright © 2020 Blake Knight + NSUserNotificationAlertStyle + alert + + diff --git a/Makefile b/Makefile deleted file mode 100644 index 901fc0d..0000000 --- a/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -PREFIX ?= /usr/local/bin -V ?= v - -all: pomodoro - -clean: - $(RM) -r .*.dSYM - $(RM) .vrepl* - $(RM) .*. - -# Moves the build binary to the installation prefix -install: pomodoro - mv -i `pwd`/pomodoro ${PREFIX}/pomodoro - -# Makes the pomodoro executable -pomodoro: - ${V} -prod -o pomodoro pomodoro.v - @echo "Successfully built pomodoro" - -# Alternate to install. Symlinks from this directory to the installation prefix -symlink: pomodoro - ln -is `pwd`/pomodoro ${PREFIX}/pomodoro diff --git a/README.md b/README.md index ffe0564..94514ba 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,6 @@ The point of pomodoro timers is to help you focus and save time. Unfortunately, I found myself wasting time with other tools. To fix that, I spent a few minutes making a simple timer for use in the terminal. -⚠️ Right now, due to notifications, this is macOS-only. My plan is to work on a -cross-platform notification system for [V](https://github.com/vlang/v). Once -that's done, this project will be updated. Two lines can be commented out for a -fully terminal-based system, but that's not what I want. - ## Usage Here are some common ways to use the timer: @@ -70,15 +65,7 @@ file](https://github.com/blakek/pomodoro/archive/master.zip). Then, in a terminal open to this project's directory, run make: ``` -$ make install -``` - -This will compile the binary and move it to a directory. The default install -directory is `/usr/local/bin`. You can change this by setting the `PREFIX` -variable: - -``` -$ PREFIX=/custom/directory make install +$ go build ``` ## Updating @@ -89,11 +76,6 @@ The easiest way to update from a source build is to re-run the install directions. If you keep the repository, you can occasionally run `git pull && make install` to build using the latest changes. -## See Also - -- [`vlang/v`](https://github.com/vlang/v) - The language this project is written - in. - ## License MIT diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3ccecde --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/blakek/pomodoro + +go 1.14 + +require ( + github.com/jessevdk/go-flags v1.4.0 + github.com/teddywing/go-notifier v0.0.0-20200310234431-5e1b28caa8d8 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6ca2513 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/teddywing/go-notifier v0.0.0-20200310234431-5e1b28caa8d8 h1:cl8PbHn7xkcaXINlURo1d2KGMRk0vKEPzKd1mGfBugM= +github.com/teddywing/go-notifier v0.0.0-20200310234431-5e1b28caa8d8/go.mod h1:HYeB+M9E41qThdA+HapliBZjZcMZton2V8HxUZUYBLs= diff --git a/notifier_mac/notifier_mac.v b/notifier_mac/notifier_mac.v deleted file mode 100644 index 28dd8cf..0000000 --- a/notifier_mac/notifier_mac.v +++ /dev/null @@ -1,15 +0,0 @@ -module notifier_mac - -import os - -struct Options { - sound_name string - text string - title string -} - -pub fn show_notification(options Options) { - command := 'osascript -e \'display notification "${options.text}" with title "${options.title}" sound name "${options.sound_name}"\'' - - os.system(command) -} diff --git a/pomodoro.go b/pomodoro.go new file mode 100644 index 0000000..7702ec0 --- /dev/null +++ b/pomodoro.go @@ -0,0 +1,55 @@ +package main + +import ( + "fmt" + "time" + + "github.com/jessevdk/go-flags" + "github.com/teddywing/go-notifier" +) + +var arguments struct { + CustomMinutes float64 `long:"custom" short:"c" description:"start a custom timer for given number of minutes" default:"25"` + RunShortTimer bool `long:"short" short:"s" description:"starts a timer for 5 minutes"` + RunLongTimer bool `long:"long" short:"l" description:"starts a timer for 20 minutes"` +} + +func printTime(time int) { + minutes := time / 60 + seconds := time % 60 + + fmt.Printf("\033[2K\r%v:%02v remaining", minutes, seconds) +} + +func main() { + var minutes float64 + + flags.Parse(&arguments) + + if arguments.RunLongTimer { + minutes = 20.0 + } else if arguments.RunShortTimer { + minutes = 5.0 + } else { + minutes = arguments.CustomMinutes + } + + seconds := int(minutes * 60) + + for i := seconds; i > 0; i-- { + printTime(i) + time.Sleep(1 * time.Second) + } + + // Print final newline + fmt.Println() + + notification := notifier.Notification{ + Title: "This is the title", + Message: "This is the message", + } + + systemNotifier, _ := notifier.NewNotifier() + + systemNotifier.DeliverNotification(notification) +} diff --git a/pomodoro.v b/pomodoro.v deleted file mode 100644 index 94d4069..0000000 --- a/pomodoro.v +++ /dev/null @@ -1,115 +0,0 @@ -import notifier_mac -import os -import time - -struct Arguments { - minutes f32 - show_help bool -} - -fn print_time(time i64) { - minutes := int(time / 60) - seconds := time % 60 - - print('\e[2K\r${minutes}:${seconds:02d} remaining') - - // Don't optimize output timing; print immediately. - C.fflush(stdout) -} - -fn show_help() { - println('Usage: pomodoro [options]') - println('') - println('Examples:') - println(' Start a standard pomodoro timer for 25 minutes:') - println(' pomodoro') - println(' Start a short (5 minute) break:') - println(' pomodoro -s') - println(' Start a 3 minute timer for tea:') - println(' pomodoro -c 3') - println('') - println('Options:') - println(' -c time, --custom time start a custom timer (time in minutes)') - println(' -h, --help show this help text') - println(' -l, --long starts the timer for 20 minutes') - println(' -s, --short starts the timer for 5 minutes') -} - -fn parse_arguments(args []string, defaultValues Arguments) Arguments { - if args.len == 0 { - return defaultValues - } - - arg := args[0] - - if arg in ['-c', '--custom'] { - return parse_arguments( - args.slice(2, args.len), - { defaultValues | minutes: args[1].f32() } - ) - } - - if arg in ['-h', '--help'] { - return parse_arguments( - args.slice(1, args.len), - { defaultValues | show_help: true } - ) - } - - if arg in ['-l', '--long'] { - return parse_arguments( - args.slice(1, args.len), - { defaultValues | minutes: 20 } - ) - } - - if arg in ['-s', '--short'] { - return parse_arguments( - args.slice(1, args.len), - { defaultValues | minutes: 5 } - ) - } - - println('Unknown argument ${arg}') - exit(1) -} - -fn main() { - // Get arguments - arguments := parse_arguments( - os.args.slice(1, os.args.len), - Arguments { - minutes: 25 - show_help: false - } - ) - - // If help specified, show help and exit - if arguments.show_help { - show_help() - exit(0) - } - - // Take in minutes for easier typing, but use seconds so we know how much - // time is left - seconds := int(arguments.minutes * 60) - - for i := seconds; i > 0; i-- { - print_time(i) - time.sleep(1) - } - - notification_minutes := seconds / 60 - notification_seconds := seconds % 60 - - notification_options := notifier_mac.Options { - sound_name: 'default', - text: 'Finished ${notification_minutes}min ${notification_seconds:d}s timer' - title: 'Pomodoro' - } - - notifier_mac.show_notification(notification_options) - - // Print extra newline so next command is on a new line - println('') -} From 67d76cd6bda290560edc6ac828e7177bfd6914db Mon Sep 17 00:00:00 2001 From: Blake Knight Date: Wed, 16 Dec 2020 22:44:52 -0600 Subject: [PATCH 2/3] :sparkles: rewrite in Go - fixes notifications not working on macOS - shows time the timer completed - the `--custom` flag has been changed from accepting time in minutes (e.g. `15`) to accepting a duration string (e.g. `1h2m3s`) - changes from using `time.Sleep()` to `time.Ticker` --- go.mod | 2 +- go.sum | 4 ++-- pomodoro.go | 65 ++++++++++++++++++++++++++++++++++------------------- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 3ccecde..c280a98 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,6 @@ module github.com/blakek/pomodoro go 1.14 require ( + github.com/blakek/go-notifier v0.1.0 github.com/jessevdk/go-flags v1.4.0 - github.com/teddywing/go-notifier v0.0.0-20200310234431-5e1b28caa8d8 ) diff --git a/go.sum b/go.sum index 6ca2513..a95d9f0 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,4 @@ +github.com/blakek/go-notifier v0.1.0 h1:ZhB7OVgbfXWL9m919xvqCfwoSsoen4oFzVUr+m1Ozec= +github.com/blakek/go-notifier v0.1.0/go.mod h1:vRLSkYnhnPiXD1kgtpBh6JpZDkFfVDdcn1dz7/rQObM= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/teddywing/go-notifier v0.0.0-20200310234431-5e1b28caa8d8 h1:cl8PbHn7xkcaXINlURo1d2KGMRk0vKEPzKd1mGfBugM= -github.com/teddywing/go-notifier v0.0.0-20200310234431-5e1b28caa8d8/go.mod h1:HYeB+M9E41qThdA+HapliBZjZcMZton2V8HxUZUYBLs= diff --git a/pomodoro.go b/pomodoro.go index 7702ec0..b4f5499 100644 --- a/pomodoro.go +++ b/pomodoro.go @@ -2,54 +2,73 @@ package main import ( "fmt" + "os" "time" + "github.com/blakek/go-notifier" "github.com/jessevdk/go-flags" - "github.com/teddywing/go-notifier" ) var arguments struct { - CustomMinutes float64 `long:"custom" short:"c" description:"start a custom timer for given number of minutes" default:"25"` - RunShortTimer bool `long:"short" short:"s" description:"starts a timer for 5 minutes"` - RunLongTimer bool `long:"long" short:"l" description:"starts a timer for 20 minutes"` + CustomTimer string `long:"custom" short:"c" description:"start a custom timer for given number of minutes" default:"25m"` + RunShortTimer bool `long:"short" short:"s" description:"starts a timer for 5 minutes"` + RunLongTimer bool `long:"long" short:"l" description:"starts a timer for 20 minutes"` } -func printTime(time int) { - minutes := time / 60 - seconds := time % 60 +func clearCurrentLine() { + fmt.Print("\033[2K\r") +} + +func printTime(timeRemaining time.Duration) { + clearCurrentLine() - fmt.Printf("\033[2K\r%v:%02v remaining", minutes, seconds) + if timeRemaining <= 0 { + fmt.Printf("Timer finished at %s\n", time.Now().Format(time.Kitchen)) + } else { + fmt.Printf("%s remaining", timeRemaining.String()) + } } func main() { - var minutes float64 - + var duration time.Duration flags.Parse(&arguments) if arguments.RunLongTimer { - minutes = 20.0 + duration = 20 * time.Minute } else if arguments.RunShortTimer { - minutes = 5.0 + duration = 5 * time.Minute } else { - minutes = arguments.CustomMinutes - } + var parseError error + duration, parseError = time.ParseDuration(arguments.CustomTimer) - seconds := int(minutes * 60) + if parseError != nil { + fmt.Fprintln(os.Stderr, parseError) + os.Exit(2) + } - for i := seconds; i > 0; i-- { - printTime(i) - time.Sleep(1 * time.Second) } - // Print final newline - fmt.Println() + ticker := time.NewTicker(time.Second) + timeRemaining := duration + + for range ticker.C { + timeRemaining = (timeRemaining - time.Second).Round(time.Second) + printTime(timeRemaining) + + if timeRemaining <= 0 { + break + } + } notification := notifier.Notification{ - Title: "This is the title", - Message: "This is the message", + Title: "Timer Finished", + Message: fmt.Sprintf("Finished %s timer", duration.String()), + Timeout: 15, } systemNotifier, _ := notifier.NewNotifier() - systemNotifier.DeliverNotification(notification) + + // HACK: tries to deliver notification before exiting + time.Sleep(time.Second) } From 43a6f5426a34db3ae6ae4ebe6d0c1653b6c8f89a Mon Sep 17 00:00:00 2001 From: Blake Knight Date: Wed, 16 Dec 2020 22:53:01 -0600 Subject: [PATCH 3/3] :pencil: add new --custom flag behavior; fix build instructions --- README.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 94514ba..effb156 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,13 @@ pomodoro -l **Start a 3 minute timer for tea:** ```bash -pomodoro -c 3 +pomodoro -c 3m +``` + +**Start a 1 hour, 2 minute, 3 second timer:** + +```bash +pomodoro -c 1h2m3s ``` If you want to see more details, here's all options at the time of writing: @@ -58,11 +64,10 @@ brew tap blakek/blakek && brew install blakek/blakek/pomodoro ### Build from Source -First, either [clone this -repo](https://help.github.com/articles/cloning-a-repository/) or [download a zip -file](https://github.com/blakek/pomodoro/archive/master.zip). +First, either [clone this repo](https://help.github.com/articles/cloning-a-repository/) +or [download a zip file](https://github.com/blakek/pomodoro/archive/master.zip). -Then, in a terminal open to this project's directory, run make: +Then, in a terminal open to this project's directory, build with Go: ``` $ go build @@ -72,9 +77,10 @@ $ go build If you installed using Homebrew, you can use the normal `brew upgrade` process. -The easiest way to update from a source build is to re-run the install -directions. If you keep the repository, you can occasionally run -`git pull && make install` to build using the latest changes. +The easiest way to update from a source build is to pull the latest changes +(e.g. `git pull`) and re-run the install directions. If you keep the +repository, you can occasionally run `git pull && go build` to build using the +latest changes. ## License