Skip to content

Instantly share code, notes, and snippets.

@justinperkins
Forked from robrasmussen/focus.rb
Created March 6, 2009 04:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinperkins/74759 to your computer and use it in GitHub Desktop.
Save justinperkins/74759 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# The script that give you focus!
# Create a text file that contains sites you only want to give yourself
# access to 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.
#
# Next, create an hourly cron to run the script, passing it the location
# of your focus file (use root's crontab since it's writing to /etc/hosts).
# 0 * * * * /Users/robert/focus.rb /Users/robert/.focus
class Focus
FOCUS_LINE_START = "#--START FOCUS--(do not remove)\n"
FOCUS_LINE_END = "#--END FOCUS--(do not remove)\n"
def initialize(focus_file_path)
unless focus_file_path && File.exist?(focus_file_path) && File.file?(focus_file_path)
raise IOError, "Focus file not found!"
end
@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_START)
focus_section_end = host_file_contents.index(FOCUS_LINE_END)
host_file_entries = host_file_contents[0...(focus_section_start || -1)].concat(focus_lines.unshift(FOCUS_LINE_START).push(FOCUS_LINE_END))
if focus_section_end
host_file_entries << host_file_contents[focus_section_end+1, host_file_contents.size]
end
open("/etc/hosts", "w") {|out| out.write(host_file_entries.join)}
`dscacheutil -flushcache` # otherwise apps don't seem to bother to check
end
private
def focus_lines
# allow anything on the weekends
return [] if %w{ 0 6 }.include?(Time.now.strftime('%w'))
lines = IO.readlines(@focus_file)
hour = Time.now.hour
sites_to_ignore = []
lines.each do |line|
case line
when /^#/
next
when /^([0-9,-]+) (\w.*)/
site = $2
groups = $1.split(",")
intervals = groups.collect {|g| s = g.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
file = ARGV.first
if ARGV.size == 0
puts "Usage: path/to/focus.rb path/to/.focus"
exit(1)
end
begin
Focus.new(file).update_hosts_file
rescue Exception
puts "Problem! #{$!.message}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment