dancroak-twitter-search 0.5.3 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.textile CHANGED
@@ -1,7 +1,16 @@
1
+ h2. 0.5.5 (May 18, 2009)
2
+
3
+ * raise error when query contains :near or :within:. (Dan Croak)
4
+
5
+ h2. 0.5.4 (May 16, 2009)
6
+
7
+ * Fixed bug in Twitter trends. (Dan Croak)
8
+ * Refactored test suite. Now organized by function, uses redgreen, began moving toward using JSON instead of YAML for fixtures. (Dan Croak)
9
+ * Exposed Shoulda Macros to apps that want to use them. (Dan Croak)
10
+
1
11
  h2. 0.5.3 (May 15, 2009)
2
12
 
3
13
  * Added Twitter trends. (Matt Sanford)
4
- * Added overdue attribution for Luke Francl, Matt Sanford, Alejandro Crosa,
5
- Danny Burkes, Don Brown, & HotFusionMan.
14
+ * Added overdue attribution for Luke Francl, Matt Sanford, Alejandro Crosa, Danny Burkes, Don Brown, & HotFusionMan.
6
15
  * Added CHANGELOG. (Dan Croak)
7
16
 
data/README.markdown CHANGED
@@ -84,7 +84,7 @@ Dustin Sallings, Dan Croak, Luke Francl, Matt Sanford, Alejandro Crosa, Danny Bu
84
84
 
85
85
  ## Resources
86
86
 
