Skip to content

Commit

Permalink
Added search api into the gem and it is dead sexy.
Browse files Browse the repository at this point in the history
  • Loading branch information
jnunemaker committed Aug 4, 2008
1 parent 8bd2585 commit 538a5d4
Show file tree
Hide file tree
Showing 13 changed files with 248 additions and 10 deletions.
3 changes: 3 additions & 0 deletions History.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
0.3.4 - August 3, 2008
* Added search support

0.3.3 - August 3, 2008
* Now has option for host when initializing to support identi.ca (Dustin Sallings)
* Twitter changed a bunch of methods to POST only so I updated those to now work
Expand Down
5 changes: 4 additions & 1 deletion Manifest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ License.txt
Manifest.txt
README.txt
Rakefile
TODO.txt
bin/twitter
config/hoe.rb
config/requirements.rb
Expand All @@ -15,6 +14,7 @@ examples/friendships.rb
examples/identica_timeline.rb
examples/location.rb
examples/replies.rb
examples/search.rb
examples/sent_messages.rb
examples/timeline.rb
examples/twitter.rb
Expand All @@ -34,6 +34,7 @@ lib/twitter/cli/models/tweet.rb
lib/twitter/direct_message.rb
lib/twitter/easy_class_maker.rb
lib/twitter/rate_limit_status.rb
lib/twitter/search.rb
lib/twitter/status.rb
lib/twitter/user.rb
lib/twitter/version.rb
Expand All @@ -51,9 +52,11 @@ spec/fixtures/friends_lite.xml
spec/fixtures/friends_timeline.xml
spec/fixtures/public_timeline.xml
spec/fixtures/rate_limit_status.xml
spec/fixtures/search_results.json
spec/fixtures/status.xml
spec/fixtures/user.xml
spec/fixtures/user_timeline.xml
spec/search_spec.rb
spec/spec.opts
spec/spec_helper.rb
spec/status_spec.rb
Expand Down
7 changes: 7 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ sudo gem install twitter will work just fine. For command line use, you'll need
puts u.name, u.status.text
puts
end

== Search Examples

Twitter::Search.new('httparty').each { |r| puts r.inspect }
Twitter::Search.new('httparty').from('jnunemaker').each { |r| puts r.inspect }
Twitter::Search.new.from('jnunemaker').to('oaknd1').each { |r| puts r.inspect }


== Command Line Use

Expand Down
3 changes: 2 additions & 1 deletion config/hoe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ def extra_deps
#p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
p.extra_deps = [['hpricot', '>= 0.6'], ['activesupport', '>= 2.1'],
['main', '>= 2.8.2'], ['highline', '>= 1.4.0'],
['activerecord', '>= 2.1'], ['sqlite3-ruby', '>= 1.2.2']]
['activerecord', '>= 2.1'], ['sqlite3-ruby', '>= 1.2.2'],
['httparty', '>= 0.1.0']]
#p.spec_extras = {} # A hash of extra values to set in the gemspec.

end
Expand Down
17 changes: 17 additions & 0 deletions examples/search.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require 'rubygems'
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')

Twitter::Search.new('httparty').each { |r| puts r.inspect,'' }

# search = Twitter::Search.new
# search.from('jnunemaker').to('oaknd1').each { |r| puts r.inspect, '' }
# pp search.result
# search.clear

# search.from('jnunemaker').to('oaknd1').since(814529437).containing('milk').each { |r| puts r.inspect, '' }
# search.clear
#
# search.geocode('40.757929', '-73.985506', '50mi').containing('holland').each { |r| puts r.inspect, '' }
# search.clear

# pp search.from('jnunemaker').fetch()
1 change: 1 addition & 0 deletions lib/twitter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require 'twitter/easy_class_maker'
require 'twitter/base'
require 'twitter/user'
require 'twitter/search'
require 'twitter/status'
require 'twitter/direct_message'
require 'twitter/rate_limit_status'
Expand Down
94 changes: 94 additions & 0 deletions lib/twitter/search.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
gem 'httparty'
require 'httparty'

module Twitter
class Search
include HTTParty
include Enumerable
base_uri 'search.twitter.com'

attr_reader :result, :query

def initialize(q=nil)
clear
containing(q) unless q.blank?
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
# 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

