Sample code for Yahoo! local
CS290F Fall 2006 - UCSB Computer Science - Thorsten von Eicken
This is sample code for fetching restaurants in Isla Vista, CA. It is similar to what was shown in class. Stefan abstracted some things a bit more nicely.
Note that this example uses PostgreSQL. In any case, you will need to edit the parameters to ActiveRecord::Base.establish_connection
require 'pp'
require 'net/http'
require 'rubygems'
require_gem 'xml-simple'
require_gem 'activerecord'
# augment the standard classes String and Hash with the
# ability to encode themselves as URL-encoded query strings
class String
def url_encode
gsub(/[^a-zA-Z0-9\-_\.!~*'+]/n){|x| sprintf('%%%02x', x[0])}
end
def query_encode
gsub(/ /,'+').url_encode
end
end
class Hash
def query_encode
collect{|k,v| "#{k.to_s.url_encode}=#{v.to_s.query_encode}"}.join('&')
end
end
# define how to make a web-API call to the Yahoo local search service
def yahoo_local_url args
args[:appid] ||= 'ucsbcs290f'
"http://api.local.yahoo.com/LocalSearchService/V1/localSearch?#{args.query_encode}"
end
url = yahoo_local_url :query=>'restaurants', :city=>'isla vista', :state=>'CA'
data = Net::HTTP.get_response(URI.parse(url)).body
# now parse the XML response and get the desired data out of it
results = XmlSimple.xml_in(data,'ForceArray'=>false)['Result'].collect do |r|
{ :name => r['Title'], :address => r['Address'], :url => r['ClickUrl'] }
end
# finally, connect to the database and save the results into it
ActiveRecord::Base.establish_connection(
:adapter => 'postgresql',
:host => 'localhost',
:database => 'cs290f',
:username => 'stefan'
)
ActiveRecord:: Base.logger = Logger.new(STDOUT)
class Restaurant < ActiveRecord::Base
# for now, do nothing.
end
results.each {|x| Restaurant.new(x).save}
Under PostgreSQL, the database schema is the following:
create table restaurants ( id serial primary key, name text, address text, url text );
An alternative is to let ActiveRecord create the table (note the absence of the id field):
ActiveRecord::Migration.create_table(:restaurants, :force => true) do |t| t.column :name, :string t.column :address, :string t.column :url, :string end
