Skip to content

Instantly share code, notes, and snippets.

@mwerner
Last active August 29, 2015 14:21
Show Gist options
  • Save mwerner/bcd671360925974ec70c to your computer and use it in GitHub Desktop.
Save mwerner/bcd671360925974ec70c to your computer and use it in GitHub Desktop.
BART predictions
#!/usr/bin/env ruby
%w(open-uri nokogiri).each{|library| require library }
class Bartleby
attr_reader :station, :key
ENDPOINT = 'http://api.bart.gov/api/etd.aspx'
def initialize(station, key)
@key = key
@station = station
end
def name
document.css('station name').text
end
def times(*destinations)
destinations = destinations.map(&:downcase)
data = {}
document.css('station etd').map do |station|
code = station.css('abbreviation').text
if destinations.empty? || destinations.include?(code.downcase)
match = {name: station.css('destination').text}
match[:times] = station.css('estimate').map{|estimate| estimate.css('minutes').text.to_i }
data[code] = match
end
end
data
end
def self.stations
{
'12th' => '12th St. Oakland City Center', '16th' => '16th St. Mission (SF)',
'19th' => '19th St. Oakland', '24th' => '24th St. Mission (SF)', 'ashb' => 'Ashby (Berkeley)',
'balb' => 'Balboa Park (SF)', 'bayf' => 'Bay Fair (San Leandro)', 'cast' => 'Castro Valley',
'civc' => 'Civic Center (SF)', 'cols' => 'Coliseum/Oakland Airport', 'colm' => 'Colma',
'conc' => 'Concord', 'daly' => 'Daly City', 'dbrk' => 'Downtown Berkeley',
'dubl' => 'Dublin/Pleasanton', 'deln' => 'El Cerrito del Norte', 'plza' => 'El Cerrito Plaza',
'embr' => 'Embarcadero (SF)', 'frmt' => 'Fremont', 'ftvl' => 'Fruitvale (Oakland)',
'glen' => 'Glen Park (SF)', 'hayw' => 'Hayward', 'lafy' => 'Lafayette', 'lake' => 'Lake Merritt (Oakland)',
'mcar' => 'MacArthur (Oakland)', 'mlbr' => 'Millbrae', 'mont' => 'Montgomery St. (SF)',
'nbrk' => 'North Berkeley', 'ncon' => 'North Concord/Martinez', 'orin' => 'Orinda',
'pitt' => 'Pittsburg/Bay Point', 'phil' => 'Pleasant Hill', 'powl' => 'Powell St. (SF)',
'rich' => 'Richmond' ,'rock' => 'Rockridge (Oakland)', 'sbrn' => 'San Bruno',
'sfia' => 'San Francisco Intl Airport', 'sanl' => 'San Leandro', 'shay' => 'South Hayward',
'ssan' => 'South San Francisco', 'ucty' => 'Union City', 'wcrk' => 'Walnut Creek',
'wdub' => 'West Dublin', 'woak' => 'West Oakland'
}.map{|k,v| "#{k} #{v}" }
end
def document
@document ||= Nokogiri::HTML(body)
end
def body
open("#{ENDPOINT}?cmd=etd&orig=#{station}&key=#{key}")
end
end
station = ARGV.shift
if station.nil?
puts "`bart` usage:\n\n bart ORIGIN_STATION *DESTINATIONS"
puts "\nExample: To get times from Powell to Richmond or Fremont:"
puts "bart POWL RICH FRMT"
puts "\n`bart stations` to print out a list of station codes"
exit(0)
elsif station == 'stations'
puts Bartleby.stations
else
client = Bartleby.new(station, 'MW9S-E7SL-26DU-VV8V')
puts "BART Arrival times for #{client.name}:"
client.times(*ARGV).each_pair do |code, data|
puts "\n#{data[:name]}"
data[:times].each do |minutes|
puts "* Arriving in #{minutes} minutes"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment