hayesdavis-grackle 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -31,7 +31,7 @@ Before you do anything else, you'll need to
31
31
  ====Using OAuth
32
32
  client = Grackle::Client.new(:auth=>{
33
33
  :type=>:oauth,
34
- :consumer_key=>'SOMECONSUMERKEYFROMTWITTER', :consumer_token=>'SOMECONSUMERTOKENFROMTWITTER',
34
+ :consumer_key=>'SOMECONSUMERKEYFROMTWITTER', :consumer_secret=>'SOMECONSUMERTOKENFROMTWITTER',
35
35
  :token=>'ACCESSTOKENACQUIREDONUSERSBEHALF', :token_secret=>'SUPERSECRETACCESSTOKENSECRET'
36
36
  })
37
37
 
data/grackle.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{grackle}
5
- s.version = "0.1.2"
5
+ s.version = "0.1.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Hayes Davis"]
9
- s.date = %q{2009-04-12}
9
+ s.date = %q{2009-05-23}
10
10
  s.description = %q{Grackle is a lightweight library for the Twitter REST and Search API.}
11
11
  s.email = %q{hayes@appozite.com}
12
12
  s.files = ["History.txt", "README.rdoc", "grackle.gemspec", "lib/grackle.rb", "lib/grackle/client.rb", "lib/grackle/handlers.rb", "lib/grackle/transport.rb", "lib/grackle/utils.rb", "test/test_grackle.rb", "test/test_helper.rb", "test/test_client.rb", "test/test_handlers.rb"]
@@ -39,7 +39,7 @@ module Grackle
39
39
  # you've got all the necessary tokens and keys:
40
40
  # client = Grackle::Client.new(:auth=>{
41
41
  # :type=>:oauth,
42
- # :consumer_key=>'SOMECONSUMERKEYFROMTWITTER, :consumer_token=>'SOMECONSUMERTOKENFROMTWITTER',
42
+ # :consumer_key=>'SOMECONSUMERKEYFROMTWITTER, :consumer_secret=>'SOMECONSUMERTOKENFROMTWITTER',
43
43
  # :token=>'ACCESSTOKENACQUIREDONUSERSBEHALF', :token_secret=>'SUPERSECRETACCESSTOKENSECRET'
44
44
  # })
45
45
  class Client
@@ -88,7 +88,7 @@ module Grackle
88
88
  :authorize_path=>'/oauth/authorize'
89
89
  }
90
90
 
91
- attr_accessor :auth, :handlers, :default_format, :headers, :ssl, :api, :transport, :request, :api_hosts
91
+ attr_accessor :auth, :handlers, :default_format, :headers, :ssl, :api, :transport, :request, :api_hosts, :timeout
92
92
 
93
93
  # Arguments (all are optional):
94
94
  # - :username - twitter username to authenticate with (deprecated in favor of :auth arg)
@@ -110,6 +110,7 @@ module Grackle
110
110
  self.ssl = options[:ssl] == true
111
111
  self.api = options[:api] || :rest
112
112
  self.api_hosts = TWITTER_API_HOSTS.clone
113
+ self.timeout = options[:timeout] || 60
113
114
  self.auth = {}
114
115
  if options.has_key?(:username) || options.has_key?(:password)
115
116
  #Use basic auth if :username and :password args are passed in
@@ -202,7 +203,7 @@ module Grackle
202
203
  def send_request(params)
203
204
  begin
204
205
  transport.request(
205
- request.method,request.url,:auth=>auth,:headers=>headers,:params=>params
206
+ request.method,request.url,:auth=>auth,:headers=>headers,:params=>params, :timeout => timeout
206
207
  )
207
208
  rescue => e
208
209
  puts e
@@ -16,6 +16,7 @@ module Grackle
16
16
  attr_accessor :debug
17
17
 
18
18
  CRLF = "\r\n"
19
+ DEFAULT_REDIRECT_LIMIT = 5
19
20
 
20
21
  def req_class(method)
21
22
  case method
@@ -31,6 +32,7 @@ module Grackle
31
32
  # a multipart request will be sent. If a Time is included, .httpdate will be called on it.
32
33
  # - :headers - a hash of headers to send with the request
33
34
  # - :auth - a hash of authentication parameters for either basic or oauth
35
+ # - :timeout - timeout for the http request in seconds
34
36
  def request(method, string_url, options={})
35
37
  params = stringify_params(options[:params])
36
38
  if method == :get && params
@@ -49,6 +51,7 @@ module Grackle
49
51
  conn.use_ssl = (url.scheme == 'https')
50
52
  conn.start do |http|
51
53
  req = req_class(method).new(url.request_uri)
54
+ http.read_timeout = options[:timeout]
52
55
  add_headers(req,options[:headers])
53
56
  if file_param?(options[:params])
54
57
  add_multipart_data(req,options[:params])
@@ -65,7 +68,12 @@ module Grackle
65
68
  dump_request(req) if debug
66
69
  res = http.request(req)
67
70
  dump_response(res) if debug