# 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 longitude, latitude and a given range.
# Ranges like 25km and 50mi work.
def geocode(long, lat, range)
@query[:geocode] = [long, lat, range].join(',')
self
end

# Clears all the query filters to make a new search
def clear
@query = {}
@query[:q] = []
self
end

# If you want to get results do something other than iterate over them.
def fetch
@query[:q] = @query[:q].join(' ')
self.class.get('/search.json', {:query => @query})
end

def each
@result = fetch()
@result['results'].each { |r| yield r }
end
end
end
2 changes: 1 addition & 1 deletion lib/twitter/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Twitter #:nodoc:
module VERSION #:nodoc:
MAJOR = 0
MINOR = 3
TINY = 3
TINY = 4

STRING = [MAJOR, MINOR, TINY].join('.')
end
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/search_results.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"max_id"=>876733347, "since_id"=>0, "results"=>[{"text"=>"post using httparty.", "from_user"=>"yuweijun", "to_user_id"=>nil, "id"=>876203197, "iso_language_code"=>"en", "from_user_id"=>1170048, "created_at"=>"Sun, 03 Aug 2008 06:40:42 +0000", "profile_image_url"=>"http://static.twitter.com/images/default_profile_normal.png"}, {"text"=>"HTTParty: Quick Web Service Consumption From Any Ruby Class: HTTParty is a new Ruby library by Joh.. http://tinyurl.com/5cb8e8", "from_user"=>"delicious_prog", "to_user_id"=>nil, "id"=>875881978, "iso_language_code"=>"en", "from_user_id"=>468104, "created_at"=>"Sat, 02 Aug 2008 20:47:02 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/54388004/delicious.42px_normal.gif"}, {"text"=>"[4Rails] HTTParty: Quick Web Service Consumption From Any Ruby Class: HTTParty: Quick Web Serv.. http://tinyurl.com/5uemxj", "from_user"=>"bumperbody", "to_user_id"=>nil, "id"=>875828918, "iso_language_code"=>"en", "from_user_id"=>476491, "created_at"=>"Sat, 02 Aug 2008 19:16:19 +0000", "profile_image_url"=>"http://static.twitter.com/images/default_profile_normal.png"}, {"text"=>"[ruby] HTTParty: Quick Web Service Consumption From Any Ruby Class", "from_user"=>"rubymentary", "to_user_id"=>nil, "id"=>875761343, "iso_language_code"=>"en", "from_user_id"=>474717, "created_at"=>"Sat, 02 Aug 2008 17:26:19 +0000", "profile_image_url"=>"http://static.twitter.com/images/default_profile_normal.png"}, {"text"=>"[ruby: RubyInside] HTTParty: Quick Web Service Consumption From Any Ruby Class http://tinyurl.com/5gryre", "from_user"=>"devfunnel", "to_user_id"=>nil, "id"=>875732752, "iso_language_code"=>"en", "from_user_id"=>465190, "created_at"=>"Sat, 02 Aug 2008 16:44:21 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/53748400/dev-funnel-logo-shiny-50x50_normal.png"}, {"text"=>"using the excellent OpenLibrary API, via HTTParty - i do like it that people have thought i'd want to do this in advance!", "from_user"=>"degsy", "to_user_id"=>nil, "id"=>875690354, "iso_language_code"=>"en", "from_user_id"=>164367, "created_at"=>"Sat, 02 Aug 2008 15:43:58 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/56185617/degsy_normal.jpg"}, {"text"=>"httparty gem rocks", "from_user"=>"shenie", "to_user_id"=>nil, "id"=>874139770, "iso_language_code"=>"en", "from_user_id"=>271831, "created_at"=>"Thu, 31 Jul 2008 22:58:19 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/42362902/Photo_28_normal.jpg"}, {"text"=>"httparty  yup.  that is what i was missing", "from_user"=>"bryanl", "to_user_id"=>nil, "id"=>873839285, "iso_language_code"=>"en", "from_user_id"=>5167, "created_at"=>"Thu, 31 Jul 2008 17:15:51 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/57603306/Photo_26_normal.jpg"}, {"text"=>"@timhaines thanks for the link to HTTParty, Xero api consumer for contacts (at least the get part) now only takes 18 lines of code.", "from_user"=>"buildmaster", "to_user"=>"timhaines", "to_user_id"=>159881, "id"=>873222820, "iso_language_code"=>"en", "from_user_id"=>26548, "created_at"=>"Thu, 31 Jul 2008 02:29:02 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/51894576/gold_o_normal.jpg"}, {"text"=>"refactoring code from yesterdays example to use HTTParty", "from_user"=>"buildmaster", "to_user_id"=>nil, "id"=>873020059, "iso_language_code"=>"en", "from_user_id"=>26548, "created_at"=>"Wed, 30 Jul 2008 21:55:19 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/51894576/gold_o_normal.jpg"}, {"text"=>"delicious: It's an HTTParty and Everyone Is Invited! // RailsTips.org by John Nunemaker http://tinyurl.com/6774gz", "from_user"=>"top_web", "to_user_id"=>nil, "id"=>872810034, "iso_language_code"=>"en", "from_user_id"=>780201, "created_at"=>"Wed, 30 Jul 2008 17:48:25 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/55853305/web_normal.jpg"}, {"text"=>"d: It's an HTTParty and Everyone Is Invited! // RailsTips.org by John Nunemaker http://tinyurl.com/6774gz", "from_user"=>"top_dedist", "to_user_id"=>nil, "id"=>872809988, "iso_language_code"=>"en", "from_user_id"=>760334, "created_at"=>"Wed, 30 Jul 2008 17:48:20 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/55845227/dedist_normal.jpg"}, {"text"=>"[4Rails] It's an HTTParty and Everyone Is Invited! // RailsTips.org by John Nunemaker: It's an.. http://tinyurl.com/57wjn4", "from_user"=>"bumperbody", "to_user_id"=>nil, "id"=>872549387, "iso_language_code"=>"en", "from_user_id"=>476491, "created_at"=>"Wed, 30 Jul 2008 13:16:57 +0000", "profile_image_url"=>"http://static.twitter.com/images/default_profile_normal.png"}, {"text"=>"New blog post: Sinatra, Passenger, HTTParty: Small, Fast, Now http://ruby.tie-rack.org/?p=70", "from_user"=>"tierack", "to_user_id"=>nil, "id"=>872275405, "iso_language_code"=>"no", "from_user_id"=>98800, "created_at"=>"Wed, 30 Jul 2008 04:55:40 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/52166714/mvb200_normal.jpg"}, {"text"=>"Tonight we're gonna HTTParty like it's 1999! - Time to boogie on down and consume some webservices! http://httparty.rubyforge.org/", "from_user"=>"hunternield", "to_user_id"=>nil, "id"=>872086627, "iso_language_code"=>"en", "from_user_id"=>47386, "created_at"=>"Wed, 30 Jul 2008 00:12:47 +0000", "profile_image_url"=>"http://s3.amazonaws.com/twitter_production/profile_images/52133648/Photo_59_normal.jpg"}], "results_per_page"=>15, "next_page"=>"?page=2&max_id=876733347&q=httparty+", "query"=>"httparty ", "page"=>1}
89 changes: 89 additions & 0 deletions spec/search_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
require File.dirname(__FILE__) + '/spec_helper.rb'

