Skip to content

Commit

Permalink
Replace HTTParty with Faraday
Browse files Browse the repository at this point in the history
  • Loading branch information
sferik committed Sep 25, 2010
1 parent ae283c2 commit 466a0d9
Show file tree
Hide file tree
Showing 20 changed files with 509 additions and 481 deletions.
18 changes: 13 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,41 @@ PATH
remote: .
specs:
twitter (0.9.11)
addressable (~> 2.2.1)
faraday (~> 0.4.6)
faraday-middleware (~> 0.0.1)
hashie (~> 0.4.0)
httparty (~> 0.6.1)
multi_json (~> 0.0.4)
oauth (~> 0.4.3)

GEM
remote: http://rubygems.org/
specs:
crack (0.1.8)
addressable (2.2.1)
fakeweb (1.3.0)
faraday (0.4.6)
addressable (>= 2.1.1)
rack (>= 1.0.1)
faraday-middleware (0.0.1)
faraday (~> 0.4.5)
hashie (0.4.0)
httparty (0.6.1)
crack (= 0.1.8)
mocha (0.9.8)
rake
multi_json (0.0.4)
oauth (0.4.3)
rack (1.2.1)
rake (0.8.7)
shoulda (2.11.3)

PLATFORMS
ruby

DEPENDENCIES
addressable (~> 2.2.1)
fakeweb (~> 1.3.0)
faraday (~> 0.4.6)
faraday-middleware (~> 0.0.1)
hashie (~> 0.4.0)
httparty (~> 0.6.1)
mocha (~> 0.9.8)
multi_json (~> 0.0.4)
oauth (~> 0.4.3)
Expand Down
6 changes: 3 additions & 3 deletions examples/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
search.each { |result| pp result }

puts '*'*50, 'Parameter Check', '*'*50
pp Twitter::Search.new('#austineats').fetch().results.first
pp Twitter::Search.new('#austineats').page(2).fetch().results.first
pp Twitter::Search.new('#austineats').since(1412737343).fetch().results.first
pp Twitter::Search.new('#austineats').fetch.results.first
pp Twitter::Search.new('#austineats').page(2).fetch.results.first
pp Twitter::Search.new('#austineats').since(1412737343).fetch.results.first
27 changes: 27 additions & 0 deletions lib/faraday/raise_errors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Faraday
class Response::RaiseErrors < Response::Middleware
def self.register_on_complete(env)
env[:response].on_complete do |response|
case response[:status].to_i
when 400
raise Twitter::RateLimitExceeded, "(#{response[:status]}): #{response[:body]}"
when 401
raise Twitter::Unauthorized, "(#{response[:status]}): #{response[:body]}"
when 403
raise Twitter::General, "(#{response[:status]}): #{response[:body]}"
when 404
raise Twitter::NotFound, "(#{response[:status]}): #{response[:body]}"
when 500
raise Twitter::InformTwitter, "Twitter had an internal error. Please let them know in the group. (#{response[:status]}): #{response[:body]}"
when 502..503
raise Twitter::Unavailable, "(#{response[:status]}): #{response[:body]}"
end
end
end

def initialize(app)
super
@parser = nil
end
end
end
149 changes: 36 additions & 113 deletions lib/twitter.rb
Original file line number Diff line number Diff line change
@@ -1,28 +1,20 @@
require "forwardable"
require "oauth"
require "hashie"
require "httparty"
require "multi_json"
require 'addressable/uri'
require 'faraday'
require 'faraday_middleware'
require 'forwardable'
require 'hashie'
require 'multi_json'
require 'oauth'

module Twitter
include HTTParty

class TwitterError < StandardError
attr_reader :data

def initialize(data)
@data = data
super
end
def self.adapter
@adapter ||= Faraday.default_adapter
end

class RateLimitExceeded < TwitterError; end
class Unauthorized < TwitterError; end
class General < TwitterError; end

class Unavailable < StandardError; end
class InformTwitter < StandardError; end
class NotFound < StandardError; end
def self.adapter=(value)
@adapter = value
end

def self.user_agent
@user_agent ||= 'Ruby Twitter Gem'
Expand All @@ -33,11 +25,13 @@ def self.user_agent=(value)
end

