Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #261 from wjlroe/search-metadata

SearchResults object contains metadata and results array
  • Loading branch information...
commit 402792c81404526ef2a284560e009ad5128ba3a9 2 parents 13a0b80 + 9dedf44
@sferik authored
View
12 README.md
@@ -138,13 +138,21 @@ Return the text of the Tweet at https://twitter.com/sferik/statuses/27558893223
Twitter.status(27558893223).text
Find the 3 most recent marriage proposals to [@justinbieber][justinbieber]
- Twitter.search("to:justinbieber marry me", :rpp => 3, :result_type => "recent").map do |status|
+ Twitter.search("to:justinbieber marry me", :rpp => 3, :result_type => "recent").results.map do |status|
"#{status.from_user}: #{status.text}"
end
Let's find a Japanese-language Tweet tagged #ruby (no retweets)
- Twitter.search("#ruby -rt", :lang => "ja", :rpp => 1).first.text
+ Twitter.search("#ruby -rt", :lang => "ja", :rpp => 1).results.first.text
+
+The search result object returned by `Twitter::Client#search` includes some metadata about the search
+results:
+
+ Twitter.search("to:justinbieber marry me", :rpp => 3, :result_type => "recent").max_id => 28857935752
+
+The `max_id` attribute can be used in your next search query as the `:since_id` parameter to only return newer
+tweets.
Certain methods require authentication. To get your Twitter OAuth credentials,
register an app at http://dev.twitter.com/apps
View
18 lib/twitter/client.rb
@@ -25,6 +25,7 @@
require 'twitter/request'
require 'twitter/retweet'
require 'twitter/saved_search'
+require 'twitter/search_results'
require 'twitter/settings'
require 'twitter/size'
require 'twitter/status'
@@ -1787,17 +1788,12 @@ def saved_search_destroy(id, options={})
# @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID. There are limits to the number of Tweets which can be accessed through the API. If the limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID available.
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Boolean, String, Integer] :with_twitter_user_id When set to either true, t or 1, the from_user_id and to_user_id values in the response will map to "official" user IDs which will match those returned by the REST API.
- # @return [Array<Twitter::Status>] Return tweets that match a specified query
+ # @return [Twitter::SearchResults] Return tweets that match a specified query with search metadata
# @example Returns tweets related to twitter
# Twitter.search('twitter')
def search(q, options={})
- if results = get("/search.json", options.merge(:q => q), :endpoint => search_endpoint)['results']
- results.map do |status|
- Twitter::Status.new(status)
- end
- else
- []
- end
+ response = get("/search.json", options.merge(:q => q), :endpoint => search_endpoint)
+ Twitter::SearchResults.new(response)
end
# Returns recent statuses related to a query with images and videos embedded
@@ -1895,7 +1891,7 @@ def suggest_users(slug, options={})
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
- # @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
+ # @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
# @return [Array<Twitter::Status>]
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @example Return the 20 most recent statuses, including retweets if they exist, posted by the authenticating user and the users they follow
@@ -2038,7 +2034,7 @@ def retweets_of_me(options={})
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
- # @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
+ # @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
# @return [Array<Twitter::Status>]
# @example Return the 20 most recent statuses posted by @sferik
# Twitter.user_timeline('sferik')
@@ -2087,7 +2083,7 @@ def media_timeline(*args)
# @option options [Integer] :max_id Returns results with an ID less than (that is, older than) or equal to the specified ID.
# @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 200.
# @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
- # @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
+ # @option options [Boolean, String, Integer] :exclude_replies This parameter will prevent replies from appearing in the returned timeline. Using exclude_replies with the count parameter will mean you will receive up-to count tweets - this is because the count parameter retrieves that many tweets before filtering out retweets and replies.
# @return [Array<Twitter::Status>]
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @example Return the 20 most recent statuses from the authenticating user's network
View
63 lib/twitter/search_results.rb
@@ -0,0 +1,63 @@
+require 'twitter/base'
+
+module Twitter
+ class SearchResults < Twitter::Base
+
+ # @return [Array<Twitter::Status>]
+ def results
+ @results ||= (@attrs['results'] || []).map{ |status| Twitter::Status.new(status) }
+ end
+ alias :collection :results
+
+ # @return [Float]
+ def completed_in
+ @attrs['completed_in']
+ end
+
+ # @return [Fixnum]
+ def max_id
+ @attrs['max_id']
+ end
+
+ # @return [String]
+ def max_id_str
+ @attrs['max_id_str']
+ end
+
+ # @return [String]
+ def next_page
+ @attrs['next_page']
+ end
+
+ # @return [Fixnum]
+ def page
+ @attrs['page']
+ end
+
+ # @return [String]
+ def query
+ @attrs['query']
+ end
+
+ # @return [String]
+ def refresh_url
+ @attrs['refresh_url']
+ end
+
+ # @return [Fixnum]
+ def results_per_page
+ @attrs['results_per_page']
+ end
+
+ # @return [Fixnum]
+ def since_id
+ @attrs['since_id']
+ end
+
+ # @return [String]
+ def since_id_str
+ @attrs['since_id_str']
+ end
+ end
+end
+
View
16 spec/twitter/client/search_spec.rb
@@ -20,9 +20,15 @@
end
it "should return recent statuses related to a query with images and videos embedded" do
search = @client.search('twitter')
- search.should be_an Array
- search.first.should be_a Twitter::Status
- search.first.text.should == "@KaiserKuo from not too far away your new twitter icon looks like Vader."
+ search.should be_a Twitter::SearchResults
+ search.results.should be_an Array
+ search.results.first.should be_a Twitter::Status
+ search.results.first.text.should == "@KaiserKuo from not too far away your new twitter icon looks like Vader."
+ end
+
+ it "should return the max_id value for a search result" do
+ search = @client.search('twitter')
+ search.max_id.should eq(28857935752)
end
context "when search API responds a malformed result" do
@@ -34,8 +40,8 @@
it "should not fail and return blank Array" do
search = @client.search('twitter')
- search.should be_an Array
- search.should have(0).items
+ search.results.should be_an Array
+ search.results.should have(0).items
end
end
end
View
135 spec/twitter/search_results_spec.rb
@@ -0,0 +1,135 @@
+require 'helper'
+
+describe Twitter::SearchResults do
+
+ describe "#completed_in" do
+ it "should return completed_in" do
+ results = Twitter::SearchResults.new('completed_in' => 23.5)
+ results.completed_in.should == 23.5
+ end
+ it "should return nil when no value exists" do
+ results = Twitter::SearchResults.new
+ results.completed_in.should be_nil
+ end
+ end
+
+ describe "#max_id" do
+ it "should contain the max_id" do
+ results = Twitter::SearchResults.new('max_id' => 123456)
+ results.max_id.should == 123456
+ end
+ it "should be nil when no value passed" do
+ results = Twitter::SearchResults.new
+ results.max_id.should be_nil
+ end
+ end
+
+ describe "#max_id_str" do
+ it "should contain the max_id_str" do
+ results = Twitter::SearchResults.new('max_id_str' => '123456')
+ results.max_id_str.should == '123456'
+ end
+ it "should be nil when no value passed" do
+ results = Twitter::SearchResults.new
+ results.max_id_str.should be_nil
+ end
+ end
+
+ describe "#next_page" do
+ it "should contain the next_page" do
+ results = Twitter::SearchResults.new('next_page' => "?page=2&max_id=122078461840982016&q=blue%20angels&rpp=5")
+ results.next_page.should == "?page=2&max_id=122078461840982016&q=blue%20angels&rpp=5"
+ end
+ it "should be nil when no value passed" do
+ results = Twitter::SearchResults.new
+ results.next_page.should be_nil
+ end
+ end
+
+ describe "#page" do
+ it "should contain the page" do
+ results = Twitter::SearchResults.new('page' => 2)
+ results.page.should == 2
+ end
+ it "should be nil when no value passed" do
+ results = Twitter::SearchResults.new
+ results.page.should be_nil
+ end
+ end
+
+ describe "#query" do
+ it "should contain the query" do
+ results = Twitter::SearchResults.new('query' => 'blue+angels')
+ results.query.should == 'blue+angels'
+ end
+ it "should be nil when no value passed" do
+ results = Twitter::SearchResults.new
+ results.query.should be_nil
+ end
+ end
+
+ describe "#refresh_url" do
+ it "should contain the refresh_url" do
+ results = Twitter::SearchResults.new('refresh_url' => '?since_id=122078461840982016&q=blue%20angels')
+ results.refresh_url.should == '?since_id=122078461840982016&q=blue%20angels'
+ end
+ it "should be nil when no value passed" do
+ results = Twitter::SearchResults.new
+ results.refresh_url.should be_nil
+ end
+ end
+
+ describe "#results_per_page" do
+ it "should contain the results_per_page" do
+ results = Twitter::SearchResults.new('results_per_page' => 10)
+ results.results_per_page.should == 10
+ end
+ it "should be nil when no value passed" do
+ results = Twitter::SearchResults.new
+ results.results_per_page.should be_nil
+ end
+ end
+
+ describe "#since_id" do
+ it "should contain the since_id" do
+ results = Twitter::SearchResults.new('since_id' => 123456)
+ results.since_id.should == 123456
+ end
+ it "should be nil when no value passed" do
+ results = Twitter::SearchResults.new
+ results.since_id.should be_nil
+ end
+ end
+
+ describe "#since_id_str" do
+ it "should contain the since_id_str" do
+ results = Twitter::SearchResults.new('since_id_str' => '123456')
+ results.since_id_str.should == '123456'
+ end
+ it "should be nil when no value passed" do
+ results = Twitter::SearchResults.new
+ results.since_id_str.should be_nil
+ end
+ end
+
+ describe "#results" do
+ it "should contain twitter status objects" do
+ search_results = Twitter::SearchResults.new('results' => [{'text' => 'tweet!'}])
+ search_results.results.should be_a Array
+ search_results.results.first.should be_a Twitter::Status
+ end
+ it "should be an empty array if no search results passed" do
+ search_results = Twitter::SearchResults.new
+ search_results.results.should be_a Array
+ search_results.results.should == []
+ end
+ end
+
+ describe "#collection" do
+ it "should alias collection to results" do
+ search_results = Twitter::SearchResults.new('results' => [{'text' => 'tweet!'}])
+ search_results.collection.should be_a Array
+ search_results.collection.first.should be_a Twitter::Status
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.