Navigation Menu

Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Josep M. Bach committed Aug 29, 2011
1 parent f6e9521 commit 7842d09
Show file tree
Hide file tree
Showing 13 changed files with 536 additions and 172 deletions.
28 changes: 21 additions & 7 deletions Readme.md
Expand Up @@ -51,13 +51,10 @@ The clients will receive notifications via sound/growl (configurable in a
If you're not using OSX, try to install the `afplay` program manually or...
send a patch to make it work with your OS :)

* The pomodoro schedule is (as of v0.0.3) hard-coded. It starts at 8:00 AM,
stops at 13:00 for lunch, and starts again at 13:20. In the following
versions this will be freely configurable.


## Configuration

### Client configuration

By default, both sound and visual notifications are displayed on each event.
If you want to configure this, create a file in your home directory named
`.domodororc` with some YAML configuration:
Expand All @@ -66,8 +63,25 @@ If you want to configure this, create a file in your home directory named
$ echo "visual: true" >> ~/.domodororc
$ echo "sound: false" >> ~/.domodororc

## Copyright
### Server configuration

Copyright (c) 2011 Josep M. Bach. Released under the MIT license.
Inside the server machine, to configure the pomodoro schedule, create a
`~/.domodororc` file with YAML configuration (the values provided below are
those that will be used by default if you don't specify them):

````yaml
server:
pomodoro_duration: 25 # in minutes
pomodoro_break: 5 # in minutes
long_break_after: 4 # pomodoros

day_start: "08:30"
day_end: "16:30"

lunch_time: "13:00"
lunch_duration: 30 # in minutes
````

## Copyright

Copyright (c) 2011 Josep M. Bach. Released under the MIT license.
2 changes: 2 additions & 0 deletions lib/domodoro.rb
@@ -1,6 +1,8 @@
require 'eventmachine'

require "domodoro/version"
require "domodoro/schedule"
require "domodoro/timepoint"
require "domodoro/config"
require "domodoro/channel"
require "domodoro/server"
Expand Down
34 changes: 8 additions & 26 deletions lib/domodoro/channel.rb
@@ -1,6 +1,6 @@
module Domodoro
class Channel < EM::Channel
def broadcast(hour, min)
def broadcast(timestamp, schedule)
if ENV['DEBUG']
puts 'DEBUG MODE: Start on even minutes, stop on odd minutes'
if min % 2 == 0
Expand All @@ -13,31 +13,13 @@ def broadcast(hour, min)
return
end

if (hour >= 8 && hour < 13)
morning(min)
elsif (hour >= 13 && min >= 20) &&
afternoon(min)
end
end
def morning(min)
case min
when 0, 30
puts "#{Time.now} - Starting pomodoro!"
self << :start
when 25, 55
puts "#{Time.now} - Pomodoro break!"
self << :stop
end
end

def afternoon(min)
case min
when 20, 50
puts "#{Time.now} - Starting pomodoro!"
self << :start
when 45, 15
puts "#{Time.now} - Pomodoro break!"
self << :stop
action = schedule.to_hash[timestamp]
if action
next_action = schedule.action_after(timestamp)
self << {
:action => action,
:next_action => next_action
}
end
end
end
Expand Down
77 changes: 60 additions & 17 deletions lib/domodoro/client.rb
Expand Up @@ -12,34 +12,49 @@ def connected=(value)
@connected = true
end

def next_action
@next_action
end

def next_action=(action)
@next_action = action
end

def start(host, port='9111')
Config.load
Config.load_client_configuration
puts "#{Time.now} - Domodoro listening on #{host}:#{port}"
puts "Visual notifications: #{Config.visual}"
puts "Sound notifications: #{Config.sound}\n"

EM.run do
EM.connect(host, port) do |c|
c.extend EM::P::LineText2
c.extend EM::P::ObjectProtocol
def c.connection_completed
puts " - Connected to server!"
Client.connected = true
end
def c.receive_line(line)
case line
when /start/
puts " - Starting pomodoro!"
Client.work
when /stop/
puts " - Pomodoro break!"
Client.break
def c.receive_object(object)
case object[:current_action].last
when :start
puts "[#{object[:current_action]}] - Starting pomodoro!"
Client.work
when :stop
puts "[#{object[:current_action]}] - Pomodoro break!"
Client.break
when :lunch
puts "[#{object[:current_action]}] - Lunch time!"
Client.lunch
when :go_home
puts "[#{object[:current_action]}] - Time to go home!"
Client.home
end
Client.next_action = object[:next_action]
end
end
EM.add_periodic_timer(1) do
EM.next_tick do
if Client.connected
print_time
print_next_action
else
puts 'Cannot connect to server. Is it running?'
end
Expand Down Expand Up @@ -71,20 +86,48 @@ def break
end
end

def lunch
EM.defer do
if Config.visual
Notify.notify "Domodoro", "Lunch time!"
end
if Config.sound
system("afplay #{path_to('lunch.wav')}")
end
end
end

def home
EM.defer do
if Config.visual
Notify.notify "Domodoro", "Time to go home!"
end
if Config.sound
system("afplay #{path_to('home.wav')}")
end
end
end

private

def path_to(asset)
File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'assets', asset))
end