def self.api_endpoint
@api_endpoint ||= "api.twitter.com/#{self.api_version}"
api_endpoint = "api.twitter.com/#{Twitter.api_version}"
api_endpoint = Addressable::URI.heuristic_parse(api_endpoint).to_s
@api_endpoint ||= api_endpoint
end

def self.api_endpoint=(value)
@api_endpoint = value
@api_endpoint = Addressable::URI.heuristic_parse(value).to_s
end

def self.api_version
Expand All @@ -48,54 +42,24 @@ def self.api_version=(value)
@api_version = value
end

def self.firehose(options = {})
perform_get("/statuses/public_timeline.json")
end

def self.user(id, options={})
perform_get("/users/show/#{id}.json")
end

def self.status(id, options={})
perform_get("/statuses/show/#{id}.json")
end

def self.friend_ids(id, options={})
perform_get("/friends/ids/#{id}.json")
end

def self.follower_ids(id, options={})
perform_get("/followers/ids/#{id}.json")
end

def self.timeline(id, options={})
perform_get("/statuses/user_timeline/#{id}.json", :query => options)
end

# :per_page = max number of statues to get at once
# :page = which page of tweets you wish to get
def self.list_timeline(list_owner_screen_name, slug, query = {})
perform_get("/#{list_owner_screen_name}/lists/#{slug}/statuses.json", :query => query)
end

private

def self.perform_get(uri, options = {})
base_uri self.api_endpoint
make_friendly(get(uri, options))
end
class TwitterError < StandardError
attr_reader :data

def self.make_friendly(response)
raise_errors(response)
data = parse(response)
# Don't mash arrays of integers
if data && data.is_a?(Array) && data.first.is_a?(Integer)
data
else
mash(data)
def initialize(data)
@data = data
super
end
end

class RateLimitExceeded < TwitterError; end
class Unauthorized < TwitterError; end
class General < TwitterError; end
class Unavailable < StandardError; end
class InformTwitter < StandardError; end
class NotFound < StandardError; end

def self.raise_errors(response)
case response.code.to_i
when 400
Expand All @@ -116,54 +80,13 @@ def self.raise_errors(response)
end
end

def self.parse(response)
case response.body
when ''
nil
when 'true'
true
when 'false'
false
else
MultiJson.decode(response.body)
end
end

def self.mash(obj)
if obj.is_a?(Array)
obj.map{|item| Hashie::Mash.new(item)}
elsif obj.is_a?(Hash)
Hashie::Mash.new(obj)
else
obj
end
end

end

module Hashie
class Mash

# Converts all of the keys to strings, optionally formatting key name
def rubyify_keys!
keys.each{|k|
v = delete(k)
new_key = k.to_s.underscore
self[new_key] = v
v.rubyify_keys! if v.is_a?(Hash)
v.each{|p| p.rubyify_keys! if p.is_a?(Hash)} if v.is_a?(Array)
}
self
end

end
end

directory = File.expand_path(File.dirname(__FILE__))

require File.join(directory, "twitter", "oauth")
require File.join(directory, "twitter", "request")
require File.join(directory, "twitter", "base")
require File.join(directory, "twitter", "search")
require File.join(directory, "twitter", "trends")
require File.join(directory, "twitter", "geo")
require File.expand_path("../faraday/raise_errors", __FILE__)
require File.expand_path("../twitter/oauth", __FILE__)
require File.expand_path("../twitter/request", __FILE__)
require File.expand_path("../twitter/base", __FILE__)
require File.expand_path("../twitter/search", __FILE__)
require File.expand_path("../twitter/trends", __FILE__)
require File.expand_path("../twitter/geo", __FILE__)
require File.expand_path("../twitter/unauthenticated", __FILE__)
Loading

2 comments on commit 466a0d9

@pengwynn
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the new Unauthenticated class, but shouldn't we forward with depreciation warnings from the Twitter module?

@sferik
Copy link
Owner Author

@sferik sferik commented on 466a0d9 Sep 25, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. There are some other API changes as well in Geo, Trends, all over the place actually. Let's add the deprecation warnings in master and release them as 0.9.13 ahead of the 1.0.0 (faraday) release.

Please sign in to comment.