From 365f8378b45c93ed6219ac49afec5c7f7eb85fe6 Mon Sep 17 00:00:00 2001 From: Daniel Neighman Date: Fri, 13 Nov 2009 17:48:10 +1100 Subject: [PATCH] Changes the Mash gem for the Hashie gem. This is the Mash gem but renamed to not clash with extlib --- lib/twitter.rb | 30 ++++++++--------- lib/twitter/request.rb | 46 +++++++++++++------------- lib/twitter/search.rb | 46 +++++++++++++------------- lib/twitter/trends.rb | 12 +++---- test/twitter/request_test.rb | 64 ++++++++++++++++++------------------ 5 files changed, 99 insertions(+), 99 deletions(-) diff --git a/lib/twitter.rb b/lib/twitter.rb index 78ccfb49e..485f3351a 100644 --- a/lib/twitter.rb +++ b/lib/twitter.rb @@ -4,8 +4,8 @@ gem 'oauth', '~> 0.3.5' require 'oauth' -gem 'mash', '~> 0.0.3' -require 'mash' +gem 'hashie', '~> 0.1.3' +require 'hashie' gem 'httparty', '~> 0.4.3' require 'httparty' @@ -13,41 +13,41 @@ module Twitter class TwitterError < StandardError attr_reader :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.firehose response = HTTParty.get('http://twitter.com/statuses/public_timeline.json', :format => :json) - response.map { |tweet| Mash.new(tweet) } + response.map { |tweet| Hashie::Mash.new(tweet) } end - + def self.user(id) response = HTTParty.get("http://twitter.com/users/show/#{id}.json", :format => :json) - Mash.new(response) + Hashie::Mash.new(response) end - + def self.status(id) response = HTTParty.get("http://twitter.com/statuses/show/#{id}.json", :format => :json) - Mash.new(response) + Hashie::Mash.new(response) end - + def self.friend_ids(id) HTTParty.get("http://twitter.com/friends/ids/#{id}.json", :format => :json) end - + def self.follower_ids(id) HTTParty.get("http://twitter.com/followers/ids/#{id}.json", :format => :json) end @@ -60,4 +60,4 @@ def self.follower_ids(id) require File.join(directory, 'twitter', 'request') require File.join(directory, 'twitter', 'base') require File.join(directory, 'twitter', 'search') -require File.join(directory, 'twitter', 'trends') \ No newline at end of file +require File.join(directory, 'twitter', 'trends') diff --git a/lib/twitter/request.rb b/lib/twitter/request.rb index 4c8b9a175..74cd871d6 100644 --- a/lib/twitter/request.rb +++ b/lib/twitter/request.rb @@ -1,70 +1,70 @@ module Twitter class Request extend Forwardable - + def self.get(client, path, options={}) new(client, :get, path, options).perform end - + def self.post(client, path, options={}) new(client, :post, path, options).perform end - + def self.put(client, path, options={}) new(client, :put, path, options).perform end - + def self.delete(client, path, options={}) new(client, :delete, path, options).perform end - + attr_reader :client, :method, :path, :options - + def_delegators :client, :get, :post, :put, :delete - + def initialize(client, method, path, options={}) @client, @method, @path, @options = client, method, path, {:mash => true}.merge(options) end - + def uri @uri ||= begin uri = URI.parse(path) - + if options[:query] && options[:query] != {} uri.query = to_query(options[:query]) end - + uri.to_s end end - + def perform make_friendly(send("perform_#{method}")) end - + private def perform_get send(:get, uri, options[:headers]) end - + def perform_post send(:post, uri, options[:body], options[:headers]) end - + def perform_put send(:put, uri, options[:body], options[:headers]) end - + def perform_delete send(:delete, uri, options[:headers]) end - + def make_friendly(response) raise_errors(response) data = parse(response) options[:mash] ? mash(data) : data end - + def raise_errors(response) case response.code.to_i when 400 @@ -84,11 +84,11 @@ def raise_errors(response) raise Unavailable, "(#{response.code}): #{response.message}" end end - + def parse(response) Crack::JSON.parse(response.body) end - + def mash(obj) if obj.is_a?(Array) obj.map { |item| make_mash_with_consistent_hash(item) } @@ -101,18 +101,18 @@ def mash(obj) # Lame workaround for the fact that mash doesn't hash correctly def make_mash_with_consistent_hash(obj) - m = Mash.new(obj) + m = Hashie::Mash.new(obj) def m.hash inspect.hash end return m end - + def to_query(options) - options.inject([]) do |collection, opt| + options.inject([]) do |collection, opt| collection << "#{opt[0]}=#{opt[1]}" collection end * '&' end end -end \ No newline at end of file +end diff --git a/lib/twitter/search.rb b/lib/twitter/search.rb index 3458c2ca3..e2a6f2d13 100644 --- a/lib/twitter/search.rb +++ b/lib/twitter/search.rb @@ -2,89 +2,89 @@ module Twitter class Search include HTTParty include Enumerable - + attr_reader :result, :query - + def initialize(q=nil, options={}) @options = options clear containing(q) if q && q.strip != '' end - + def user_agent @options[:user_agent] || 'Ruby Twitter Gem' end - + def from(user) @query[:q] << "from:#{user}" self end - + def to(user) @query[:q] << "to:#{user}" self end - + def referencing(user) @query[:q] << "@#{user}" self end alias :references :referencing alias :ref :referencing - + def containing(word) @query[:q] << "#{word}" self end alias :contains :containing - + # adds filtering based on hash tag ie: #twitter def hashed(tag) @query[:q] << "##{tag}" self end - + # lang must be ISO 639-1 code ie: en, fr, de, ja, etc. # - # when I tried en it limited my results a lot and took - # out several tweets that were english so i'd avoid + # when I tried en it limited my results a lot and took + # out several tweets that were english so i'd avoid # this unless you really want it def lang(lang) @query[:lang] = lang self end - + # Limits the number of results per page def per_page(num) @query[:rpp] = num self end - + # Which page of results to fetch def page(num) @query[:page] = num self end - - # Only searches tweets since a given id. + + # Only searches tweets since a given id. # Recommended to use this when possible. def since(since_id) @query[:since_id] = since_id self end - + # Search tweets by latitude, longitude, and a given range. # Ranges like 25km and 50mi work. def geocode(lat, long, range) @query[:geocode] = [lat, long, range].join(',') self end - + def max(id) @query[:max_id] = id self end - + # Clears all the query filters to make a new search def clear @fetch = nil @@ -92,20 +92,20 @@ def clear @query[:q] = [] self end - + def fetch(force=false) if @fetch.nil? || force query = @query.dup query[:q] = query[:q].join(' ') response = self.class.get('http://search.twitter.com/search.json', :query => query, :format => :json, :headers => {'User-Agent' => user_agent}) - @fetch = Mash.new(response) + @fetch = Hashie::Mash.new(response) end - + @fetch end - + def each fetch()['results'].each { |r| yield r } end end -end \ No newline at end of file +end diff --git a/lib/twitter/trends.rb b/lib/twitter/trends.rb index b9601be00..b46a9e750 100644 --- a/lib/twitter/trends.rb +++ b/lib/twitter/trends.rb @@ -3,27 +3,27 @@ class Trends include HTTParty base_uri 'search.twitter.com/trends' format :json - + # :exclude => 'hashtags' to exclude hashtags def self.current(options={}) mashup(get('/current.json', :query => options)) end - + # :exclude => 'hashtags' to exclude hashtags # :date => yyyy-mm-dd for specific date def self.daily(options={}) mashup(get('/daily.json', :query => options)) end - + # :exclude => 'hashtags' to exclude hashtags # :date => yyyy-mm-dd for specific date def self.weekly(options={}) mashup(get('/weekly.json', :query => options)) end - + private def self.mashup(response) - response['trends'].values.flatten.map { |t| Mash.new(t) } + response['trends'].values.flatten.map { |t| Hashie::Mash.new(t) } end end -end \ No newline at end of file +end diff --git a/test/twitter/request_test.rb b/test/twitter/request_test.rb index 5b7edfabb..183205367 100644 --- a/test/twitter/request_test.rb +++ b/test/twitter/request_test.rb @@ -6,115 +6,115 @@ class RequestTest < Test::Unit::TestCase @client = mock('twitter client') @request = Twitter::Request.new(@client, :get, '/statuses/user_timeline.json', {:query => {:since_id => 1234}}) end - + should "have client" do @request.client.should == @client end - + should "have method" do @request.method.should == :get end - + should "have path" do @request.path.should == '/statuses/user_timeline.json' end - + should "have options" do @request.options[:query].should == {:since_id => 1234} end - + should "have uri" do @request.uri.should == '/statuses/user_timeline.json?since_id=1234' end - + context "performing request for collection" do setup do response = mock('response') do stubs(:body).returns(fixture_file('user_timeline.json')) stubs(:code).returns('200') end - + @client.expects(:get).returns(response) @object = @request.perform end should "return array of mashes" do @object.size.should == 20 - @object.each { |obj| obj.class.should be(Mash) } + @object.each { |obj| obj.class.should be(Hashie::Mash) } @object.first.text.should == 'Colder out today than expected. Headed to the Beanery for some morning wakeup drink. Latte or coffee...hmmm...' end end - + context "performing a request for a single object" do setup do response = mock('response') do stubs(:body).returns(fixture_file('status.json')) stubs(:code).returns('200') end - + @client.expects(:get).returns(response) @object = @request.perform end should "return a single mash" do - @object.class.should be(Mash) + @object.class.should be(Hashie::Mash) @object.text.should == 'Rob Dyrdek is the funniest man alive. That is all.' end end - + context "with no query string" do should "not have any query string" do request = Twitter::Request.new(@client, :get, '/statuses/user_timeline.json') request.uri.should == '/statuses/user_timeline.json' end end - + context "with blank query string" do should "not have any query string" do request = Twitter::Request.new(@client, :get, '/statuses/user_timeline.json', :query => {}) request.uri.should == '/statuses/user_timeline.json' end end - + should "have get shortcut to initialize and perform all in one" do Twitter::Request.any_instance.expects(:perform).returns(nil) Twitter::Request.get(@client, '/foo') end - + should "allow setting query string and headers" do response = mock('response') do stubs(:body).returns('') stubs(:code).returns('200') end - + @client.expects(:get).with('/statuses/friends_timeline.json?since_id=1234', {'Foo' => 'Bar'}).returns(response) Twitter::Request.get(@client, '/statuses/friends_timeline.json?since_id=1234', :headers => {'Foo' => 'Bar'}) end end - + context "new post request" do setup do @client = mock('twitter client') @request = Twitter::Request.new(@client, :post, '/statuses/update.json', {:body => {:status => 'Woohoo!'}}) end - + should "allow setting body and headers" do response = mock('response') do stubs(:body).returns('') stubs(:code).returns('200') end - + @client.expects(:post).with('/statuses/update.json', {:status => 'Woohoo!'}, {'Foo' => 'Bar'}).returns(response) Twitter::Request.post(@client, '/statuses/update.json', :body => {:status => 'Woohoo!'}, :headers => {'Foo' => 'Bar'}) end - + context "performing request" do setup do response = mock('response') do stubs(:body).returns(fixture_file('status.json')) stubs(:code).returns('200') end - + @client.expects(:post).returns(response) @object = @request.perform end @@ -123,48 +123,48 @@ class RequestTest < Test::Unit::TestCase @object.text.should == 'Rob Dyrdek is the funniest man alive. That is all.' end end - + should "have post shortcut to initialize and perform all in one" do Twitter::Request.any_instance.expects(:perform).returns(nil) Twitter::Request.post(@client, '/foo') end end - + context "error raising" do setup do oauth = Twitter::OAuth.new('token', 'secret') oauth.authorize_from_access('atoken', 'asecret') @client = Twitter::Base.new(oauth) end - + should "not raise error for 200" do stub_get('http://twitter.com:80/foo', '', ['200']) lambda { Twitter::Request.get(@client, '/foo') }.should_not raise_error end - + should "not raise error for 304" do stub_get('http://twitter.com:80/foo', '', ['304']) lambda { Twitter::Request.get(@client, '/foo') }.should_not raise_error end - + should "raise RateLimitExceeded for 400" do stub_get('http://twitter.com:80/foo', 'rate_limit_exceeded.json', ['400']) lambda { Twitter::Request.get(@client, '/foo') }.should raise_error(Twitter::RateLimitExceeded) end - + should "raise Unauthorized for 401" do stub_get('http://twitter.com:80/foo', '', ['401']) lambda { Twitter::Request.get(@client, '/foo') }.should raise_error(Twitter::Unauthorized) end - + should "raise General for 403" do stub_get('http://twitter.com:80/foo', '', ['403']) lambda { @@ -200,18 +200,18 @@ class RequestTest < Test::Unit::TestCase }.should raise_error(Twitter::Unavailable) end end - + context "Making request with mash option set to false" do setup do oauth = Twitter::OAuth.new('token', 'secret') oauth.authorize_from_access('atoken', 'asecret') @client = Twitter::Base.new(oauth) end - + should "not attempt to create mash of return object" do stub_get('http://twitter.com:80/foo', 'friend_ids.json') object = Twitter::Request.get(@client, '/foo', :mash => false) - object.class.should_not be(Mash) + object.class.should_not be(Hashie::Mash) end end -end \ No newline at end of file +end