68
- Response.new(method,url.to_s,res.code.to_i,res.body)
71
+ redirect_limit = options[:redirect_limit] || DEFAULT_REDIRECT_LIMIT
72
+ if res.code.to_s =~ /^30\d$/ && redirect_limit > 0
73
+ execute_request(method,URI.parse(res['location']),options.merge(:redirect_limit=>redirect_limit-1))
74
+ else
75
+ Response.new(method,url.to_s,res.code.to_i,res.body)
76
+ end
69
77
  end
70
78
  end
71
79
 
data/lib/grackle.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Grackle
2
2
 
3
3
  # :stopdoc:
4
- VERSION = '0.1.2'
4
+ VERSION = '0.1.3'
5
5
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
6
6
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
7
7
  # :startdoc:
data/test/test_client.rb CHANGED
@@ -5,21 +5,26 @@ class TestClient < Test::Unit::TestCase
5
5
  #Used for mocking HTTP requests
6
6
  class Net::HTTP
7
7
  class << self
8
- attr_accessor :response, :request, :last_instance
8
+ attr_accessor :response, :request, :last_instance, :responder
9
9
  end
10
10
 
11
11
  def request(req)
12
12
  self.class.last_instance = self
13
- self.class.request = req
14
- self.class.response
13
+ if self.class.responder
14
+ self.class.responder.call(self,req)
15
+ else
16
+ self.class.request = req
17
+ self.class.response
18
+ end
15
19
  end
16
20
  end
17
21
 
18
- #Mock responses that conform mostly to HTTPResponse's interface
19
- class MockResponse
20
- include Net::HTTPHeader
22
+ #Mock responses that conform to HTTPResponse's interface
23
+ class MockResponse < Net::HTTPResponse
24
+ #include Net::HTTPHeader
21
25
  attr_accessor :code, :body
22
26
  def initialize(code,body,headers={})
27
+ super
23
28
  self.code = code
24
29
  self.body = body
25
30
  headers.each do |name, value|
@@ -30,7 +35,7 @@ class TestClient < Test::Unit::TestCase
30
35
 
31
36
  #Transport that collects info on requests and responses for testing purposes
32
37
  class MockTransport < Grackle::Transport
33
- attr_accessor :status, :body, :method, :url, :options
38
+ attr_accessor :status, :body, :method, :url, :options, :timeout
34
39
 
35
40
  def initialize(status,body,headers={})
36
41
  Net::HTTP.response = MockResponse.new(status,body,headers)
@@ -56,6 +61,36 @@ class TestClient < Test::Unit::TestCase
56
61
  end
57
62
  end
58
63
 
64
+ def test_redirects
65
+ redirects = 2 #Check that we can follow 2 redirects before getting to original request
66
+ req_count = 0
67
+ responder = Proc.new do |inst, req|
68
+ req_count += 1
69
+ #Store the original request
70
+ if req_count == 1
71
+ inst.class.request = req
72
+ else
73
+ assert_equal("/somewhere_else#{req_count-1}.json",req.path)
74
+ end
75
+ if req_count <= redirects
76
+ MockResponse.new(302,"You are being redirected",'location'=>"http://twitter.com/somewhere_else#{req_count}.json")
77
+ else
78
+ inst.class.response
79
+ end
80
+ end
81
+ with_http_responder(responder) do
82
+ test_simple_get_request
83
+ end
84
+ assert_equal(redirects+1,req_count)
85
+ end
86
+
87
+ def test_timeouts
88
+ client = new_client(200,'{"id":12345,"screen_name":"test_user"}')
89
+ assert_equal(60, client.timeout)
90
+ client.timeout = 30
91
+ assert_equal(30, client.timeout)
92
+ end
93
+
59
94
  def test_simple_get_request
60
95
  client = new_client(200,'{"id":12345,"screen_name":"test_user"}')
61
96
  value = client.users.show.json? :screen_name=>'test_user'
@@ -150,6 +185,13 @@ class TestClient < Test::Unit::TestCase
150
185
  end
151
186
 
152
187
  private
188
+ def with_http_responder(responder)
189
+ Net::HTTP.responder = responder
190
+ yield
191
+ ensure
192
+ Net::HTTP.responder = nil
193
+ end
194
+
153
195
  def new_client(response_status, response_body, client_opts={})
154
196
  client = Grackle::Client.new(client_opts)
155
197
  client.transport = MockTransport.new(response_status,response_body)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hayesdavis-grackle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hayes Davis
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-12 00:00:00 -07:00
12
+ date: 2009-05-23 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -65,6 +65,7 @@ files:
65
65
  - test/test_handlers.rb
66
66
  has_rdoc: true
67
67
  homepage: http://github.com/hayesdavis/grackle
68
+ licenses:
68
69
  post_install_message:
69
70
  rdoc_options:
70
71
  - --inline-source
@@ -87,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
88
  requirements: []
88
89
 
89
90
  rubyforge_project: grackle
90
- rubygems_version: 1.2.0
91
+ rubygems_version: 1.3.5
91
92
  signing_key:
92
93
  specification_version: 2
93
94
  summary: Grackle is a library for the Twitter REST and Search API designed to not require a new release in the face Twitter API changes or errors. It supports both basic and OAuth authentication mechanisms.