caffo (owner)

Fork Of

Revisions

gist: 73659 Download_button fork
public
Public Clone URL: git://gist.github.com/73659.git
Embed All Files: show embed
focus.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env ruby
 
# The script that give you focus!
# Create a text file that contains sites want to give yourself
# access to only during certain times of day.
#
# The file will look like this:
# 12 news.ycombinator.com
# 11-13,19-21 twitter.com
#
# In this case, I can visit hacker news only over the lunch hour,
# and twitter between 11-1pm and 7-9pm. (Note, in your focus
# file X is the same as X-X+1).
#
# Next, create an hourly cron to run the script, passing it the location
# of your focus file.
# 0 * * * * /Users/robert/focus.rb /Users/robert/.focus
#
# NOTE: /etc/hosts needs to be writable by the user running the cron job
#
class Focus
  FOCUS_LINE = "#--FOCUS--(do not remove this line)\n"
  def initialize(focus_file_path)
    @focus_file = focus_file_path
  end
  
  def update_hosts_file
    host_file_contents = IO.readlines("/etc/hosts")
    focus_section_start = host_file_contents.index(FOCUS_LINE)
    host_file_entries = host_file_contents[0...(focus_section_start || -1)].concat(focus_lines.unshift(FOCUS_LINE)).join
    open("/etc/hosts", "w") {|out| out.write(host_file_entries)}
    `dscacheutil -flushcache` # otherwise apps don't seem to bother to check
  end
  
  private
  def focus_lines
    lines = IO.readlines(@focus_file)
    hour = Time.now.hour
    sites_to_ignore = []
    lines.each do |line|
      if line =~ /^([0-9,-]+) (\w.*)/
        site, times = $2, $1.split(",")
        intervals = times.collect {|t| s = t.split("-"); s.size == 1 ? s[0].to_i : (s[0].to_i...s[-1].to_i)}
        sites_to_ignore << site unless intervals.any? {|i| i === hour}
      end
    end
    sites_to_ignore.collect {|site| "127.0.0.1 #{site}\n"}
  end
    
end
 
if __FILE__ == $0
  unless ARGV.size == 1
    puts "Usage: focus /path/to/focus_file.txt"
    exit(1)
  end
  begin
    Focus.new(ARGV[0]).update_hosts_file
  rescue Exception
    puts "Problem! #{$!.message}"
    exit(1)
  end
end