Skip to content

Commit

Permalink
Allow search query to be passed in options hash
Browse files Browse the repository at this point in the history
  • Loading branch information
sferik committed Dec 24, 2013
1 parent ed39c7e commit 8e846e1
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 34 deletions.
1 change: 1 addition & 0 deletions .yardopts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ README.md
examples/AllTweets.md
examples/Configuration.md
examples/RateLimiting.md
examples/Search.md
examples/Update.md
15 changes: 8 additions & 7 deletions examples/AllTweets.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# All Tweets

You can fetch up to 3,200 tweets for a user, 200 at a time (up to 16 HTTP
requests). **Note: This may result in [rate limiting][].**
You can get up to 3,200 tweets for a user, 200 at a time.

[rate limiting]: https://github.com/sferik/twitter/blob/master/examples/RateLimiting.md
Here is an example of recursively getting pages of 200 Tweets until you receive
an empty response.

**Note: This may result in [rate limiting][].**

Here is an example of recursively fetching pages of 200 Tweets until you
receive an empty response.
[rate limiting]: https://github.com/sferik/twitter/blob/master/examples/RateLimiting.md

```ruby
require 'twitter'
Expand All @@ -17,13 +18,13 @@ def collect_with_max_id(collection=[], max_id=nil, &block)
response.empty? ? collection.flatten : collect_with_max_id(collection, response.last.id - 1, &block)
end

def fetch_all_tweets(user)
def get_all_tweets(user)
collect_with_max_id do |max_id|
options = {:count => 200, :include_rts => true}
options[:max_id] = max_id unless max_id.nil?
@client.user_timeline(user, options)
end
end

fetch_all_tweets("sferik")
get_all_tweets("sferik")
```
22 changes: 22 additions & 0 deletions examples/Search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Search

You can get search results, up to 100 at a time.

Here is an example of recursively geting pages of 100 Tweets until you receive
an empty response.

**Note: This may result in [rate limiting][].**

[rate limiting]: https://github.com/sferik/twitter/blob/master/examples/RateLimiting.md

```ruby
require 'twitter'

def get_all_results(options, collection = [])
results = @client.search(options)
collection += results.to_a
results.next_results? ? get_all_results(results.next_results, collection) : collection
end

get_all_results(:q => "@sferik since:#{Date.today}", :count => 100)
```
43 changes: 30 additions & 13 deletions lib/twitter/rest/api/search.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'twitter/arguments'
require 'twitter/rest/api/utils'
require 'twitter/search_results'