describe Twitter::Search do
before do
@search = Twitter::Search.new
end

it "should be able to initialize with a search term" do
Twitter::Search.new('httparty').query[:q].should include('httparty')
end

it "should be able to specify from" do
@search.from('jnunemaker').query[:q].should include('from:jnunemaker')
end

it "should be able to specify to" do
@search.to('jnunemaker').query[:q].should include('to:jnunemaker')
end

it "should be able to specify referencing" do
@search.referencing('jnunemaker').query[:q].should include('@jnunemaker')
end

it "should alias references to referencing" do
@search.references('jnunemaker').query[:q].should include('@jnunemaker')
end

it "should alias ref to referencing" do
@search.ref('jnunemaker').query[:q].should include('@jnunemaker')
end

it "should be able to specify containing" do
@search.containing('milk').query[:q].should include('milk')
end

it "should alias contains to containing" do
@search.contains('milk').query[:q].should include('milk')
end

it "should be able to specify hashed" do
@search.hashed('twitter').query[:q].should include('#twitter')
end

it "should be able to specify the language" do
@search.lang('en').query[:lang].should == 'en'
end

it "should be able to specify the number of results per page" do
@search.per_page(25).query[:rpp].should == 25
end

it "should be able to specify only returning results greater than an id" do
@search.since(1234).query[:since_id].should == 1234
end

