thyme 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. data/README.md +13 -30
  2. data/thyme +6 -1
  3. data/thyme.rb +108 -1
  4. data/thyme_test.rb +22 -4
  5. metadata +18 -2
data/README.md CHANGED
@@ -14,7 +14,7 @@ Usage
14
14
  Start thyme with:
15
15
 
16
16
  $ thyme
17
- [=.........................] 25m
17
+ [=== ] 24:59
18
18
 
19
19
  You'll have 25 minutes by default. `Ctrl-C` to interrupt. You can also start
20
20
  it in daemon mode, which is only useful if you've got tmux integration to notify
@@ -32,66 +32,49 @@ Thyme is configurable and extensible. All configurations live in the
32
32
  `~/.thymerc` file:
33
33
 
34
34
  set :timer, 25
35
- set :outfile, "~/.thyme-tmux"
35
+ set :tmux, true
36
36
 
37
- option :o, :open, 'opens today & records sheets' do
38
- `vim -O ~/.thyme-today.md ~/.thyme-records.md`
37
+ option :o, :open, 'open sheets' do
38
+ `vim -O ~/.thyme-today.md ~/.thyme-records.md < \`tty\` > \`tty\``
39
39
  end
40
40
 
41
41
  before do
42
- puts "Get ready, get set, GO!"
42
+ `mplayer ~/music/flight-of-the-bumble-bee.mp3 &`
43
43
  end
44
44
 
45
45
  after do
46
- `mplayer ~/music/wohoo.mp3`
47
- `vim -O ~/.thyme-today.md`
46
+ `notify-send -u critical "0:00 Thymes Up!"`
48
47
  end
49
48
 
50
49
  The `set` method sets different configurations. There are only two:
51
50
 
52
51
  * `:timer` is the number of minutes to countdown from
53
- * `:outfile` is the file to write out progress to for tmux integration
52
+ * `:tmux` is whether or not you want tmux integration on (off by default)
54
53
 
55
54
  The `option` method adds new options to the `thyme` command. In the above
56
55
  example, we can now execute `thyme -o`. Use `thyme -h` to see available
57
56
  options.
58
57
 
59
58
  The `before` and `after` adds hooks to our timer. Now before the timer starts,
60
- STDOUT will receive a message. After the timer ends, vim will open our today
61
- sheet.
59
+ an mp3 will play. After the timer ends, a notification will be sent.
62
60
 
63
61
  Integration
64
62
  ===========
65
63
 
66
- For tmux integration, make sure to set the outfile in `~/.thymerc`:
64
+ For tmux integration, make sure to set the `:tmux` option in `~/.thymerc`:
67
65
 
68
- set :outfile, "~/.thyme-tmux"
66
+ set :tmux, true
69
67
 
70
68
  Then in your `.tmux.conf` file:
71
69
 
72
70
  set-option -g status-right '#(cat ~/.thyme-tmux)'
71
+ set-option -g status-interval 1
73
72
 
74
73
  For vim integration, I like to execute `thyme -d` to toggle the timer. This only
75
74
  works if you have tmux integration setup for the countdown:
76
75
 
77
- nmap <leader>t :!thyme -d
78
- nmap <leader>T :!thyme -s
79
-
80
- TODO
81
- ====
82
-
83
- * add directory stucture (binary, lib file, tests, Rakefile, gemspec)
84
- * add `--help`
85
- * add 25 minute timer
86
- * add progress bar
87
- * add `--daemon` switch and `--stop`
88
- * add config reader
89
- * add config `set`
90
- * add `set :timer`
91
- * add `set :outfile`
92
- * add config `option`
93
- * add config `before` and `after`
94
- * add color to outfile tmux integration (?)
76
+ nmap <leader>t :!thyme -d<cr>
77
+ nmap <leader>T :!thyme -s<cr>
95
78
 
96
79
  License
97
80
  =======
data/thyme CHANGED
@@ -2,11 +2,16 @@
2
2
  require 'optparse'
3
3
  require File.expand_path('thyme', File.dirname(__FILE__))
4
4
 
5
+ $0 = 'thyme'
5
6
  ARGV.options do |o|
7
+ thyme = Thyme.new
8
+ thyme.load_config(o)
6
9
  o.set_summary_indent(' ')
7
10
  o.banner = "Usage: #{File.basename($0)} [OPTION]"
8
11
  o.define_head "Timer for Pomodoro Technique"
12
+ o.on('-d', '--daemon', 'run in background') { thyme.daemonize! }
9
13
  o.on('-h', '--help', 'show this help message') { puts o; exit }
14
+ o.on('-s', '--stop', 'stops timer') { thyme.stop; exit }
10
15
  o.parse!
11
- puts o
16
+ thyme.run
12
17
  end
data/thyme.rb CHANGED
@@ -1,4 +1,111 @@
1
+ require 'ruby-progressbar'
2
+ require 'date'
3
+
1
4
  class Thyme
2
- VERSION = '0.0.1'
5
+ VERSION = '0.0.2'
3
6
  CONFIG_FILE = "#{ENV['HOME']}/.thymerc"