Expand All @@ -15,20 +16,36 @@ module Search
# @rate_limited Yes
# @authentication Requires user context
# @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
# @param q [String] A search term.
# @param options [Hash] A customizable set of options.
# @option options [String] :geocode Returns tweets by users located within a given radius of the given latitude/longitude. The location is preferentially taking from the Geotagging API, but will fall back to their Twitter profile. The parameter value is specified by "latitude,longitude,radius", where radius units must be specified as either "mi" (miles) or "km" (kilometers). Note that you cannot use the near operator via the API to geocode arbitrary locations; however you can use this geocode parameter to search near geocodes directly.
# @option options [String] :lang Restricts tweets to the given language, given by an ISO 639-1 code.
# @option options [String] :locale Specify the language of the query you are sending (only ja is currently effective). This is intended for language-specific clients and the default should work in the majority of cases.
# @option options [String] :result_type Specifies what type of search results you would prefer to receive. Options are "mixed", "recent", and "popular". The current default is "mixed."
# @option options [Integer] :count The number of tweets to return per page, up to a maximum of 100.
# @option options [String] :until Optional. Returns tweets generated before the given date. Date should be formatted as YYYY-MM-DD.
# @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] :include_entities The tweet entities node will be disincluded when set to false.
# @return [Twitter::SearchResults] Return tweets that match a specified query with search metadata
def search(q, options = {})
object_from_response(Twitter::SearchResults, :get, '/1.1/search/tweets.json', options.merge(:q => q))
# @overload search(q, options = {})
# @param q [String] A search term.
# @param options [Hash] A customizable set of options.
# @option options [String] :geocode Returns tweets by users located within a given radius of the given latitude/longitude. The location is preferentially taking from the Geotagging API, but will fall back to their Twitter profile. The parameter value is specified by "latitude,longitude,radius", where radius units must be specified as either "mi" (miles) or "km" (kilometers). Note that you cannot use the near operator via the API to geocode arbitrary locations; however you can use this geocode parameter to search near geocodes directly.
# @option options [String] :lang Restricts tweets to the given language, given by an ISO 639-1 code.
# @option options [String] :locale Specify the language of the query you are sending (only ja is currently effective). This is intended for language-specific clients and the default should work in the majority of cases.
# @option options [String] :result_type Specifies what type of search results you would prefer to receive. Options are "mixed", "recent", and "popular". The current default is "mixed."
# @option options [Integer] :count The number of tweets to return per page, up to a maximum of 100.
# @option options [String] :until Optional. Returns tweets generated before the given date. Date should be formatted as YYYY-MM-DD.
# @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] :include_entities The tweet entities node will be disincluded when set to false.
# @overload search(options)
# @param options [Hash] A customizable set of options.
# @option options [String] :q A search term.
# @option options [String] :geocode Returns tweets by users located within a given radius of the given latitude/longitude. The location is preferentially taking from the Geotagging API, but will fall back to their Twitter profile. The parameter value is specified by "latitude,longitude,radius", where radius units must be specified as either "mi" (miles) or "km" (kilometers). Note that you cannot use the near operator via the API to geocode arbitrary locations; however you can use this geocode parameter to search near geocodes directly.
# @option options [String] :lang Restricts tweets to the given language, given by an ISO 639-1 code.
# @option options [String] :locale Specify the language of the query you are sending (only ja is currently effective). This is intended for language-specific clients and the default should work in the majority of cases.
# @option options [String] :result_type Specifies what type of search results you would prefer to receive. Options are "mixed", "recent", and "popular". The current default is "mixed."
# @option options [Integer] :count The number of tweets to return per page, up to a maximum of 100.
# @option options [String] :until Optional. Returns tweets generated before the given date. Date should be formatted as YYYY-MM-DD.
# @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] :include_entities The tweet entities node will be disincluded when set to false.
def search(*args)
arguments = Twitter::Arguments.new(args)
q = arguments.pop || arguments.options[:q]
fail(ArgumentError, "wrong number of arguments (#{args.size} for #{args.size + 1})") if q.nil?
object_from_response(Twitter::SearchResults, :get, '/1.1/search/tweets.json', arguments.options.merge(:q => q))
end
end
end
Expand Down
40 changes: 26 additions & 14 deletions spec/twitter/rest/api/search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,38 @@
before do
stub_get('/1.1/search/tweets.json').with(:query => {:q => 'twitter'}).to_return(:body => fixture('search.json'), :headers => {:content_type => 'application/json; charset=utf-8'})
end
it 'requests the correct resource' do
@client.search('twitter')
expect(a_get('/1.1/search/tweets.json').with(:query => {:q => 'twitter'})).to have_been_made
end
it 'returns recent Tweets related to a query with images and videos embedded' do
search = @client.search('twitter')
expect(search).to be_a Twitter::SearchResults
expect(search.first).to be_a Twitter::Tweet
expect(search.first.text).to eq('Bubble Mailer #freebandnames')
context 'with query passed as the first argument' do
it 'requests the correct resource' do
@client.search('twitter')
expect(a_get('/1.1/search/tweets.json').with(:query => {:q => 'twitter'})).to have_been_made
end
it 'returns recent Tweets related to a query with images and videos embedded' do
search = @client.search('twitter')
expect(search).to be_a Twitter::SearchResults
expect(search.first).to be_a Twitter::Tweet
expect(search.first.text).to eq('Bubble Mailer #freebandnames')
end
it 'returns the max_id value for a search result' do
search = @client.search('twitter')
expect(search.max_id).to eq(250_126_199_840_518_145)
end
end
it 'returns the max_id value for a search result' do
search = @client.search('twitter')
expect(search.max_id).to eq(250_126_199_840_518_145)
context 'with query passed in options hash' do
it 'requests the correct resource' do
@client.search(:q => 'twitter')
expect(a_get('/1.1/search/tweets.json').with(:query => {:q => 'twitter'})).to have_been_made
end
it 'returns recent Tweets related to a query with images and videos embedded' do
search = @client.search(:q => 'twitter')
expect(search).to be_a Twitter::SearchResults
expect(search.first).to be_a Twitter::Tweet
expect(search.first.text).to eq('Bubble Mailer #freebandnames')
end
end

context 'when search API responds a malformed result' do
before do
stub_get('/1.1/search/tweets.json').with(:query => {:q => 'twitter'}).to_return(:body => fixture('search_malformed.json'), :headers => {:content_type => 'application/json; charset=utf-8'})
end

it 'returns an empty array' do
search = @client.search('twitter')
expect(search.to_a).to be_an Array
Expand Down

0 comments on commit 8e846e1

Please sign in to comment.