grackle 0.1.5 → 0.1.6
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/CHANGELOG.rdoc +4 -0
- data/README.rdoc +20 -0
- data/grackle.gemspec +2 -2
- data/lib/grackle/client.rb +60 -27
- data/lib/grackle/transport.rb +1 -6
- data/lib/grackle.rb +1 -1
- data/test/test_client.rb +39 -0
- metadata +2 -2
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
== 0.1.6 (2009-10-29)
|
2
|
+
* Added support for HTTP methods beside GET and POST using block syntax
|
3
|
+
* Added method for appending to the request path something that's not a valid ruby method
|
4
|
+
|
1
5
|
== 0.1.5 (2009-10-28)
|
2
6
|
Added support for the Twitter version 1 API as a API symbol :v1
|
3
7
|
|
data/README.rdoc
CHANGED
@@ -79,6 +79,20 @@ You can force a format. To update the authenticated user's status using the XML
|
|
79
79
|
|
80
80
|
Or, with JSON
|
81
81
|
client.statuses.update.json! :status=>'this status is from grackle' #POST to http://twitter.com/statuses/update.json
|
82
|
+
|
83
|
+
===Using Other HTTP Verbs
|
84
|
+
To use HTTP verbs like DELETE or PUT, Grackle provides a slightly different syntax:
|
85
|
+
client.put{ hayesdavis.lists.my_list :name=>'New Name' } #HTTP PUT
|
86
|
+
client.delete{ direct_messages.destroy :id=>1 } #HTTP DELETE
|
87
|
+
|
88
|
+
You may specify any method chain you wish in the block. Note that if your method chain inside the block
|
89
|
+
ends in a ! or ?, that the HTTP verb for the block will still be used. This means that
|
90
|
+
client.delete{ direct_messages.destroy! :id=>1 } #Uses HTTP DELETE, not POST
|
91
|
+
client.direct_messages.destroy! :id=>1 #Uses HTTP POST
|
92
|
+
|
93
|
+
If for some reason you don't like the preferred block syntax above, you may specify a
|
94
|
+
parameter to your method chain called :__method (note the double underscores) to specify the HTTP verb:
|
95
|
+
client.direct_messages.destroy! :id=>1, :__method=>:delete #HTTP DELETE
|
82
96
|
|
83
97
|
===Toggling APIs
|
84
98
|
By default, the Grackle::Client sends all requests to the unversioned Twitter REST API. If you want to send requests to
|
@@ -125,6 +139,12 @@ the raw response body. The Grackle::Client has a default_format you can specify.
|
|
125
139
|
If you don't include a named format in your method chain as described above, but use a "?" or "!" then the
|
126
140
|
Grackle::Client.default_format is used.
|
127
141
|
|
142
|
+
===Odds and Ends
|
143
|
+
If you need to append something to the request path that isn't a valid ruby method, e.g.
|
144
|
+
/1user/lists.json #1user isn't a valid Ruby method
|
145
|
+
you can use the Grackle::Client#_ method like so:
|
146
|
+
client._('1user').lists.json
|
147
|
+
|
128
148
|
== REQUIREMENTS:
|
129
149
|
|
130
150
|
You'll need the following gems to use all features of Grackle:
|
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.
|
5
|
+
s.version = "0.1.6"
|
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-
|
9
|
+
s.date = %q{2009-10-29}
|
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 = ["CHANGELOG.rdoc", "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"]
|
data/lib/grackle/client.rb
CHANGED
@@ -45,13 +45,12 @@ module Grackle
|
|
45
45
|
class Client
|
46
46
|
|
47
47
|
class Request #:nodoc:
|
48
|
-
attr_accessor :client, :path, :method, :api, :ssl
|
48
|
+
attr_accessor :client, :path, :method, :api, :ssl, :params
|
49
49
|
|
50
50
|
def initialize(client,api=:rest,ssl=true)
|
51
51
|
self.client = client
|
52
52
|
self.api = api
|
53
53
|
self.ssl = ssl
|
54
|
-
self.method = :get
|
55
54
|
self.path = ''
|
56
55
|
end
|
57
56
|
|
@@ -74,9 +73,12 @@ module Grackle
|
|
74
73
|
def scheme
|
75
74
|
ssl ? 'https' :'http'
|
76
75
|
end
|
76
|
+
|
77
|
+
def params
|
78
|
+
@params ||= {}
|
79
|
+
end
|
77
80
|
end
|
78
81
|
|
79
|
-
VALID_METHODS = [:get,:post,:put,:delete]
|
80
82
|
VALID_FORMATS = [:json,:xml,:atom,:rss]
|
81
83
|
|
82
84
|
# Contains the mapping of API name symbols to actual host (and path)
|
@@ -133,26 +135,11 @@ module Grackle
|
|
133
135
|
end
|
134
136
|
end
|
135
137
|
|
136
|
-
def method_missing(name,*args)
|
137
|
-
|
138
|
-
|
139
|
-
return call_with_format(name,*args)
|
140
|
-
end
|
141
|
-
#If method ends in ! or ? use that to determine post or get
|
142
|
-
if name.to_s =~ /^(.*)(!|\?)$/
|
143
|
-
name = $1.to_sym
|
144
|
-
#! is a post, ? is a get
|
145
|
-
self.request.method = ($2 == '!' ? :post : :get)
|
146
|
-
if format_invocation?(name)
|
147
|
-
return call_with_format(name,*args)
|
148
|
-
else
|
149
|
-
self.request << "/#{$1}"
|
150
|
-
return call_with_format(self.default_format,*args)
|
151
|
-
end
|
138
|
+
def method_missing(name,*args,&block)
|
139
|
+
if block_given?
|
140
|
+
return request_with_http_method_block(name,&block)
|
152
141
|
end
|
153
|
-
|
154
|
-
self.request << "/#{name}"
|
155
|
-
self
|
142
|
+
append(name,*args)
|
156
143
|
end
|
157
144
|
|
158
145
|
# Used to toggle APIs for a particular request without setting the Client's default API
|
@@ -197,21 +184,53 @@ module Grackle
|
|
197
184
|
auth[:password] = value
|
198
185
|
end
|
199
186
|
|
187
|
+
def append(name,*args)
|
188
|
+
name = name.to_sym
|
189
|
+
#The args will be a hash, store them if they're specified
|
190
|
+
self.request.params = *args
|
191
|
+
#If method is a format name, execute using that format
|
192
|
+
if format_invocation?(name)
|
193
|
+
return call_with_format(name)
|
194
|
+
end
|
195
|
+
#If method ends in ! or ? use that to determine post or get
|
196
|
+
if name.to_s =~ /^(.*)(!|\?)$/
|
197
|
+
name = $1.to_sym
|
198
|
+
#! is a post, ? is a get - only set this if the method hasn't been set
|
199
|
+
self.request.method ||= ($2 == '!' ? :post : :get)
|
200
|
+
if format_invocation?(name)
|
201
|
+
return call_with_format(name)
|
202
|
+
else
|
203
|
+
self.request << "/#{$1}"
|
204
|
+
return call_with_format(self.default_format)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
#Else add to the request path
|
208
|
+
self.request << "/#{name}"
|
209
|
+
self
|
210
|
+
end
|
211
|
+
|
212
|
+
alias_method :_, :append
|
213
|
+
|
200
214
|
protected
|
201
|
-
def call_with_format(format
|
202
|
-
id = params.delete(:id)
|
215
|
+
def call_with_format(format)
|
216
|
+
id = request.params.delete(:id)
|
203
217
|
request << "/#{id}" if id
|
204
218
|
request << ".#{format}"
|
205
|
-
res = send_request
|
219
|
+
res = send_request
|
206
220
|
process_response(format,res)
|
207
221
|
ensure
|
208
222
|
clear
|
209
223
|
end
|
210
224
|
|
211
|
-
def send_request
|
225
|
+
def send_request
|
212
226
|
begin
|
227
|
+
http_method = (
|
228
|
+
request.params.delete(:__method) or request.method or :get
|
229
|
+
)
|
213
230
|
transport.request(
|
214
|
-
|
231
|
+
http_method, request.url,
|
232
|
+
:auth=>auth,:headers=>headers,
|
233
|
+
:params=>request.params,:timeout => timeout
|
215
234
|
)
|
216
235
|
rescue => e
|
217
236
|
puts e
|
@@ -251,5 +270,19 @@ module Grackle
|
|
251
270
|
def format_invocation?(name)
|
252
271
|
self.request.path? && VALID_FORMATS.include?(name)
|
253
272
|
end
|
273
|
+
|
274
|
+
def pending_request?
|
275
|
+
!@request.nil?
|
276
|
+
end
|
277
|
+
|
278
|
+
def request_with_http_method_block(method,&block)
|
279
|
+
request.method = method
|
280
|
+
response = instance_eval(&block)
|
281
|
+
if pending_request?
|
282
|
+
call_with_format(self.default_format)
|
283
|
+
else
|
284
|
+
response
|
285
|
+
end
|
286
|
+
end
|
254
287
|
end
|
255
288
|
end
|
data/lib/grackle/transport.rb
CHANGED
@@ -19,12 +19,7 @@ module Grackle
|
|
19
19
|
DEFAULT_REDIRECT_LIMIT = 5
|
20
20
|
|
21
21
|
def req_class(method)
|
22
|
-
|
23
|
-
when :get then Net::HTTP::Get
|
24
|
-
when :post then Net::HTTP::Post
|
25
|
-
when :put then Net::HTTP::Put
|
26
|
-
when :delete then Net::HTTP::Delete
|
27
|
-
end
|
22
|
+
Net::HTTP.const_get(method.to_s.capitalize)
|
28
23
|
end
|
29
24
|
|
30
25
|
# Options are one of
|
data/lib/grackle.rb
CHANGED
data/test/test_client.rb
CHANGED
@@ -195,6 +195,45 @@ class TestClient < Test::Unit::TestCase
|
|
195
195
|
client.statuses.public_timeline? :since=>time
|
196
196
|
assert_equal("/statuses/public_timeline.json?since=#{CGI::escape(time.httpdate)}",Net::HTTP.request.path)
|
197
197
|
end
|
198
|
+
|
199
|
+
def test_simple_http_method_block
|
200
|
+
client = new_client(200,'[{"id":1,"text":"test 1"}]')
|
201
|
+
client.delete { direct_messages.destroy :id=>1, :other=>'value' }
|
202
|
+
assert_equal(:delete,client.transport.method, "delete block should use delete method")
|
203
|
+
assert_equal("/direct_messages/destroy/1.json",Net::HTTP.request.path)
|
204
|
+
assert_equal('value',client.transport.options[:params][:other])
|
205
|
+
|
206
|
+
client = new_client(200,'{"id":54321,"screen_name":"test_user"}')
|
207
|
+
value = client.get { users.show.json? :screen_name=>'test_user' }
|
208
|
+
assert_equal(:get,client.transport.method)
|
209
|
+
assert_equal('http',client.transport.url.scheme)
|
210
|
+
assert(!Net::HTTP.last_instance.use_ssl?,'Net::HTTP instance should not be set to use SSL')
|
211
|
+
assert_equal('twitter.com',client.transport.url.host)
|
212
|
+
assert_equal('/users/show.json',client.transport.url.path)
|
213
|
+
assert_equal('test_user',client.transport.options[:params][:screen_name])
|
214
|
+
assert_equal('screen_name=test_user',Net::HTTP.request.path.split(/\?/)[1])
|
215
|
+
assert_equal(54321,value.id)
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_http_method_blocks_choose_right_method
|
219
|
+
client = new_client(200,'[{"id":1,"text":"test 1"}]')
|
220
|
+
client.get { search :q=>'test' }
|
221
|
+
assert_equal(:get,client.transport.method, "Get block should choose get method")
|
222
|
+
client.delete { direct_messages.destroy :id=>1 }
|
223
|
+
assert_equal(:delete,client.transport.method, "Delete block should choose delete method")
|
224
|
+
client.post { direct_messages.destroy :id=>1 }
|
225
|
+
assert_equal(:post,client.transport.method, "Post block should choose post method")
|
226
|
+
client.put { direct_messages :id=>1 }
|
227
|
+
assert_equal(:put,client.transport.method, "Put block should choose put method")
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_http_method_selection_precedence
|
231
|
+
client = new_client(200,'[{"id":1,"text":"test 1"}]')
|
232
|
+
client.get { search! :q=>'test' }
|
233
|
+
assert_equal(:get,client.transport.method, "Get block should override method even if post bang is used")
|
234
|
+
client.delete { search? :q=>'test', :__method=>:post }
|
235
|
+
assert_equal(:post,client.transport.method, ":__method=>:post should override block setting and method suffix")
|
236
|
+
end
|
198
237
|
|
199
238
|
private
|
200
239
|
def with_http_responder(responder)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grackle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
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-
|
12
|
+
date: 2009-10-29 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|