def print_time
hour = Time.now.hour.to_s.rjust(2, '0')
min = Time.now.min.to_s.rjust(2, '0')
secs = Time.now.sec.to_s.rjust(2, '0')
def print_next_action
timestamp = Timepoint.new(Client.next_action.first)
action = case Client.next_action.last
when :start then "Pomodoro"
when :stop then "Pomodoro Break"
when :lunch then "Lunch time"
when :go_home then "Go home"

time_left = timestamp.left_until

$stdout.print "\r"
$stdout.print " " * 20
$stdout.print " " * 50
$stdout.print "\r"
$stdout.print "#{hour}:#{min}:#{secs}"
$stdout.print "Next: #{action} in #{time_left}"
$stdout.flush
end

Expand Down
33 changes: 32 additions & 1 deletion lib/domodoro/config.rb
@@ -1,11 +1,12 @@
require 'yaml'
require 'ostruct'

module Domodoro
module Config
attr_accessor :visual, :sound
extend self

def load
def load_client_configuration
if File.exist?(File.expand_path('~/.domodororc'))
file = YAML.load(File.read(File.expand_path('~/.domodororc')))

Expand All @@ -16,5 +17,35 @@ def load
self.sound = true
end
end

def get_server_configuration
config = OpenStruct.new

if File.exist?(File.expand_path('~/.domodororc'))
file = YAML.load(File.read(File.expand_path('~/.domodororc')))['server']

config.pomodoro_duration = file['pomodoro_duration']
config.pomodoro_break = file['pomodoro_break']
config.long_break_after = file['long_break_after']

config.day_start = Timepoint.new(file['day_start'])
config.day_end = Timepoint.new(file['day_end'])

config.lunch_time = Timepoint.new(file['lunch_time'])
config.lunch_duration = file['lunch_duration']
end

config.pomodoro_duration ||= 25
config.pomodoro_break ||= 5
config.long_break_after ||= 4

config.day_start ||= Timepoint.new('08:30')
config.day_end ||= Timepoint.new('16:30')

config.lunch_time ||= Timepoint.new('13:00')
config.lunch_duration ||= 30

config
end
end
end
82 changes: 82 additions & 0 deletions lib/domodoro/schedule.rb
@@ -0,0 +1,82 @@
module Domodoro
class Schedule
def initialize
@times = {}
@config = Config.get_server_configuration
end

def generate!
# Key points
@times[@config.lunch_time.to_s] = :lunch
@times[@config.day_end.to_s] = :go_home



generate_pomodoros_between(@config.day_start, @config.lunch_time)
generate_pomodoros_between(@config.lunch_time + @config.lunch_duration, @config.day_end)
end

def to_hash
@times
end

def current_action(timestamp)
times = @times.dup

if times[timestamp]
minus_one = false
else
minus_one = true
times[timestamp] = :now
end

sorted = times.sort

idx = sorted.index do |element|
element == sorted.assoc(timestamp)
end

idx = idx - 1 if minus_one

sorted[idx]
end

def action_after(timestamp)
times = @times.dup
times[timestamp] ||= :now
sorted = times.sort

idx = sorted.index do |element|
element == sorted.assoc(timestamp)
end

sorted[idx + 1]
end

private

def generate_pomodoros_between(start, finish)
duration = @config.pomodoro_duration
pomodoro_break = @config.pomodoro_break

time = start
long_break_yet = 1

while time.before?(finish)
@times[time.to_s] = :start
time += duration

break unless time.before?(finish)

@times[time.to_s] = :stop

break_rest = pomodoro_break
break_rest *= 2 if long_break_yet == @config.long_break_after

time += break_rest

long_break_yet += 1
end
end
end
end

0 comments on commit 7842d09

Please sign in to comment.