87
- * [Official Twitter Search API](http://search.twitter.com/api)
87
+ * [Official Twitter Search API](http://apiwiki.twitter.com/Twitter-API-Documentation)
88
88
 
89
89
  ## License
90
90
 
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rake'
2
2
  require 'rake/testtask'
3
3
 
4
- test_files_pattern = 'test/twitter_*_test.rb'
4
+ test_files_pattern = 'test/*_test.rb'
5
5
  Rake::TestTask.new do |t|
6
6
  t.libs << 'lib'
7
7
  t.pattern = test_files_pattern
@@ -13,13 +13,13 @@ task :default => :test
13
13
 
14
14
  gem_spec = Gem::Specification.new do |gem_spec|
15
15
  gem_spec.name = "twitter-search"
16
- gem_spec.version = "0.5.3"
17
- gem_spec.summary = "Ruby client for Twitter Search."
16
+ gem_spec.version = "0.5.5"
17
+ gem_spec.summary = "Ruby client for Twitter Search. Includes trends."
18
18
  gem_spec.email = "dcroak@thoughtbot.com"
19
19
  gem_spec.homepage = "http://github.com/dancroak/twitter-search"
20
20
  gem_spec.description = "Ruby client for Twitter Search."
21
21
  gem_spec.authors = ["Dustin Sallings", "Dan Croak", "Luke Francl", "Matt Sanford", "Alejandro Crosa", "Danny Burkes", "Don Brown", "HotFusionMan"]
22
- gem_spec.files = FileList["[A-Z]*", "{generators,lib,shoulda_macros,rails}/**/*"]
22
+ gem_spec.files = FileList["[A-Z]*", "{lib,shoulda_macros}/**/*"]
23
23
  gem_spec.add_dependency('json', '>= 1.1.2')
24
24
  end
25
25
 
@@ -64,7 +64,7 @@ end
64
64
  def write_yaml(opts = {})
65
65
  @client = TwitterSearch::Client.new 'twitter-search'
66
66
  tweets = @client.query(opts[:tweets])
67
- File.open(File.join(File.dirname(__FILE__), 'test', 'yaml', "#{opts[:file]}.yaml"), 'w+') do |file|
67
+ File.open(File.join(File.dirname(__FILE__), 'test', 'yaml', "#{opts[:file]}.yaml"), 'w+') do |file|
68
68
  file.puts tweets.to_yaml
69
69
  end
70
70
  end
data/lib/trends.rb CHANGED
@@ -3,7 +3,7 @@ module TwitterSearch
3
3
  VARS = [ :query, :name ]
4
4
  attr_reader *VARS
5
5
  attr_reader :exclude_hashtags
6
-
6
+
7
7
  def initialize(opts)
8
8
  @exclude_hashtags = !!opts['exclude_hashtags']
9
9
  VARS.each { |each| instance_variable_set "@#{each}", opts[each.to_s] }
@@ -17,7 +17,7 @@ module TwitterSearch
17
17
  include Enumerable
18
18
 
19
19
  def initialize(opts)
20
- @trends = opts['trends'].first.collect { |each| Trend.new(each) }
20
+ @trends = opts['trends'].values.first.collect { |each| Trend.new(each) }
21
21
  VARS.each { |each| instance_variable_set "@#{each}", opts[each.to_s] }
22
22
  end
23
23
 
@@ -28,9 +28,9 @@ module TwitterSearch
28
28
  def size
29
29
  @trends.size
30
30
  end
31
-
31
+
32
32
  def [](index)
33
33
  @trends[index]
34
34
  end
35
35
  end
36
- end
36
+ end
data/lib/tweets.rb CHANGED
@@ -3,7 +3,7 @@ module TwitterSearch
3
3
  VARS = [:text, :from_user, :to_user, :to_user_id, :id, :iso_language_code, :from_user_id, :created_at, :profile_image_url, :source ]
4
4
  attr_reader *VARS
5
5
  attr_reader :language
6
-
6
+
7
7
  def initialize(opts)
8
8
  @language = opts['iso_language_code']
9
9
  VARS.each { |each| instance_variable_set "@#{each}", opts[each.to_s] }
@@ -28,7 +28,7 @@ module TwitterSearch
28
28
  def size
29
29
  @results.size
30
30
  end
31
-
31
+
32
32
  def [](index)
33
33
  @results[index]
34
34
  end
@@ -42,4 +42,4 @@ module TwitterSearch
42
42
  return client.query( CGI.parse( @next_page[1..-1] ) )
43
43
  end
44
44
  end
45
- end
45
+ end
@@ -7,41 +7,45 @@ require File.join(File.dirname(__FILE__), 'tweets')
7
7
  require File.join(File.dirname(__FILE__), 'trends')
8
8
 
9
9
  module TwitterSearch
10
+ class SearchOperatorError < ArgumentError
11
+ end
10
12
 
11
13
  class Client
12
14
  TWITTER_SEARCH_API_URL = 'http://search.twitter.com/search.json'
13
15
  TWITTER_TRENDS_API_URL = 'http://search.twitter.com/trends/current.json'
14
- TWITTER_API_DEFAULT_TIMEOUT = 5
15
-
16
+ DEFAULT_TIMEOUT = 5
17
+
16
18
  attr_accessor :agent
17
19
  attr_accessor :timeout
18
-
19
- def initialize(agent = 'twitter-search', timeout = TWITTER_API_DEFAULT_TIMEOUT)
20
+
21
+ def initialize(agent = 'twitter-search', timeout = DEFAULT_TIMEOUT)
20
22
  @agent = agent
21
23
  @timeout = timeout
22
24
  end
23
-
25
+
24
26
  def headers
25
27
  { "Content-Type" => 'application/json',
26
28
  "User-Agent" => @agent }
27
29
  end
28
-
30
+
29
31
  def query(opts = {})
30
32
  url = URI.parse(TWITTER_SEARCH_API_URL)
31
33
  url.query = sanitize_query(opts)
32
34
 
35
+ ensure_no_location_operators(url.query)
36
+
33
37
  req = Net::HTTP::Get.new(url.path)
34
38
  http = Net::HTTP.new(url.host, url.port)
35
39
  http.read_timeout = timeout
36
-
40
+
37
41
  json = http.start { |http|
38
42
  http.get("#{url.path}?#{url.query}", headers)
39
43
  }.body
40
44
  Tweets.new JSON.parse(json)
41
45
  end
42
-
46
+
43
47
  def trends(opts = {})
44
- url = URI.parse(TWITTER_TRENDS_API_URL)
48
+ url = URI.parse(TWITTER_TRENDS_API_URL)
45
49
  if opts['exclude_hashtags']
46
50
  url.query = sanitize_query_hash({ :exclude_hashtags => opts['exclude_hashtags'] })
47
51
  end
@@ -49,7 +53,7 @@ module TwitterSearch
49
53
  req = Net::HTTP::Get.new(url.path)
50
54
  http = Net::HTTP.new(url.host, url.port)
51
55
  http.read_timeout = timeout
52
-
56
+
53
57
  json = http.start { |http|
54
58
  http.get("#{url.path}?#{url.query}", headers)
55
59
  }.body
@@ -60,18 +64,25 @@ module TwitterSearch
60
64
 
61
65
  def sanitize_query(opts)
62
66
  if opts.is_a? String
63
- "q=#{CGI.escape(opts)}"
67
+ "q=#{CGI.escape(opts)}"
64
68
  elsif opts.is_a? Hash
65
69
  "#{sanitize_query_hash(opts)}"
66
70
  end
67
71
  end
68
72
 
69
73
  def sanitize_query_hash(query_hash)
70
- query_hash.collect { |key, value|
71
- "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
74
+ query_hash.collect { |key, value|
75
+ "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
72
76
  }.join('&')
73
77
  end
74
-
75
- end
76
78
 
79
+ def ensure_no_location_operators(query_string)
80
+ if query_string.include?("near%3A") ||
81
+ query_string.include?("within%3A")
82
+ raise TwitterSearch::SearchOperatorError,
83
+ "near: and within: are available from the Twitter Search web interface, but not the API. The API requires the geocode parameter. See dancroak/twitter-search README."
84
+ end
85
+ end
86
+
87
+ end
77
88
  end
@@ -0,0 +1,36 @@
1
+ module TwitterSearch
2
+ module Shoulda
3
+ def should_have_default_search_behaviors
4
+ should_find_tweets
5
+ should_have_text_for_all_tweets
6
+ should_return_page 1
7
+ should_return_tweets_in_sets_of 15
8
+ end
9
+
10
+ def should_find_tweets
11
+ should 'find tweets' do
12
+ assert @tweets.any?
13
+ end
14
+ end
15
+
16
+ def should_have_text_for_all_tweets
17
+ should 'have text for all tweets' do
18
+ assert @tweets.all? { |tweet| tweet.text.size > 0 }
19
+ end
20
+ end
21
+
22
+ def should_return_page(number)
23
+ should "return page #{number}" do
24
+ assert_equal number, @tweets.page
25
+ end
26
+ end
27
+
28
+ def should_return_tweets_in_sets_of(number)
29
+ should "return tweets in sets of #{number}" do
30
+ assert_equal number, @tweets.results_per_page
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ Test::Unit::TestCase.extend(TwitterSearch::Shoulda)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dancroak-twitter-search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dustin Sallings
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2009-05-14 21:00:00 -07:00
19
+ date: 2009-05-17 21:00:00 -07:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -45,6 +45,7 @@ files:
45
45
  - lib/trends.rb
46
46
  - lib/tweets.rb
47
47
  - lib/twitter_search.rb
48
+ - shoulda_macros/twitter_search.rb
48
49
  has_rdoc: true
49
50
  homepage: http://github.com/dancroak/twitter-search
50
51
  post_install_message:
@@ -70,6 +71,6 @@ rubyforge_project:
70
71
  rubygems_version: 1.2.0
71
72
  signing_key:
72
73
  specification_version: 3
73
- summary: Ruby client for Twitter Search.
74
+ summary: Ruby client for Twitter Search. Includes trends.
74
75
  test_files: []
75
76