7
+ PID_FILE = "#{ENV['HOME']}/.thyme-pid"
8
+ TMUX_FILE = "#{ENV['HOME']}/.thyme-tmux"
9
+ OPTIONS = [:timer, :tmux]
10
+
11
+ def initialize
12
+ @timer = 25
13
+ @tmux = false
14
+ end
15
+
16
+ def run
17
+ @before.call if @before
18
+ start = @timer * 60
19
+ start_time = DateTime.now
20
+ seconds = start + 1
21
+ min_length = (seconds / 60).floor.to_s.length
22
+ tmux_file = File.open(TMUX_FILE, "w")
23
+ bar = ProgressBar.create(
24
+ title: format(seconds-1, min_length),
25
+ total: seconds,
26
+ length: 50,
27
+ format: '[%B] %t')
28
+ while !bar.finished? && seconds > 0
29
+ seconds = start - seconds_since(start_time)
30
+ title = format(seconds, min_length)
31
+ fg = color(seconds)
32
+ bar.title = title
33
+ bar.increment
34
+ if @tmux
35
+ tmux_file.truncate(0)
36
+ tmux_file.rewind
37
+ tmux_file.write("#[default]#[fg=#{fg}]#{title}#[default]")
38
+ tmux_file.flush
39
+ end
40
+ sleep(1)
41
+ end
42
+ rescue SignalException => e
43
+ puts ""
44
+ ensure
45
+ tmux_file.close
46
+ @after.call if @after && seconds <= 0
47
+ stop
48
+ end
49
+
50
+ def stop
51
+ File.delete(TMUX_FILE) if File.exists?(TMUX_FILE)
52
+ if File.exists?(PID_FILE)
53
+ pid = File.read(PID_FILE).to_i
54
+ File.delete(PID_FILE)
55
+ Process.kill('TERM', pid) if pid > 1
56
+ end
57
+ end
58
+
59
+ def daemonize!
60
+ Process.daemon
61
+ File.open(PID_FILE, "w") { |f| f.print(Process.pid) }
62
+ end
63
+
64
+ def set(opt, val)
65
+ raise ThymeError.new("Invalid option: #{opt}") if !OPTIONS.include?(opt.to_sym)
66
+ self.instance_variable_set("@#{opt}", val)
67
+ end
68
+
69
+ def before(&block)
70
+ @before = block
71
+ end
72
+
73
+ def after(&block)
74
+ @after = block
75
+ end
76
+
77
+ def option(optparse, short, long, desc, &block)
78
+ optparse.on("-#{short}", "--#{long}", desc) { block.call; exit }
79
+ end
80
+
81
+ def load_config(optparse)
82
+ return if !File.exists?(CONFIG_FILE)
83
+ app = self
84
+ Object.class_eval do
85
+ define_method(:set) { |opt,val| app.set(opt,val) }
86
+ define_method(:before) { |&block| app.before(&block) }
87
+ define_method(:after) { |&block| app.after(&block) }
88
+ define_method(:option) { |sh,lo,desc,&b| app.option(optparse,sh,lo,desc,&b) }
89
+ end
90
+ load(CONFIG_FILE, true)
91
+ end
92
+
93
+ private
94
+ def seconds_since(time)
95
+ ((DateTime.now - time) * 24 * 60 * 60).to_i
96
+ end
97
+
98
+ def format(seconds, min_length)
99
+ min = (seconds / 60).floor
100
+ lead = ' ' * (min_length - min.to_s.length)
101
+ sec = (seconds % 60).floor
102
+ sec = "0#{sec}" if sec.to_s.length == 1
103
+ "#{lead}#{min}:#{sec}"
104
+ end
105
+
106
+ def color(seconds)
107
+ seconds < (5*60) ? 'red,bold' : 'default'
108
+ end
4
109
  end
110
+
111
+ class ThymeError < StandardError; end;
data/thyme_test.rb CHANGED
@@ -1,12 +1,30 @@
1
1
  require 'rubygems'
2
2
  require "#{File.dirname(__FILE__)}/thyme"
3
- require 'minitest/autorun'
3
+ require 'minitest'
4
4
 
5
- class ThymeTest < MiniTest::Unit::TestCase
5
+ Minitest.autorun
6
+
7
+ class ThymeTest < Minitest::Test
6
8
  def setup
9
+ @thyme = Thyme.new
10
+ end
11
+
12
+ def test_format
13
+ assert_equal('25:00', @thyme.send(:format, 25*60, 2))
14
+ assert_equal('24:59', @thyme.send(:format, 25*60-1, 2))
15
+ assert_equal(' 5:00', @thyme.send(:format, 5*60, 2))
16
+ assert_equal(' 4:05', @thyme.send(:format, 4*60+5, 2))
17
+ end
18
+
19
+ def test_color
20
+ assert_equal('default', @thyme.send(:color, 5*60))
21
+ assert_equal('red,bold', @thyme.send(:color, 5*60-1))
7
22
  end
8
23
 
9
- def test_truth
10
- assert(true)
24
+ def test_set
25
+ assert_equal(25, @thyme.instance_variable_get('@timer'))
26
+ @thyme.set(:timer, 20)
27
+ assert_equal(20, @thyme.instance_variable_get('@timer'))
28
+ assert_raises(ThymeError) { @thyme.set(:invalid, nil) }
11
29
  end
12
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thyme
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: .
11
11
  cert_chain: []
12
- date: 2013-05-30 00:00:00.000000000 Z
12
+ date: 2013-05-31 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ruby-progressbar
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: minitest
16
32
  requirement: !ruby/object:Gem::Requirement