Toggle hosts file for less distractions (in Haskell)

I decided to edit the /etc/hosts file to block access to some domains that I compulsory visit when working, in order to reduce my distractions. The usual suspects are Twitter, Facebook, Hacker News, and some real-world news sites.

So I edited the file and added the following lines:

# -- WORK --
127.0.0.1     news.ycombinator.com
127.0.0.1     facebook.com
127.0.0.1     twitter.com

Now they’re blocked. But I also wanted the option to quickly comment this section out and back again.

I could do it quickly in Ruby but I thought that it would be a great way to exercise my basic Haskell skills.

It took me quite a while to get it right — my Haskell is rusty. But after it compiled, I only had one little logical bug, which I quickly found out and fixed.

The final code is below. It also backs up hosts file (just in case) and prints the resulting hosts file. Both of these steps could be removed, as they’re not important for its main functionality.

import Data.List

-- Starts toggling the comment after a line that starts with "# --"

processLine switch line
    | length line == 0                          = (switch, line)
    | switch == False && take 4 line == "# --"  = (True, line)
    | switch == True                            = (True, toggleLine line)
    | otherwise                                 = (switch, line)
      where toggleLine l
              | head l == '#' = tail l
              | otherwise     = "#" ++ l

process = snd . mapAccumL processLine False

main = do
  hosts <- readFile "/etc/hosts"
  writeFile "/etc/hosts.backup" hosts
  let newHosts = unlines $ process (lines hosts)
  putStrLn newHosts
  writeFile "/etc/hosts" newHosts

I’m sure this could be done shorter, as everything in Haskell, but I’m just a beginner.

I then compiled the code and put the binary in my user’s bin folder.

Since it edits the /etc/hosts file, it has to be run with sudo. I added a line to sudo permissions (run sudo visudo to edit the file) to allow me to run it without a password:

jacob ALL = NOPASSWD: /Users/jacob/bin/switch_hosts

Then, I added an action to Keyboard Maestro to run sudo /Users/jacob/bin/switch_hosts using a trigger in its system menu. You could do a hotkey trigger or use a TextExpander expansion, or use LaunchBar, or Alfred, or just type it in the Terminal.

It just was this kind of day. I couldn’t do real work, but I could play a little to make my environment better for when I’ll be able to work.

Of course, there are commercial products that can help with distraction-free work environment, like Concentrate, which offers this and more. But I prefer to run less applications, if possible.