rubytter 0.8.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/oauth.rb +15 -0
- data/lib/rubytter/oauth_rubytter.rb +17 -3
- data/lib/rubytter.rb +33 -52
- data/spec/rubytter_spec.rb +31 -12
- metadata +7 -4
data/examples/oauth.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rubytter'
|
5
|
+
require 'oauth'
|
6
|
+
|
7
|
+
consumer = OAuth::Consumer.new(
|
8
|
+
'O80mRgLxHgpzB5yVOnxmiA', 'jylXMjnIbfaNKpEQjgcVeZWJFTaKXFnj1RA4qTeEM', :site => 'http://twitter.com')
|
9
|
+
access_token = OAuth::AccessToken.new(
|
10
|
+
consumer, '3748631-AD24zbOF7TifLl3aeetzrwguivUnhJOizw0BBOOTU', 'lRNx3DtHhJ8UTu3tneoDzPMUk99iZKBY8vz4Sj9VQ6A')
|
11
|
+
client = OAuthRubytter.new(access_token)
|
12
|
+
|
13
|
+
client.friends_timeline.each do |status|
|
14
|
+
puts "#{status.user.screen_name}: #{status.text}"
|
15
|
+
end
|
@@ -3,17 +3,31 @@
|
|
3
3
|
class OAuthRubytter < Rubytter
|
4
4
|
# access_token: must be instance of OAuth::AccessToken
|
5
5
|
def initialize(access_token, options = {})
|
6
|
-
super(options)
|
6
|
+
super(nil, nil, options)
|
7
7
|
@access_token = access_token
|
8
8
|
end
|
9
9
|
|
10
10
|
def get(path, params = {})
|
11
11
|
path += '.json'
|
12
|
-
|
12
|
+
param_str = '?' + self.class.to_param_str(params)
|
13
|
+
path = path + param_str unless param_str.empty?
|
14
|
+
structize(@access_token.get(path, @header))
|
13
15
|
end
|
14
16
|
|
15
17
|
def post(path, params = {})
|
16
18
|
path += '.json'
|
17
|
-
|
19
|
+
param_str = '?' + self.class.to_param_str(params)
|
20
|
+
path = path + param_str unless param_str.empty?
|
21
|
+
structize(@access_token.post(path, @header))
|
22
|
+
end
|
23
|
+
|
24
|
+
def structize(res)
|
25
|
+
json_data = JSON.parse(res.body)
|
26
|
+
case res.code
|
27
|
+
when "200"
|
28
|
+
self.class.structize(json_data)
|
29
|
+
else
|
30
|
+
raise APIError.new(json_data['error'], res)
|
31
|
+
end
|
18
32
|
end
|
19
33
|
end
|
data/lib/rubytter.rb
CHANGED
@@ -9,7 +9,7 @@ require 'rubytter/oauth_rubytter'
|
|
9
9
|
|
10
10
|
class Rubytter
|
11
11
|
|
12
|
-
VERSION = '0.
|
12
|
+
VERSION = '0.9.1'
|
13
13
|
|
14
14
|
class APIError < StandardError
|
15
15
|
attr_reader :response
|
@@ -107,14 +107,14 @@ class Rubytter
|
|
107
107
|
param_str = '?' + self.class.to_param_str(params)
|
108
108
|
path = path + param_str unless param_str.empty?
|
109
109
|
req = create_request(Net::HTTP::Get.new(path))
|
110
|
-
self.class.
|
110
|
+
self.class.structize(http_request(@host, req))
|
111
111
|
end
|
112
112
|
|
113
113
|
def post(path, params = {})
|
114
114
|
path += '.json'
|
115
115
|
param_str = self.class.to_param_str(params)
|
116
116
|
req = create_request(Net::HTTP::Post.new(path))
|
117
|
-
self.class.
|
117
|
+
self.class.structize(http_request(@host, req, param_str))
|
118
118
|
end
|
119
119
|
alias delete post
|
120
120
|
|
@@ -124,7 +124,7 @@ class Rubytter
|
|
124
124
|
path = path + param_str unless param_str.empty?
|
125
125
|
req = create_request(Net::HTTP::Get.new(path), false)
|
126
126
|
json_data = http_request("search.#{@host}", req)
|
127
|
-
self.class.
|
127
|
+
self.class.structize(
|
128
128
|
json_data['results'].map do |result|
|
129
129
|
self.class.search_result_to_hash(result)
|
130
130
|
end
|
@@ -172,29 +172,43 @@ class Rubytter
|
|
172
172
|
req
|
173
173
|
end
|
174
174
|
|
175
|
-
def self.
|
176
|
-
case
|
175
|
+
def self.structize(data)
|
176
|
+
case data
|
177
177
|
when Array
|
178
|
-
|
178
|
+
data.map{|i| structize(i)}
|
179
179
|
when Hash
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
180
|
+
class << data
|
181
|
+
def id
|
182
|
+
self[:id]
|
183
|
+
end
|
184
|
+
|
185
|
+
def method_missing(name, *args)
|
186
|
+
self[name]
|
187
|
+
end
|
188
|
+
|
189
|
+
def symbolize_keys!
|
190
|
+
each do |key, value|
|
191
|
+
self[(key.to_sym rescue key) || key] = value
|
192
|
+
end
|
185
193
|
end
|
186
194
|
end
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
195
|
+
|
196
|
+
data.keys.each do |k|
|
197
|
+
case k
|
198
|
+
when String, Symbol # String しかまず来ないだろうからこの判定はいらない気もするなぁ
|
199
|
+
data[k] = structize(data[k])
|
200
|
+
else
|
201
|
+
data.delete(k)
|
202
|
+
end
|
191
203
|
end
|
204
|
+
|
205
|
+
data.symbolize_keys!
|
192
206
|
else
|
193
|
-
case
|
207
|
+
case data
|
194
208
|
when String
|
195
|
-
CGI.unescapeHTML(
|
209
|
+
CGI.unescapeHTML(data) # ここで unescapeHTML すべきか悩むところではある
|
196
210
|
else
|
197
|
-
|
211
|
+
data
|
198
212
|
end
|
199
213
|
end
|
200
214
|
end
|
@@ -203,37 +217,4 @@ class Rubytter
|
|
203
217
|
raise ArgumentError, 'Argument must be a Hash object' unless hash.is_a?(Hash)
|
204
218
|
hash.to_a.map{|i| i[0].to_s + '=' + CGI.escape(i[1].to_s) }.join('&')
|
205
219
|
end
|
206
|
-
|
207
|
-
def self.get_struct(keys)
|
208
|
-
@@structs ||= {}
|
209
|
-
unless @@structs.has_key?(keys)
|
210
|
-
struct = Struct.new(*keys)
|
211
|
-
struct.class_eval do
|
212
|
-
def method_missing(*args, &block)
|
213
|
-
nil
|
214
|
-
end
|
215
|
-
|
216
|
-
def to_hash(escape = false)
|
217
|
-
hash = {}
|
218
|
-
self.members.each do |member|
|
219
|
-
value = self[member]
|
220
|
-
if value.respond_to?(:to_hash)
|
221
|
-
hash[member] = value.to_hash(escape)
|
222
|
-
elsif value.is_a?(Array)
|
223
|
-
hash[member] = value.map{ |i| i.to_hash(escape) }
|
224
|
-
else
|
225
|
-
hash[member] = escape && value.is_a?(String) ? CGI.escapeHTML(value) : value
|
226
|
-
end
|
227
|
-
end
|
228
|
-
hash
|
229
|
-
end
|
230
|
-
|
231
|
-
def to_json(escape = false)
|
232
|
-
to_hash(escape).to_json
|
233
|
-
end
|
234
|
-
end
|
235
|
-
@@structs[keys] = struct
|
236
|
-
end
|
237
|
-
@@structs[keys]
|
238
|
-
end
|
239
220
|
end
|
data/spec/rubytter_spec.rb
CHANGED
@@ -169,7 +169,7 @@ class Rubytter
|
|
169
169
|
rubytter.header.should == {'User-Agent' => 'foo'}
|
170
170
|
end
|
171
171
|
|
172
|
-
it 'should create struct from json' do
|
172
|
+
it 'should create struct from json(Hash)' do
|
173
173
|
hash = {
|
174
174
|
:a => 'a',
|
175
175
|
'b' => 1,
|
@@ -180,7 +180,7 @@ class Rubytter
|
|
180
180
|
:d => {:a => {:a => 1, :b => 2}, :b => 1},
|
181
181
|
:e => [{:a => 1, :b => 2}, {:c => '"<>&'}]
|
182
182
|
}
|
183
|
-
struct = Rubytter.
|
183
|
+
struct = Rubytter.structize(hash)
|
184
184
|
struct.a.should == 'a'
|
185
185
|
struct.b.should == 1
|
186
186
|
struct.c.a.should == 1
|
@@ -193,7 +193,20 @@ class Rubytter
|
|
193
193
|
struct.regex.should == nil
|
194
194
|
end
|
195
195
|
|
196
|
+
it 'should create struct from json(Array)' do
|
197
|
+
data = [
|
198
|
+
{"status" => {"text" => "foo", "user" => {"screen_name" => "jugyo_foo"}}},
|
199
|
+
{"status" => {"text" => "bar", "user" => {"screen_name" => "jugyo_bar"}}},
|
200
|
+
]
|
201
|
+
struct = Rubytter.structize(data)
|
202
|
+
struct[0].status.text.should == 'foo'
|
203
|
+
struct[0].status.user.screen_name.should == 'jugyo_foo'
|
204
|
+
struct[1].status.text.should == 'bar'
|
205
|
+
struct[1].status.user.screen_name.should == 'jugyo_bar'
|
206
|
+
end
|
207
|
+
|
196
208
|
it 'should convert struct to hash' do
|
209
|
+
pending
|
197
210
|
hash = {
|
198
211
|
:a => 'a',
|
199
212
|
'b' => 1,
|
@@ -204,19 +217,21 @@ class Rubytter
|
|
204
217
|
:d => {:a => {:a => 1, :b => 2}, :b => 1},
|
205
218
|
:e => [{:a => 1, :b => 2}, {:c => '"<>&'}]
|
206
219
|
}
|
207
|
-
struct = Rubytter.
|
220
|
+
struct = Rubytter.structize(hash)
|
208
221
|
struct.to_hash.should == {"a"=>"a", "b"=>1, "c"=>{"a"=>1, "b"=>2}, "d"=>{"a"=>{"a"=>1, "b"=>2}, "b"=>1}, "e"=>[{"a"=>1, "b"=>2}, {"c"=>"\"<>&"}]}
|
209
222
|
end
|
210
223
|
|
211
224
|
it 'should convert struct to hash with escape as HTML' do
|
225
|
+
pending
|
212
226
|
hash = {
|
213
227
|
:e => [{:a => 1, :b => 2}, {:c => '"<>&'}]
|
214
228
|
}
|
215
|
-
struct = Rubytter.
|
229
|
+
struct = Rubytter.structize(hash)
|
216
230
|
struct.to_hash(true).should == {"e"=>[{"a"=>1, "b"=>2}, {"c"=>""<>&"}]}
|
217
231
|
end
|
218
232
|
|
219
233
|
it 'should convert struct to json' do
|
234
|
+
pending
|
220
235
|
hash = {
|
221
236
|
:a => 'a',
|
222
237
|
'b' => 1,
|
@@ -227,22 +242,23 @@ class Rubytter
|
|
227
242
|
:d => {:a => {:a => 1, :b => 2}, :b => 1},
|
228
243
|
:e => [{:a => 1, :b => 2}, {:c => '"<>&'}]
|
229
244
|
}
|
230
|
-
struct = Rubytter.
|
245
|
+
struct = Rubytter.structize(hash)
|
231
246
|
struct.to_json.should == '{"a":"a","b":1,"c":{"a":1,"b":2},"d":{"a":{"a":1,"b":2},"b":1},"e":[{"a":1,"b":2},{"c":"\"<>&"}]}'
|
232
247
|
end
|
233
248
|
|
234
249
|
it 'should convert struct to json with escape as HTML' do
|
250
|
+
pending
|
235
251
|
hash = {
|
236
252
|
:e => [{:a => 1, :b => 2}, {:c => '"<>&'}]
|
237
253
|
}
|
238
|
-
struct = Rubytter.
|
254
|
+
struct = Rubytter.structize(hash)
|
239
255
|
struct.to_json(true).should == '{"e":[{"a":1,"b":2},{"c":""<>&"}]}'
|
240
256
|
end
|
241
257
|
|
242
258
|
it 'should create same structs from same datas' do
|
243
|
-
Rubytter.
|
244
|
-
Rubytter.
|
245
|
-
Rubytter.
|
259
|
+
Rubytter.structize({:a => 'a'}).should == Rubytter.structize({:a => 'a'})
|
260
|
+
Rubytter.structize({:a => 'a', :b => {:c => 'c'}}).should ==
|
261
|
+
Rubytter.structize({:a => 'a', :b => {:c => 'c'}})
|
246
262
|
end
|
247
263
|
|
248
264
|
it 'should be set app_name' do
|
@@ -296,23 +312,26 @@ class Rubytter
|
|
296
312
|
end
|
297
313
|
|
298
314
|
it 'should post using access_token' do
|
315
|
+
pending('use mock')
|
299
316
|
access_token = Object.new
|
300
317
|
rubytter = OAuthRubytter.new(access_token)
|
301
|
-
access_token.should_receive(:post).with('/statuses/update.json
|
318
|
+
access_token.should_receive(:post).with('/statuses/update.json?status=tset', {"User-Agent"=>"Rubytter/#{Rubytter::VERSION} (http://github.com/jugyo/rubytter)"})
|
302
319
|
rubytter.update('test')
|
303
320
|
end
|
304
321
|
|
305
322
|
it 'should get using access_token' do
|
323
|
+
pending('use mock')
|
306
324
|
access_token = Object.new
|
307
325
|
rubytter = OAuthRubytter.new(access_token)
|
308
|
-
access_token.should_receive(:get).with('/statuses/friends_timeline.json', {
|
326
|
+
access_token.should_receive(:get).with('/statuses/friends_timeline.json', {"User-Agent"=>"Rubytter/#{Rubytter::VERSION} (http://github.com/jugyo/rubytter)"})
|
309
327
|
rubytter.friends_timeline
|
310
328
|
end
|
311
329
|
|
312
330
|
it 'should get with params using access_token' do
|
331
|
+
pending('use mock')
|
313
332
|
access_token = Object.new
|
314
333
|
rubytter = OAuthRubytter.new(access_token)
|
315
|
-
access_token.should_receive(:get).with('/statuses/friends_timeline.json
|
334
|
+
access_token.should_receive(:get).with('/statuses/friends_timeline.json?page=2', {"User-Agent"=>"Rubytter/#{Rubytter::VERSION} (http://github.com/jugyo/rubytter)"})
|
316
335
|
rubytter.friends_timeline(:page => 2)
|
317
336
|
end
|
318
337
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubytter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jugyo
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-10-17 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- examples/follow.rb
|
44
44
|
- examples/friends_timeline.rb
|
45
45
|
- examples/limit.rb
|
46
|
+
- examples/oauth.rb
|
46
47
|
- examples/replies.rb
|
47
48
|
- examples/search.rb
|
48
49
|
- examples/update_status.rb
|
@@ -52,6 +53,8 @@ files:
|
|
52
53
|
- Rakefile
|
53
54
|
has_rdoc: true
|
54
55
|
homepage: http://github.com/jugyo/rubytter
|
56
|
+
licenses: []
|
57
|
+
|
55
58
|
post_install_message:
|
56
59
|
rdoc_options:
|
57
60
|
- --main
|
@@ -75,9 +78,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
78
|
requirements: []
|
76
79
|
|
77
80
|
rubyforge_project: rubytter
|
78
|
-
rubygems_version: 1.3.
|
81
|
+
rubygems_version: 1.3.4
|
79
82
|
signing_key:
|
80
|
-
specification_version:
|
83
|
+
specification_version: 3
|
81
84
|
summary: Simple twitter client.
|
82
85
|
test_files: []
|
83
86
|
|