pomodoro 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest ADDED
@@ -0,0 +1,9 @@
1
+ # ./.autotest
2
+ Autotest.add_hook(:initialize) {|at|
3
+ at.add_exception %r{^\.git} # ignore Version Control System
4
+ at.add_mapping(%r{^lib/.*\.rb$}) {|f, _|
5
+ Dir['spec/**/*.rb']
6
+ }
7
+ nil
8
+ }
9
+
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ *~
5
+ *.swp
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2@pomodoro
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in pomodoro.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem "rspec", "~>2.1.0"
8
+ gem "autotest"
9
+ gem "timecop"
10
+ gem "chronic"
11
+ end
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,11 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+ Bundler.setup
4
+
5
+ require 'rspec/core/rake_task'
6
+
7
+ desc 'Run the code in spec'
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.pattern = "spec/**/*_spec.rb"
10
+ t.rspec_opts = "-r ./spec/spec_helper.rb"
11
+ end
@@ -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
+
@@ -0,0 +1,3 @@
1
+ require "pomodoro"
2
+ Pomodoro.start!
3
+ PomodoroServer.run! :port => 80
@@ -0,0 +1,3 @@
1
+ module Pomodoro
2
+ VERSION = "1.0.0"
3
+ end
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
@@ -0,0 +1,7 @@
1
+ require 'rspec'
2
+ require '../lib/pomodoro'
3
+
4
+ RSpec.configure do |c|
5
+ c.fail_fast = true #this is awesome
6
+ end
7
+
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