it "should be able to specify geo coordinates" do
@search.geocode('40.757929', '-73.985506', '25mi').query[:geocode].should == '40.757929,-73.985506,25mi'
end

it "should be able to clear the filters set" do
@search.from('jnunemaker').to('oaknd1')
@search.clear.query.should == {:q => []}
end

it "should be able to chain methods together" do
@search.from('jnunemaker').to('oaknd1').referencing('orderedlist').containing('milk').hashed('twitter').lang('en').per_page(20).since(1234).geocode('40.757929', '-73.985506', '25mi')
@search.query[:q].should == ['from:jnunemaker', 'to:oaknd1', '@orderedlist', 'milk', '#twitter']
@search.query[:lang].should == 'en'
@search.query[:rpp].should == 20
@search.query[:since_id].should == 1234
@search.query[:geocode].should == '40.757929,-73.985506,25mi'
end

describe "fetching" do
before do
@response = open(File.dirname(__FILE__) + '/fixtures/friends_timeline.xml').read
@search.class.stub!(:get).and_return(@response)
end

it "should return results" do
@search.class.should_receive(:get).and_return(@response)
@search.from('jnunemaker').fetch().should == @response
end
end

it "should be able to iterate over results" do
@search.respond_to?(:each).should == true
end
end
10 changes: 7 additions & 3 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
require 'rubygems'
gem 'rspec'
require 'spec'
begin
require 'spec'
rescue LoadError
require 'rubygems'
gem 'rspec'
require 'spec'
end

dir = File.dirname(__FILE__)

