pomodoro 1.0.0
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.
- data/.autotest +9 -0
- data/.gitignore +5 -0
- data/.rvmrc +1 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +48 -0
- data/README.md +49 -0
- data/Rakefile +11 -0
- data/autotest/discover.rb +1 -0
- data/bin/pomodoro +20 -0
- data/lib/pomodoro/config.ru +3 -0
- data/lib/pomodoro/version.rb +3 -0
- data/lib/pomodoro.rb +79 -0
- data/pomodoro.gemspec +23 -0
- data/spec/command_spec.rb +27 -0
- data/spec/pomodoro_spec.rb +102 -0
- data/spec/spec_helper.rb +7 -0
- metadata +122 -0
data/.autotest
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.2@pomodoro
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
pomodoro (1.0.0)
|
5
|
+
noprocrast
|
6
|
+
sinatra
|
7
|
+
thin
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
autotest (4.4.5)
|
13
|
+
chronic (0.3.0)
|
14
|
+
daemons (1.1.0)
|
15
|
+
diff-lcs (1.1.2)
|
16
|
+
eventmachine (0.12.10)
|
17
|
+
noprocrast (0.1.6)
|
18
|
+
rack (1.2.1)
|
19
|
+
rspec (2.1.0)
|
20
|
+
rspec-core (~> 2.1.0)
|
21
|
+
rspec-expectations (~> 2.1.0)
|
22
|
+
rspec-mocks (~> 2.1.0)
|
23
|
+
rspec-core (2.1.0)
|
24
|
+
rspec-expectations (2.1.0)
|
25
|
+
diff-lcs (~> 1.1.2)
|
26
|
+
rspec-mocks (2.1.0)
|
27
|
+
sinatra (1.1.0)
|
28
|
+
rack (~> 1.1)
|
29
|
+
tilt (~> 1.1)
|
30
|
+
thin (1.2.7)
|
31
|
+
daemons (>= 1.0.9)
|
32
|
+
eventmachine (>= 0.12.6)
|
33
|
+
rack (>= 1.0.0)
|
34
|
+
tilt (1.1)
|
35
|
+
timecop (0.3.5)
|
36
|
+
|
37
|
+
PLATFORMS
|
38
|
+
ruby
|
39
|
+
|
40
|
+
DEPENDENCIES
|
41
|
+
autotest
|
42
|
+
chronic
|
43
|
+
noprocrast
|
44
|
+
pomodoro!
|
45
|
+
rspec (~> 2.1.0)
|
46
|
+
sinatra
|
47
|
+
thin
|
48
|
+
timecop
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
Pomodoro
|
2
|
+
========
|
3
|
+
|
4
|
+
A gem to make you productive.
|
5
|
+
|
6
|
+
Wait, what?
|
7
|
+
-----------
|
8
|
+
|
9
|
+
Yeah, that's right. See, there's this great [noprocrast gem](https://github.com/rfwatson/noprocrast) that tuns off your access to time-sucking sites, like Twitter and Hacker News. The problem with the gem is that you have to turn it on and off yourself, and I don't have that kind of self-control. I'll forget to turn it back on, and then keep wasting time.
|
10
|
+
|
11
|
+
So I avoided doing more work by making Yet Another Gem: Pomodoro!
|
12
|
+
|
13
|
+
The Technique
|
14
|
+
-------------
|
15
|
+
|
16
|
+
The '[pomodoro technique](http://en.wikipedia.org/wiki/Pomodoro_Technique)' is a time-management technique named after tomatos. I have no idea, either. Basically, you work for 25 minutes, and then take a break for 5.
|
17
|
+
|
18
|
+
So what's it actually do?
|
19
|
+
-------------------------
|
20
|
+
|
21
|
+
Basically, when you start it up, it changes your /etc/hosts file to redirect websites to localhost. Then, it does two things: starts up `thin` to run a tiny website on localhost that tells you you're a bad person if you try to visit one of those sites, and spins up a thread to run in the background, that checks every 5 minutes to see if the timer is up. Once 25 minutes have gone by, it lets you back into your sites, and 5 minutes later, shuts you out again.
|
22
|
+
|
23
|
+
Oh, and you get growl notifications every time the switch happens.
|
24
|
+
|
25
|
+
How do I get it?
|
26
|
+
----------------
|
27
|
+
|
28
|
+
Small note: This only really works with OSX. Patches welcome!
|
29
|
+
|
30
|
+
Just `gem install pomodoro`. Easy-peasy!
|
31
|
+
|
32
|
+
How do I use it?
|
33
|
+
----------------
|
34
|
+
|
35
|
+
Just `sudo pomodoro start` in a terminal. If you're using rvm, you may want to `rvmsudo` instead.
|
36
|
+
|
37
|
+
Sudo is needed because noprocrast messes with your /etc/hosts file. Since that's neccesary, I also decided to run the local site on port 80, for simplicity's sake, and that takes root permissions too.
|
38
|
+
|
39
|
+
If this worries you, [check out the source](http://github.com/steveklabnik/pomodoro). It's real short. No tricks up my sleeve!
|
40
|
+
|
41
|
+
If you'd like to change the sites it blocks, `sudo noprocrast edit` will open your $EDITOR and let you change it up.
|
42
|
+
|
43
|
+
Future stuff
|
44
|
+
------------
|
45
|
+
|
46
|
+
* Eventually, I'm sure this could be useful on other platforms.
|
47
|
+
* Maybe a simple to-do list with HTML5 local storage could be cool, rather than yelling. Dunno.
|
48
|
+
* Pretty icons for growl
|
49
|
+
* Growl notifications on how much time you have left.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
data/bin/pomodoro
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require './lib/pomodoro'
|
4
|
+
require 'thin'
|
5
|
+
|
6
|
+
rackup_file = "./lib/pomodoro/config.ru"
|
7
|
+
|
8
|
+
Thread.new do
|
9
|
+
loop do
|
10
|
+
Pomodoro.work
|
11
|
+
sleep 300 # sleep for 5 minutes
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
argv = ARGV
|
16
|
+
argv << ["-R", rackup_file] unless ARGV.include?("-R")
|
17
|
+
argv << ["-p", "80"] unless ARGV.include?("-p")
|
18
|
+
argv << ["-e", "production"] unless ARGV.include?("-e")
|
19
|
+
Thin::Runner.new(argv.flatten).run!
|
20
|
+
|
data/lib/pomodoro.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
require 'sinatra'
|
4
|
+
require 'noprocrast'
|
5
|
+
|
6
|
+
module Pomodoro
|
7
|
+
class << self
|
8
|
+
def start!
|
9
|
+
Noprocrast.activate!
|
10
|
+
@start_time = Time.now
|
11
|
+
work_growl
|
12
|
+
@stopped = false
|
13
|
+
end
|
14
|
+
def stop!
|
15
|
+
Noprocrast.deactivate!
|
16
|
+
break_growl
|
17
|
+
@stopped = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def work
|
21
|
+
@start_time = Time.now if @start_time.nil?
|
22
|
+
elapsed_time = Time.now - @start_time
|
23
|
+
if elapsed_time >= 1800 && @stopped == true # 30 minutes * 60 seconds
|
24
|
+
start!
|
25
|
+
elsif elapsed_time >= 1500 && @stopped == false # 25 minutes * 60 seconds
|
26
|
+
stop!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def break_growl
|
31
|
+
system 'growlnotify -w -n Pomodoro -m "You have 5 minutes." "BREAK TIME"'
|
32
|
+
end
|
33
|
+
|
34
|
+
def work_growl
|
35
|
+
system 'growlnotify -w -n Pomodoro -m "This lasts 25 minutes." "WORK TIME"'
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class PomodoroServer < Sinatra::Base
|
42
|
+
enable :sessions
|
43
|
+
|
44
|
+
|
45
|
+
get "/" do
|
46
|
+
session[:visits] ||= 0
|
47
|
+
session[:visits] += 1
|
48
|
+
"<!DOCTYPE html>
|
49
|
+
<html lang='en'>
|
50
|
+
<head>
|
51
|
+
<meta charset='utf-8' />
|
52
|
+
<style type='text/css'>
|
53
|
+
/*<![CDATA[*/
|
54
|
+
h1 {
|
55
|
+
font-family: Verdana, Arial, sans-serif;
|
56
|
+
font-size: 96px;
|
57
|
+
font-weight: bold;
|
58
|
+
text-align: center;
|
59
|
+
padding-top: 50px;
|
60
|
+
}
|
61
|
+
h2 {
|
62
|
+
font-family: Verdana, Arial, sans-serif;
|
63
|
+
font-size: 72px;
|
64
|
+
font-weight: bold;
|
65
|
+
text-align: center;
|
66
|
+
}
|
67
|
+
/*]]>*/
|
68
|
+
</style>
|
69
|
+
|
70
|
+
</head>
|
71
|
+
<body>
|
72
|
+
<h1>GET BACK TO WORK!</h1>
|
73
|
+
<h2>YOU'VE BEEN HERE #{session[:visits]} TIMES THIS BREAK!</h2>
|
74
|
+
</body>
|
75
|
+
</html>"
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
data/pomodoro.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "pomodoro/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "pomodoro"
|
7
|
+
s.version = Pomodoro::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Steve Klabnik"]
|
10
|
+
s.email = ["steve@steveklabnik.com"]
|
11
|
+
s.homepage = "http://github.com/steveklabnik/pomodoro"
|
12
|
+
s.summary = %q{Turns off certain sites in conjunction with pomodoro timekeeping.}
|
13
|
+
s.description = %q{I can never get work done because the internet makes it too easy to waste time. This turns off access to sites, but lets you on every so often, too.}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency("noprocrast")
|
21
|
+
s.add_dependency("thin")
|
22
|
+
s.add_dependency("sinatra")
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
describe "command line tool" do
|
2
|
+
|
3
|
+
it "exists" do
|
4
|
+
failed = false
|
5
|
+
begin
|
6
|
+
`pomodoro`
|
7
|
+
rescue Errno::ENOENT
|
8
|
+
fail
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "start" do
|
13
|
+
|
14
|
+
# this doesn't work, for some reason. I think it's because
|
15
|
+
# the file reloads the gem, maybe? Not sure. Sucks, though.
|
16
|
+
#it "should delegate to Pomodoro#start" do
|
17
|
+
# Pomodoro.should_receive(:start)
|
18
|
+
# `./bin/pomodoro start`
|
19
|
+
#end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "stop" do
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# I'm not sure why these don't work, since they're in the spec_helper...
|
2
|
+
require 'noprocrast'
|
3
|
+
require './lib/pomodoro'
|
4
|
+
require 'timecop'
|
5
|
+
require 'chronic'
|
6
|
+
|
7
|
+
describe Pomodoro do
|
8
|
+
|
9
|
+
before :all do
|
10
|
+
#all of these methods have ugly side effects, so let's just
|
11
|
+
#redefine them as noops
|
12
|
+
def Noprocrast.activate!
|
13
|
+
end
|
14
|
+
def Noprocrast.deactivate!
|
15
|
+
end
|
16
|
+
def Pomodoro.break_growl
|
17
|
+
end
|
18
|
+
def Pomodoro.work_growl
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#start!" do
|
23
|
+
|
24
|
+
it "uses noprocrast" do
|
25
|
+
Noprocrast.should_receive(:activate!)
|
26
|
+
Pomodoro.start!
|
27
|
+
end
|
28
|
+
|
29
|
+
it "saves its start time" do
|
30
|
+
Timecop.freeze do
|
31
|
+
Pomodoro.start!
|
32
|
+
Pomodoro.instance_variable_get(:@start_time).should == Time.now
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "growls" do
|
37
|
+
Pomodoro.should_receive(:work_growl)
|
38
|
+
Pomodoro.start!
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#stop!" do
|
44
|
+
|
45
|
+
it "uses noprocrast" do
|
46
|
+
Noprocrast.should_receive(:deactivate!)
|
47
|
+
Pomodoro.stop!
|
48
|
+
end
|
49
|
+
|
50
|
+
it "growls" do
|
51
|
+
Pomodoro.should_receive(:break_growl)
|
52
|
+
Pomodoro.stop!
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#work" do
|
58
|
+
|
59
|
+
it "doesn't call #stop! for the first 24 minutes" do
|
60
|
+
Pomodoro.start!
|
61
|
+
Pomodoro.should_not_receive(:stop!)
|
62
|
+
Timecop.travel(Chronic.parse('24 minutes from now'))
|
63
|
+
Pomodoro.work
|
64
|
+
Timecop.return
|
65
|
+
end
|
66
|
+
|
67
|
+
it "calls #stop! after 25 minutes" do
|
68
|
+
Pomodoro.start!
|
69
|
+
Pomodoro.should_receive(:stop!)
|
70
|
+
Timecop.travel(Chronic.parse('26 minutes from now'))
|
71
|
+
Pomodoro.work
|
72
|
+
Timecop.return
|
73
|
+
end
|
74
|
+
|
75
|
+
it "doesn't call #start! for the first 29 minutes" do
|
76
|
+
Pomodoro.start!
|
77
|
+
Pomodoro.should_not_receive(:start!)
|
78
|
+
Timecop.travel(Chronic.parse('29 minutes from now'))
|
79
|
+
Pomodoro.work
|
80
|
+
Timecop.return
|
81
|
+
end
|
82
|
+
|
83
|
+
it "calls #start! after 30 minutes" do
|
84
|
+
Pomodoro.start!
|
85
|
+
Pomodoro.should_receive(:start!)
|
86
|
+
Pomodoro.instance_variable_set(:@stopped, true)
|
87
|
+
Timecop.travel(Chronic.parse('31 minutes from now'))
|
88
|
+
Pomodoro.work
|
89
|
+
Timecop.return
|
90
|
+
end
|
91
|
+
|
92
|
+
it "sets @start_time if it's not set" do
|
93
|
+
Pomodoro.instance_variable_set(:@start_time, nil)
|
94
|
+
Timecop.freeze do
|
95
|
+
Pomodoro.work
|
96
|
+
Pomodoro.instance_variable_get(:@start_time).should == Time.now
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pomodoro
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 1.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Steve Klabnik
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-11-28 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: noprocrast
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
prerelease: false
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: thin
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
segments:
|
41
|
+
- 0
|
42
|
+
version: "0"
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sinatra
|
48
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 0
|
55
|
+
version: "0"
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *id003
|
59
|
+
description: I can never get work done because the internet makes it too easy to waste time. This turns off access to sites, but lets you on every so often, too.
|
60
|
+
email:
|
61
|
+
- steve@steveklabnik.com
|
62
|
+
executables:
|
63
|
+
- pomodoro
|
64
|
+
extensions: []
|
65
|
+
|
66
|
+
extra_rdoc_files: []
|
67
|
+
|
68
|
+
files:
|
69
|
+
- .autotest
|
70
|
+
- .gitignore
|
71
|
+
- .rvmrc
|
72
|
+
- Gemfile
|
73
|
+
- Gemfile.lock
|
74
|
+
- README.md
|
75
|
+
- Rakefile
|
76
|
+
- autotest/discover.rb
|
77
|
+
- bin/pomodoro
|
78
|
+
- lib/pomodoro.rb
|
79
|
+
- lib/pomodoro/config.ru
|
80
|
+
- lib/pomodoro/version.rb
|
81
|
+
- pomodoro.gemspec
|
82
|
+
- spec/command_spec.rb
|
83
|
+
- spec/pomodoro_spec.rb
|
84
|
+
- spec/spec_helper.rb
|
85
|
+
has_rdoc: true
|
86
|
+
homepage: http://github.com/steveklabnik/pomodoro
|
87
|
+
licenses: []
|
88
|
+
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 177127893593783456
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
hash: 177127893593783456
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
version: "0"
|
112
|
+
requirements: []
|
113
|
+
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 1.3.7
|
116
|
+
signing_key:
|
117
|
+
specification_version: 3
|
118
|
+
summary: Turns off certain sites in conjunction with pomodoro timekeeping.
|
119
|
+
test_files:
|
120
|
+
- spec/command_spec.rb
|
121
|
+
- spec/pomodoro_spec.rb
|
122
|
+
- spec/spec_helper.rb
|