pmd 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +28 -0
- data/bin/pmd +9 -0
- data/lib/pmd.rb +14 -0
- data/lib/pmd/cli.rb +78 -0
- data/lib/pmd/config.rb +46 -0
- data/lib/pmd/counter.rb +40 -0
- data/lib/pmd/daemon.rb +153 -0
- data/lib/pmd/help.rb +15 -0
- data/lib/pmd/pause.rb +27 -0
- data/lib/pmd/reset.rb +17 -0
- data/lib/pmd/restart.rb +26 -0
- data/lib/pmd/stop.rb +27 -0
- data/lib/version.rb +5 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7efb6b7f80ac9f7e62347d74ae034ebb4c363a9c
|
4
|
+
data.tar.gz: f94a4e9409a0b297e1efa0b5cf9b855a5e8d4f4b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 044ea75324c8c95ae2d4c0cd4c8b0ee8291c98a9982df0a09929de266895296794f7b9f33fefdb8af2cbc405c5848ec40f9f80490d6c1276dbb0a6b7ae3fa270
|
7
|
+
data.tar.gz: bfbc3106fa4cee2be392382571bcec2c39a2af77455ea3ed22020b82c42542be5e30479253bea7c3eaa030bc775fee11a69e2dc0a5d05686ceacb9839ac7d0b0
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
pmd
|
2
|
+
====
|
3
|
+
|
4
|
+
My simple Pomodoro timer for Mac OS X, command line based.
|
5
|
+
|
6
|
+
<p style="text-align:center"><img src="http://i.imgur.com/Kk7CY.png" alt="pmd!!!"></p>
|
7
|
+
|
8
|
+
Installation
|
9
|
+
-------------
|
10
|
+
Please install:
|
11
|
+
|
12
|
+
* MacRuby
|
13
|
+
* Growl and growlnotify
|
14
|
+
|
15
|
+
Then clone this repository and add this to your `~/.bash_profile`:
|
16
|
+
|
17
|
+
alias pmd=/path/to/your/pmd/pmd
|
18
|
+
|
19
|
+
Usage
|
20
|
+
--------
|
21
|
+
|
22
|
+
Run:
|
23
|
+
|
24
|
+
pmd start
|
25
|
+
|
26
|
+
You will see a countdown timer at the top right corner of your screen. When it count to zero, you will see a Growl notification.
|
27
|
+
|
28
|
+
Configure Growl to make it emit sound.
|
data/bin/pmd
ADDED
data/lib/pmd.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "version.rb"
|
2
|
+
|
3
|
+
# pmd core
|
4
|
+
require "pmd/config.rb"
|
5
|
+
require "pmd/counter.rb"
|
6
|
+
require "pmd/restart.rb"
|
7
|
+
require "pmd/stop.rb"
|
8
|
+
require "pmd/pause.rb"
|
9
|
+
require "pmd/help.rb"
|
10
|
+
require "pmd/daemon.rb"
|
11
|
+
|
12
|
+
# master cli
|
13
|
+
require "pmd/cli.rb"
|
14
|
+
|
data/lib/pmd/cli.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module PMD
|
4
|
+
class CLI
|
5
|
+
@@commands = {
|
6
|
+
|
7
|
+
daemon: Daemon, #default as well
|
8
|
+
help: Help, # help
|
9
|
+
pause: Pause, # pause
|
10
|
+
restart: Restart, # restart
|
11
|
+
stop: Stop,
|
12
|
+
}
|
13
|
+
|
14
|
+
@@default = Daemon
|
15
|
+
|
16
|
+
@@aliases = {
|
17
|
+
|
18
|
+
:daemon => :d,
|
19
|
+
:help => :h,
|
20
|
+
:pause => :p, # finished
|
21
|
+
:restart => :restart,
|
22
|
+
}
|
23
|
+
|
24
|
+
def initialize(argv, stdin=STDIN, stdout=STDOUT, stderr=STDERR, kernel=Kernel)
|
25
|
+
@argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
|
26
|
+
end
|
27
|
+
|
28
|
+
def execute!
|
29
|
+
|
30
|
+
before
|
31
|
+
command_class = subcommand
|
32
|
+
command_class.new().execute!
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def before
|
38
|
+
|
39
|
+
if not File.directory? Config.base_dir
|
40
|
+
FileUtils.mkdir_p Config.base_dir
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def subcommand
|
46
|
+
|
47
|
+
if not @argv.length > 0
|
48
|
+
return @@default
|
49
|
+
end
|
50
|
+
|
51
|
+
keyword = @argv[0].to_sym
|
52
|
+
|
53
|
+
@@commands.each do |key, command_class|
|
54
|
+
|
55
|
+
aliases = nil
|
56
|
+
|
57
|
+
if @@aliases.has_key? key
|
58
|
+
# grab the key and then fill the aliases hash properly
|
59
|
+
value = @@aliases[key]
|
60
|
+
if value.kind_of?(Symbol)
|
61
|
+
aliases = [value]
|
62
|
+
else
|
63
|
+
aliases = value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
if keyword == key or (aliases and aliases.include?(keyword))
|
68
|
+
return command_class
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
return @@default
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
data/lib/pmd/config.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module PMD
|
2
|
+
|
3
|
+
class Config
|
4
|
+
|
5
|
+
@@base_dir = "/tmp/pmd"
|
6
|
+
@@update_frequency = 1 # number of seconds between updates
|
7
|
+
|
8
|
+
def self.base_dir
|
9
|
+
return @@base_dir
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.stop_path
|
13
|
+
return File.join @@base_dir, "stop"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.pause_path
|
17
|
+
return File.join @@base_dir, "pause"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.restart_path
|
21
|
+
return File.join @@base_dir, "restart"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.counter_path
|
25
|
+
return File.join @@base_dir, "counter"
|
26
|
+
end
|
27
|
+
|
28
|
+
# return seconds needed for pomodoro
|
29
|
+
def self.pomodoro_length
|
30
|
+
value = 25
|
31
|
+
value = 1
|
32
|
+
if ENV.key "POMODORO_LENGTH"
|
33
|
+
value = ENV["POMODORO_LENGTH"].to_i
|
34
|
+
end
|
35
|
+
return value * 60
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.break_length
|
39
|
+
value = 3
|
40
|
+
if ENV.key "POMODORO_BREAK_LENGTH"
|
41
|
+
value = ENV["POMODORO_BREAK_LENGTH"].to_i
|
42
|
+
end
|
43
|
+
return value * 60
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/pmd/counter.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module PMD
|
2
|
+
|
3
|
+
class Counter
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@value = 0
|
7
|
+
if File.exists? Config.counter_path
|
8
|
+
File.open Config.counter_path, "r" do |file|
|
9
|
+
file_value = file.read
|
10
|
+
if file_value and file_value.to_i
|
11
|
+
@value = file_value.to_i
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def value
|
18
|
+
# return current value
|
19
|
+
return @value
|
20
|
+
end
|
21
|
+
|
22
|
+
def reset
|
23
|
+
@value = 0
|
24
|
+
write @value
|
25
|
+
end
|
26
|
+
|
27
|
+
def increase
|
28
|
+
@value = @value + 1
|
29
|
+
write @value
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def write(value)
|
34
|
+
File.open Config.counter_path, "w" do |file|
|
35
|
+
file.write value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
data/lib/pmd/daemon.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module PMD
|
5
|
+
|
6
|
+
class MyAppDelegate
|
7
|
+
|
8
|
+
# declare class variables
|
9
|
+
def initialize
|
10
|
+
@started = false
|
11
|
+
@end_time = nil
|
12
|
+
@paused = false
|
13
|
+
@break = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def applicationDidFinishLaunching(notification)
|
17
|
+
menu = NSMenu.new
|
18
|
+
menu.initWithTitle "Pomodoro"
|
19
|
+
statusBar = NSStatusBar.systemStatusBar
|
20
|
+
@item = item = statusBar._statusItemWithLength(0, withPriority:2137483647)
|
21
|
+
item.length = 0
|
22
|
+
item.length = NSVariableStatusItemLength
|
23
|
+
NSTimer.scheduledTimerWithTimeInterval(1.0, target:self, selector: :"handler:", userInfo:nil, repeats:true)
|
24
|
+
start Config.pomodoro_length
|
25
|
+
end
|
26
|
+
|
27
|
+
def handler(sender)
|
28
|
+
# check to see if stop was flagged - this should exit
|
29
|
+
if stop_handler
|
30
|
+
return
|
31
|
+
# check to see if a restart was flagged
|
32
|
+
elsif restart_handler
|
33
|
+
return
|
34
|
+
# check to see if a pause was flagged
|
35
|
+
elsif pause_handler
|
36
|
+
return
|
37
|
+
else # normal run
|
38
|
+
update
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def stop_handler
|
44
|
+
if not Stop.stopped
|
45
|
+
return false
|
46
|
+
end
|
47
|
+
app = NSApplication.sharedApplication
|
48
|
+
app.terminate(self)
|
49
|
+
return true
|
50
|
+
end
|
51
|
+
|
52
|
+
def restart_handler
|
53
|
+
if not Restart.restarted
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
start Config.pomodoro_length
|
57
|
+
end
|
58
|
+
|
59
|
+
def pause_handler
|
60
|
+
|
61
|
+
is_paused = Pause.is_paused
|
62
|
+
if not @paused == is_paused #change of state
|
63
|
+
if is_paused
|
64
|
+
pause
|
65
|
+
else
|
66
|
+
unpause
|
67
|
+
end
|
68
|
+
end
|
69
|
+
# will call update if it isn't paused!
|
70
|
+
return @paused
|
71
|
+
end
|
72
|
+
|
73
|
+
def pause
|
74
|
+
@time_remaining = @end_time - Time.now
|
75
|
+
@paused = true
|
76
|
+
end
|
77
|
+
|
78
|
+
def unpause
|
79
|
+
if not @time_remaining
|
80
|
+
return start
|
81
|
+
end
|
82
|
+
@end_time = Time.now + @time_remaining
|
83
|
+
@paused = false
|
84
|
+
end
|
85
|
+
|
86
|
+
# utilities
|
87
|
+
def start(length = Config.pomodoro_length)
|
88
|
+
@end_time = Time.now + length
|
89
|
+
@running = true
|
90
|
+
update
|
91
|
+
end
|
92
|
+
|
93
|
+
def update
|
94
|
+
# determine the amount of difference between end_time and now
|
95
|
+
difference = @end_time - Time.now
|
96
|
+
if difference > 0
|
97
|
+
@item.title = title_string difference
|
98
|
+
else
|
99
|
+
restart
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def restart
|
104
|
+
# handle difference
|
105
|
+
if @break #currently on break start a normal pomodoro
|
106
|
+
@break = false
|
107
|
+
start Config.pomodoro_length
|
108
|
+
else
|
109
|
+
@break = true
|
110
|
+
Counter.new().increase
|
111
|
+
start Config.break_length
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def title_string difference
|
116
|
+
value = Counter.new().value
|
117
|
+
time_string = difference_to_formatted_string difference
|
118
|
+
if value > 0 and not @break
|
119
|
+
@item.title = "#{Counter.new().value} #{time_string}"
|
120
|
+
elsif @break
|
121
|
+
@item.title = "B #{time_string}"
|
122
|
+
else
|
123
|
+
@item.title = time_string
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def difference_to_formatted_string difference
|
128
|
+
minutes = (difference / 60).floor.to_s
|
129
|
+
seconds = (difference % 60).floor.to_s.rjust 2, "0"
|
130
|
+
return "#{minutes}:#{seconds}"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class Daemon
|
135
|
+
def initialize
|
136
|
+
# load up cocoa here instead of as a parent - to avoid weird error each time we run!
|
137
|
+
framework 'Cocoa'
|
138
|
+
# remove any files from previous runner
|
139
|
+
[Config.stop_path, Config.restart_path, Config.pause_path].each do |file|
|
140
|
+
if File.exists? file
|
141
|
+
FileUtils.rm file
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def execute!
|
147
|
+
app = NSApplication.sharedApplication
|
148
|
+
app.delegate = MyAppDelegate.new
|
149
|
+
app.run
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
data/lib/pmd/help.rb
ADDED
data/lib/pmd/pause.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module PMD
|
2
|
+
|
3
|
+
class Pause
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.is_paused
|
10
|
+
|
11
|
+
if File.exists? Config.pause_path
|
12
|
+
return true
|
13
|
+
end
|
14
|
+
return false
|
15
|
+
end
|
16
|
+
|
17
|
+
def execute!
|
18
|
+
|
19
|
+
if not File.exists? Config.pause_path
|
20
|
+
FileUtils.touch Config.pause_path
|
21
|
+
else
|
22
|
+
FileUtils.rm Config.pause_path
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/pmd/reset.rb
ADDED
data/lib/pmd/restart.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module PMD
|
4
|
+
|
5
|
+
class Restart
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.restarted
|
12
|
+
if File.exists? Config.restart_path
|
13
|
+
FileUtils.rm Config.restart_path
|
14
|
+
return true
|
15
|
+
else
|
16
|
+
return false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute!
|
21
|
+
FileUtils.touch Config.restart_path
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/pmd/stop.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module PMD
|
4
|
+
|
5
|
+
class Stop
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute!
|
12
|
+
|
13
|
+
FileUtils.touch Config.stop_path
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.stopped
|
18
|
+
if File.exists? Config.stop_path
|
19
|
+
FileUtils.rm Config.stop_path
|
20
|
+
return true
|
21
|
+
end
|
22
|
+
return false
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pmd
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jon Morehouse
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-10 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: MacRuby Pomodoro Timer. Places a timer in your status bar.
|
14
|
+
email:
|
15
|
+
- morehousej09@gmail.com
|
16
|
+
executables:
|
17
|
+
- pmd
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- README.md
|
22
|
+
- bin/pmd
|
23
|
+
- lib/pmd.rb
|
24
|
+
- lib/pmd/cli.rb
|
25
|
+
- lib/pmd/config.rb
|
26
|
+
- lib/pmd/counter.rb
|
27
|
+
- lib/pmd/daemon.rb
|
28
|
+
- lib/pmd/help.rb
|
29
|
+
- lib/pmd/pause.rb
|
30
|
+
- lib/pmd/reset.rb
|
31
|
+
- lib/pmd/restart.rb
|
32
|
+
- lib/pmd/stop.rb
|
33
|
+
- lib/version.rb
|
34
|
+
homepage: http://github.com/jonmorehouse/pmd
|
35
|
+
licenses:
|
36
|
+
- MIT
|
37
|
+
metadata: {}
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 2.2.2
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: Pomodoro Manager / Timer
|
58
|
+
test_files: []
|