Skip to content

Instantly share code, notes, and snippets.

@revans
Created November 20, 2008 02:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save revans/26888 to your computer and use it in GitHub Desktop.
Save revans/26888 to your computer and use it in GitHub Desktop.
%w[net/http net/https uri ostruct rubygems json].each { |gem| require gem }
module HTTP
class UnSupportedFormat < StandardError; end
class UnAuthenticated < StandardError; end
MimeTypes = { :xml => "text/xml", :json => "application/json" }
def self.included(klass)
klass.extend ClassMethods
end
# Class Methods
module ClassMethods
%w[get post put delete].each do |verb|
meths = %{
def #{verb}(url, &block)
request = new(url)
request.instance_eval(&block)
request.send_request("#{verb}")
request
end
}
self.class_eval meths
end
end
attr_reader :response, :results
# Instance Methods
def initialize(url)
@uri = URI.parse(normalize(url))
@url, @port = @uri.host, @uri.port
end
def proxy(address=nil, port=nil)
@proxy_address = address
@proxy_port = port
end
def basic_auth(user, pass)
@basic_auth = { :user => user, :password => pass }
end
def query(hash={}, q=[])
return nil if hash.empty?
hash.each { |key, *values| q << "#{key}=#{values.join(',')}" }
@uri.query = q.join("&")
end
def header(head={})
head
end
def mime_type(type)
MimeTypes.each { |key,value| @mime_type = key if type.include?(value) }
end
def send_request(resource)
klass = Net::HTTP.const_get resource.to_s.downcase.capitalize
request = klass.new(@uri.request_uri)
request.body = @uri.query
request.initialize_http_header(header)
request.basic_auth(@basic_auth[:user], @basic_auth[:password]) if has_auth?
@response = http.request(request)
mime_type(@response['content-type'])
@results = parse(@response.body)
end
def use_ssl?
@uri.port == 443
end
def has_query?
!!@uri.query
end
def has_auth?
!!@basic_auth
end
def has_proxy?
!!@proxy_address && !!@proxy_port
end
private
def parse(body)
results = case @mime_type
when :xml
Hash.from_xml(body)
when :json
JSON.parse(body)
else
body
end
results
end
def http
net = has_proxy? ? Net::HTTP.new(@uri.host, @uri.port, @proxy_address, @proxy_port) : Net::HTTP.new(@uri.host, @uri.port)
net.use_ssl = use_ssl?
net.verify_mode = OpenSSL::SSL::VERIFY_NONE
net
end
def normalize(url)
url =~ /^https?:\/\// ? url : "http#{'s' if url.include?(':443')}://#{url}"
end
end
class Twitter
include HTTP
def self.search(*terms)
get("http://search.twitter.com/search.json") do
query(:q => terms)
end
end
def self.for(*terms)
get("http://search.twitter.com/search.json").query(:q => terms)
end
end
puts Twitter.search("merb").results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment