Using BOSS api with rails

168 views Asked by At

I am trying to use yahoo's BOSS api with rails.
Controller:

class WelcomeController < ApplicationController
  def index
    require 'bossman'
    BOSSMan.application_id = "api key"

    boss = BOSSMan::Search.web("prospect park", :count => 5, :filter => "-hate")

    puts "Matches:"
    puts
    boss.results.each { |result| puts "#{result.title} [#{result.url}]" }
  end
end

In gem file I have include

gem 'gemcutter'

gem 'bossman','~> 0.4.1'

gem 'fakeweb'

gem 'spec'

gem 'activesupport'

When I run the application, I get the following error:

No such file or directory - getaddrinfo
Extracted source (around line #6):  

BOSSMan.application_id = ""
boss = BOSSMan::Search.images("brooklyn dumbo", :dimensions => "large") #Line 6
boss.results.map { |result| result.url }
end
2

There are 2 answers

3
techvineet On

You can try and include Socket lib at the top of your controller.

require 'socket'

this seems like some socket issue with BOSS.

0
Simon Meyborg On

After long hours of debugging I finally managed to get the boss api to work via rails. It's not really polished, but my guess is everybody should be able to work with it.

This is how:

require 'oauth_util.rb'
require 'net/http'
 
def get_response(buckets, query_params)


    parsed_url = URI.parse("https://yboss.yahooapis.com/ysearch/#{buckets}" )

    o = OauthUtil.new
    o.consumer_key = YAHOO_KEY
    o.consumer_secret = YAHOO_SECRET
    o.sign(parsed_url,query_params)
  


    Net::HTTP.start( parsed_url.host, parsed_url.port, :use_ssl => true ) { | http |
        req = Net::HTTP::Get.new ("/ysearch/#{buckets}?format=json&q=#{query_params}")
        
        req['Authorization'] = o.header
        response = http.request(req)
        return response.read_body
    }
end

Using my altered Verison of oauth_util.rb

# A utility for signing an url using OAuth in a way that's convenient for debugging
# Note: the standard Ruby OAuth lib is here http://github.com/mojodna/oauth
# License: http://gist.github.com/375593
# Usage: see example.rb below

require 'uri'
require 'cgi'
require 'openssl'
require 'base64'

class OauthUtil
  
  attr_accessor :consumer_key, :consumer_secret, :token, :token_secret, :req_method, 
                :sig_method, :oauth_version, :callback_url, :params, :req_url, :base_str
  
  def initialize
    @consumer_key = ''
    @consumer_secret = ''
    @token = ''
    @token_secret = ''
    @req_method = 'GET'
    @sig_method = 'HMAC-SHA1'
    @oauth_version = '1.0'
    @callback_url = ''
    @time
  end
  
  # openssl::random_bytes returns non-word chars, which need to be removed. using alt method to get length
  # ref http://snippets.dzone.com/posts/show/491
  def nonce
    Array.new( 5 ) { rand(256) }.pack('C*').unpack('H*').first
  end
  
  def percent_encode( string )
    
    # ref http://snippets.dzone.com/posts/show/1260
    return URI.escape( string, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]") ).gsub('*', '%2A')
  end

  # @ref http://oauth.net/core/1.0/#rfc.section.9.2
  def signature
    key = percent_encode( @consumer_secret ) + '&' + percent_encode( @token_secret )
 
    # ref: http://blog.nathanielbibler.com/post/63031273/openssl-hmac-vs-ruby-hmac-benchmarks
    digest = OpenSSL::Digest.new( 'sha1' )
   
    hmac = OpenSSL::HMAC.digest( digest, key, @base_str )

    # ref http://groups.google.com/group/oauth-ruby/browse_thread/thread/9110ed8c8f3cae81
    Base64.encode64( hmac ).chomp.gsub( /\n/, '' )
    
  end


  
  # sort (very important as it affects the signature), concat, and percent encode
  # @ref http://oauth.net/core/1.0/#rfc.section.9.1.1
  # @ref http://oauth.net/core/1.0/#9.2.1
  # @ref http://oauth.net/core/1.0/#rfc.section.A.5.1



  def query_string
    pairs = []
    @params.sort.each { | key, val | 
      pairs.push( "#{ percent_encode( key ) }=#{ percent_encode( val.to_s ) }" )
    }
    pairs.join '&'
  end
  
  
  def header 
   'OAuth oauth_version="1.0",oauth_nonce="'+@nonce_now+'",oauth_timestamp="'+@time+'",oauth_consumer_key="'+@consumer_key+'",oauth_signature_method="'+@sig_method+'",oauth_signature="'+percent_encode(signature)+'"'
  end
    
  # organize params & create signature
  def sign( parsed_url, query_param )
        @time=Time.now.to_i.to_s
        @nonce_now=nonce

    @params = {
      'format' => 'json',      
      'oauth_consumer_key' => @consumer_key,
      'oauth_nonce' => @nonce_now,
      'oauth_signature_method' => @sig_method,
      'oauth_timestamp' => @time,
      'oauth_version' => @oauth_version,
      'q'=> query_param
    }

    # if url has query, merge key/values into params obj overwriting defaults
 
     #if parsed_url.query
    #  @params.merge! CGI.parse( parsed_url.query )
    #end


    # @ref http://oauth.net/core/1.0/#rfc.section.9.1.2
    @req_url = parsed_url.scheme + '://' + parsed_url.host + parsed_url.path
  


    # create base str. make it an object attr for ez debugging
    # ref http://oauth.net/core/1.0/#anchor14

    @base_str = [ 
      @req_method, 
      percent_encode(req_url), 
      # normalization is just x-www-form-urlencoded
      percent_encode(query_string)
      
    ].join( '&' )

    # add signature

    
    return self
  end
end