#!/usr/bin/env ruby # # Find text directions using Google directions. You can put a home # address in ~/.directions. The first non-empty line will be used. # # comment out the rest of the line. # # We need two address -- FROM and DEST. These are determined this way. # # FROM address: # - Use the one in ~/.directions if we don't use the -o option # - If -o is used or none is found in ~/.directions use the first # command line argument # - If there is no such argument prompt the user # # DEST address: # - Use the second command line argument # - If there is no such argument, prompt the user # require 'open-uri' require 'cgi' class Directions BASE_URL = 'http://jeffpalm.com/directions' def main(argv) # Arguments @verbose = false override = false args = [] argv.each do |arg| if arg.match /^-+v/ @verbose = true elsif arg.match /^-+o/ override = true elsif arg.match /^-+h/ print_help return else args << arg end end # Check whether we've specified a home address in ~/.directions home_address = find_home_address note 'Home address: ' + home_address.to_s from = nil dest = nil if !override && args.length < 2 note 'Using home address' from = home_address else note 'Overriding home address' end if !from from = args.empty? ? prompt("From:") : args.shift end dest = args.empty? ? prompt("To:") : args.shift url = BASE_URL + '/request.php' url += '?from=' + CGI.escape(from) url += '&dest=' + CGI.escape(dest) note url open(url).read spinner 'Loading',5 url = BASE_URL + '/get.php' output_results open(url).read end private def print_help def e(s) STDERR.puts s end e 'Usage: ' + File.basename($0) + ' [options] origin? destination?' e 'where options include:' e ' -o Over ride and don\'t use address in ~/.directions' e ' -h Print this message' e ' -v Be loud' e 'You can put a home address in ~/.directions. If this address' e 'exists it will used as the origin address. You can over ride' e 'using this address with the -o option. If no home address' e 'is exists in ~/.directions and none is given as an argument' e 'we prompt for it. If no destination address is given on the' e 'command line, we prompt for it.' end def output_results(c) puts puts lines = c.split /\n/ if lines.length < 3 lines.each do |line| puts line end return end distance = lines.shift.strip duration = lines.shift.strip puts 'Distance: ' + distance puts 'Duration: ' + duration puts format = "%-10s %-10s %s\n" printf format, 'Distance', 'Duration', 'Directions' lines.each do |line| if line.match /^\d/ dist,dur,desc = line.split /\t/ printf format,dist,dur,desc else puts ' --- ' + line + ' ---' end end end def spinner(title,dur) arr = ['|', '/', '-', '\\'] sleep_time = 0.1 print title + ' ' + arr[0] i = 0 0.upto(dur/sleep_time) do print "\b" + arr[i] STDOUT.flush sleep sleep_time i = (i+1) % arr.length end end def prompt(msg) addr = nil while !addr print msg + ' ' addr = STDIN.readline addr.strip! end return addr end def note(s) STDERR.puts s if @verbose end def find_home_address f = File.join ENV['HOME'],'.directions' return nil if !File.exist? f IO.foreach f do |line| line = line.gsub /\#.*/,'' line.strip! return line if line != '' end return nil end end Directions.new.main ARGV