Expand Down
9 changes: 6 additions & 3 deletions twitter.gemspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = %q{twitter}
s.version = "0.3.3"
s.version = "0.3.4"

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["John Nunemaker"]
Expand All @@ -9,8 +9,8 @@ Gem::Specification.new do |s|
s.description = %q{a command line interface for twitter, also a library which wraps the twitter api}
s.email = %q{[email protected]}
s.executables = ["twitter"]
s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt", "README.txt", "TODO.txt"]
s.files = ["History.txt", "License.txt", "Manifest.txt", "README.txt", "Rakefile", "TODO.txt", "bin/twitter", "config/hoe.rb", "config/requirements.rb", "examples/blocks.rb", "examples/direct_messages.rb", "examples/favorites.rb", "examples/friends_followers.rb", "examples/friendships.rb", "examples/identica_timeline.rb", "examples/location.rb", "examples/replies.rb", "examples/sent_messages.rb", "examples/timeline.rb", "examples/twitter.rb", "examples/verify_credentials.rb", "lib/twitter.rb", "lib/twitter/base.rb", "lib/twitter/cli.rb", "lib/twitter/cli/config.rb", "lib/twitter/cli/helpers.rb", "lib/twitter/cli/migrations/20080722194500_create_accounts.rb", "lib/twitter/cli/migrations/20080722194508_create_tweets.rb", "lib/twitter/cli/migrations/20080722214605_add_account_id_to_tweets.rb", "lib/twitter/cli/migrations/20080722214606_create_configurations.rb", "lib/twitter/cli/models/account.rb", "lib/twitter/cli/models/configuration.rb", "lib/twitter/cli/models/tweet.rb", "lib/twitter/direct_message.rb", "lib/twitter/easy_class_maker.rb", "lib/twitter/rate_limit_status.rb", "lib/twitter/status.rb", "lib/twitter/user.rb", "lib/twitter/version.rb", "script/destroy", "script/generate", "script/txt2html", "setup.rb", "spec/base_spec.rb", "spec/cli/helper_spec.rb", "spec/direct_message_spec.rb", "spec/fixtures/followers.xml", "spec/fixtures/friends.xml", "spec/fixtures/friends_for.xml", "spec/fixtures/friends_lite.xml", "spec/fixtures/friends_timeline.xml", "spec/fixtures/public_timeline.xml", "spec/fixtures/rate_limit_status.xml", "spec/fixtures/status.xml", "spec/fixtures/user.xml", "spec/fixtures/user_timeline.xml", "spec/spec.opts", "spec/spec_helper.rb", "spec/status_spec.rb", "spec/user_spec.rb", "tasks/deployment.rake", "tasks/environment.rake", "tasks/website.rake", "twitter.gemspec", "website/css/common.css", "website/images/terminal_output.png", "website/index.html"]
s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt", "README.txt"]
s.files = ["History.txt", "License.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/twitter", "config/hoe.rb", "config/requirements.rb", "examples/blocks.rb", "examples/direct_messages.rb", "examples/favorites.rb", "examples/friends_followers.rb", "examples/friendships.rb", "examples/identica_timeline.rb", "examples/location.rb", "examples/replies.rb", "examples/search.rb", "examples/sent_messages.rb", "examples/timeline.rb", "examples/twitter.rb", "examples/verify_credentials.rb", "lib/twitter.rb", "lib/twitter/base.rb", "lib/twitter/cli.rb", "lib/twitter/cli/config.rb", "lib/twitter/cli/helpers.rb", "lib/twitter/cli/migrations/20080722194500_create_accounts.rb", "lib/twitter/cli/migrations/20080722194508_create_tweets.rb", "lib/twitter/cli/migrations/20080722214605_add_account_id_to_tweets.rb", "lib/twitter/cli/migrations/20080722214606_create_configurations.rb", "lib/twitter/cli/models/account.rb", "lib/twitter/cli/models/configuration.rb", "lib/twitter/cli/models/tweet.rb", "lib/twitter/direct_message.rb", "lib/twitter/easy_class_maker.rb", "lib/twitter/rate_limit_status.rb", "lib/twitter/search.rb", "lib/twitter/status.rb", "lib/twitter/user.rb", "lib/twitter/version.rb", "script/destroy", "script/generate", "script/txt2html", "setup.rb", "spec/base_spec.rb", "spec/cli/helper_spec.rb", "spec/direct_message_spec.rb", "spec/fixtures/followers.xml", "spec/fixtures/friends.xml", "spec/fixtures/friends_for.xml", "spec/fixtures/friends_lite.xml", "spec/fixtures/friends_timeline.xml", "spec/fixtures/public_timeline.xml", "spec/fixtures/rate_limit_status.xml", "spec/fixtures/search_results.json", "spec/fixtures/status.xml", "spec/fixtures/user.xml", "spec/fixtures/user_timeline.xml", "spec/search_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/status_spec.rb", "spec/user_spec.rb", "tasks/deployment.rake", "tasks/environment.rake", "tasks/website.rake", "twitter.gemspec", "website/css/common.css", "website/images/terminal_output.png", "website/index.html"]
s.has_rdoc = true
s.homepage = %q{http://twitter.rubyforge.org}
s.rdoc_options = ["--main", "README.txt"]
Expand All @@ -30,13 +30,15 @@ Gem::Specification.new do |s|
s.add_runtime_dependency(%q<highline>, [">= 1.4.0"])
s.add_runtime_dependency(%q<activerecord>, [">= 2.1"])
s.add_runtime_dependency(%q<sqlite3-ruby>, [">= 1.2.2"])
s.add_runtime_dependency(%q<httparty>, [">= 0.1.0"])
else
s.add_dependency(%q<hpricot>, [">= 0.6"])
s.add_dependency(%q<activesupport>, [">= 2.1"])
s.add_dependency(%q<main>, [">= 2.8.2"])
s.add_dependency(%q<highline>, [">= 1.4.0"])
s.add_dependency(%q<activerecord>, [">= 2.1"])
s.add_dependency(%q<sqlite3-ruby>, [">= 1.2.2"])
s.add_dependency(%q<httparty>, [">= 0.1.0"])
end
else
s.add_dependency(%q<hpricot>, [">= 0.6"])
Expand All @@ -45,5 +47,6 @@ Gem::Specification.new do |s|
s.add_dependency(%q<highline>, [">= 1.4.0"])
s.add_dependency(%q<activerecord>, [">= 2.1"])
s.add_dependency(%q<sqlite3-ruby>, [">= 1.2.2"])
s.add_dependency(%q<httparty>, [">= 0.1.0"])
end
end
Loading

0 comments on commit 538a5d4

Please sign in to comment.