rubytter 0.11.0 → 1.0.0
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 +18 -46
- data/VERSION +1 -1
- data/examples/use_oauth.rb +28 -0
- data/lib/rubytter/core_ext.rb +26 -0
- data/lib/rubytter/oauth_rubytter.rb +6 -16
- data/lib/rubytter.rb +15 -31
- data/spec/rubytter_spec.rb +14 -15
- metadata +5 -4
- data/examples/home_timeline.rb +0 -14
data/README.rdoc
CHANGED
@@ -13,66 +13,38 @@ Rubytter is simple twitter library.
|
|
13
13
|
=== implemented API methods:
|
14
14
|
|
15
15
|
- /statuses/update
|
16
|
-
- /statuses/destroy
|
16
|
+
- /statuses/destroy/id
|
17
17
|
- /statuses/public_timeline
|
18
|
-
- /statuses/home_timeline
|
19
18
|
- /statuses/friends_timeline
|
20
19
|
- /statuses/replies
|
21
|
-
- /statuses/
|
22
|
-
- /statuses/
|
23
|
-
- /statuses/
|
24
|
-
- /statuses/
|
25
|
-
- /
|
26
|
-
- /statuses/retweet/%s
|
27
|
-
- /statuses/retweets/%s
|
28
|
-
- /statuses/retweeted_by_me
|
29
|
-
- /statuses/retweeted_to_me
|
30
|
-
- /statuses/retweets_of_me
|
31
|
-
- /users/show/%s
|
20
|
+
- /statuses/user_timeline/id
|
21
|
+
- /statuses/show/id
|
22
|
+
- /statuses/friends/id
|
23
|
+
- /statuses/followers/id
|
24
|
+
- /users/show/id
|
32
25
|
- /direct_messages
|
33
26
|
- /direct_messages/sent
|
34
27
|
- /direct_messages/new
|
35
|
-
- /direct_messages/destroy
|
36
|
-
- /friendships/create
|
37
|
-
- /friendships/destroy
|
28
|
+
- /direct_messages/destroy/id
|
29
|
+
- /friendships/create/id
|
30
|
+
- /friendships/destroy/id
|
38
31
|
- /friendships/exists
|
39
|
-
- /followers/ids
|
40
|
-
- /friends/ids
|
41
|
-
- /favorites
|
42
|
-
- /favorites/create
|
43
|
-
- /favorites/destroy
|
32
|
+
- /followers/ids/id
|
33
|
+
- /friends/ids/id
|
34
|
+
- /favorites
|
35
|
+
- /favorites/create/id
|
36
|
+
- /favorites/destroy/id
|
44
37
|
- /account/verify_credentials
|
45
38
|
- /account/end_session
|
46
39
|
- /account/update_delivery_device
|
47
40
|
- /account/update_profile_colors
|
48
41
|
- /account/rate_limit_status
|
49
42
|
- /account/update_profile
|
50
|
-
- /notifications/follow
|
51
|
-
- /notifications/leave
|
52
|
-
- /blocks/create
|
53
|
-
- /blocks/destroy
|
54
|
-
- /blocks/exists/%s
|
55
|
-
- /blocks/blocking
|
56
|
-
- /blocks/blocking/ids
|
57
|
-
- /saved_searches
|
58
|
-
- /saved_searches/show/%s
|
59
|
-
- /saved_searches/create
|
60
|
-
- /saved_searches/destroy/%s
|
61
|
-
- /:user/lists (create)
|
62
|
-
- /:user/lists/%s (update)
|
63
|
-
- /:user/lists/%s (delete)
|
64
|
-
- /:user/lists
|
65
|
-
- /:user/lists/memberships
|
66
|
-
- /:user/lists/%s/statuses
|
67
|
-
- /:user/lists/%s
|
68
|
-
- /%s/%s/members
|
69
|
-
- /:user/%s/members
|
70
|
-
- /:user/%s/members
|
71
|
-
- /%s/%s/subscribers
|
72
|
-
- /%s/%s/subscribers
|
73
|
-
- /%s/%s/subscribers
|
43
|
+
- /notifications/follow/id
|
44
|
+
- /notifications/leave/id
|
45
|
+
- /blocks/create/id
|
46
|
+
- /blocks/destroy/id
|
74
47
|
- (search.twitter.com)/search
|
75
|
-
- (api.twitter.com)/1/users/search
|
76
48
|
|
77
49
|
== SYNOPSIS:
|
78
50
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
@@ -0,0 +1,28 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '../lib')
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubytter'
|
4
|
+
require 'oauth'
|
5
|
+
|
6
|
+
key = "httN2PgAfeEuOywgw4m2g"
|
7
|
+
secret = "qunvnx27QC98380PUHQ0YUhSoMFMA2HJQZisWKDOgI"
|
8
|
+
|
9
|
+
consumer = OAuth::Consumer.new(key, secret, :site => "http://twitter.com")
|
10
|
+
|
11
|
+
request_token = consumer.get_request_token
|
12
|
+
system('open', request_token.authorize_url) || puts("Access here: #{request_token.authorize_url}\nand...")
|
13
|
+
|
14
|
+
print "Enter PIN: "
|
15
|
+
pin = gets.strip
|
16
|
+
|
17
|
+
access_token = request_token.get_access_token(
|
18
|
+
:oauth_token => request_token.token,
|
19
|
+
:oauth_verifier => pin
|
20
|
+
)
|
21
|
+
|
22
|
+
client = OAuthRubytter.new(access_token)
|
23
|
+
client.friends_timeline.each do |status|
|
24
|
+
puts "#{status.user.screen_name}: #{status.text}"
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'irby'
|
28
|
+
client.irb
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Hash
|
2
|
+
def stringify_keys
|
3
|
+
inject({}) do |options, (key, value)|
|
4
|
+
options[key.to_s] = value
|
5
|
+
options
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def stringify_keys!
|
10
|
+
keys.each do |key|
|
11
|
+
self[key.to_s] = delete(key)
|
12
|
+
end
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def symbolize_keys
|
17
|
+
inject({}) do |options, (key, value)|
|
18
|
+
options[(key.to_sym rescue key) || key] = value
|
19
|
+
options
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def symbolize_keys!
|
24
|
+
self.replace(self.symbolize_keys)
|
25
|
+
end
|
26
|
+
end
|
@@ -9,33 +9,23 @@ class OAuthRubytter < Rubytter
|
|
9
9
|
|
10
10
|
def get(path, params = {})
|
11
11
|
path += '.json'
|
12
|
-
param_str =
|
12
|
+
param_str = to_param_str(params)
|
13
13
|
path = path + '?' + param_str unless param_str.empty?
|
14
|
-
|
14
|
+
parse_response(@access_token.get(path, @header))
|
15
15
|
end
|
16
16
|
|
17
17
|
def post(path, params = {})
|
18
18
|
path += '.json'
|
19
|
-
|
19
|
+
parse_response(@access_token.post(path, params.stringify_keys, @header))
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
path += '.json'
|
24
|
-
structize(@access_token.put(path, params, @header))
|
25
|
-
end
|
26
|
-
|
27
|
-
def delete(path, params = {})
|
28
|
-
path += '.json'
|
29
|
-
param_str = self.class.to_param_str(params)
|
30
|
-
path = path + '?' + param_str unless param_str.empty?
|
31
|
-
structize(@access_token.delete(path, @header))
|
32
|
-
end
|
22
|
+
private
|
33
23
|
|
34
|
-
def
|
24
|
+
def parse_response(res)
|
35
25
|
json_data = JSON.parse(res.body)
|
36
26
|
case res.code
|
37
27
|
when "200"
|
38
|
-
|
28
|
+
structize(json_data)
|
39
29
|
else
|
40
30
|
raise APIError.new(json_data['error'], res)
|
41
31
|
end
|
data/lib/rubytter.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
# -*- coding: utf-8 -*-
|
3
2
|
require 'rubygems'
|
4
3
|
require 'json'
|
@@ -7,6 +6,7 @@ require 'cgi'
|
|
7
6
|
|
8
7
|
require 'rubytter/connection'
|
9
8
|
require 'rubytter/oauth_rubytter'
|
9
|
+
require 'rubytter/core_ext'
|
10
10
|
|
11
11
|
class Rubytter
|
12
12
|
VERSION = File.read(File.join(File.dirname(__FILE__), '../VERSION')).strip
|
@@ -39,7 +39,6 @@ class Rubytter
|
|
39
39
|
update_status /statuses/update post
|
40
40
|
remove_status /statuses/destroy/%s delete
|
41
41
|
public_timeline /statuses/public_timeline
|
42
|
-
home_timeline /statuses/home_timeline
|
43
42
|
friends_timeline /statuses/friends_timeline
|
44
43
|
replies /statuses/replies
|
45
44
|
mentions /statuses/mentions
|
@@ -47,11 +46,6 @@ class Rubytter
|
|
47
46
|
show /statuses/show/%s
|
48
47
|
friends /statuses/friends/%s
|
49
48
|
followers /statuses/followers/%s
|
50
|
-
retweet /statuses/retweet/%s post
|
51
|
-
retweets /statuses/retweets/%s
|
52
|
-
retweeted_by_me /statuses/retweeted_by_me
|
53
|
-
retweeted_to_me /statuses/retweeted_to_me
|
54
|
-
retweets_of_me /statuses/retweets_of_me
|
55
49
|
user /users/show/%s
|
56
50
|
direct_messages /direct_messages
|
57
51
|
sent_direct_messages /direct_messages/sent
|
@@ -62,7 +56,7 @@ class Rubytter
|
|
62
56
|
friendship_exists /friendships/exists
|
63
57
|
followers_ids /followers/ids/%s
|
64
58
|
friends_ids /friends/ids/%s
|
65
|
-
favorites /favorites
|
59
|
+
favorites /favorites
|
66
60
|
favorite /favorites/create/%s post
|
67
61
|
remove_favorite /favorites/destroy/%s delete
|
68
62
|
verify_credentials /account/verify_credentials get
|
@@ -106,9 +100,7 @@ class Rubytter
|
|
106
100
|
def #{method}(*args)
|
107
101
|
path = login ? '#{path}'.gsub(':user', login) :'#{path}'
|
108
102
|
params = args.last.kind_of?(Hash) ? args.pop : {}
|
109
|
-
path
|
110
|
-
path.sub!(/\\/\\z/, '')
|
111
|
-
#{http_method}(path, params)
|
103
|
+
#{http_method}(path % args, params)
|
112
104
|
end
|
113
105
|
EOS
|
114
106
|
else
|
@@ -158,49 +150,41 @@ class Rubytter
|
|
158
150
|
|
159
151
|
def get(path, params = {})
|
160
152
|
path += '.json'
|
161
|
-
param_str = '?' +
|
153
|
+
param_str = '?' + to_param_str(params)
|
162
154
|
path = path + param_str unless param_str.empty?
|
163
155
|
req = create_request(Net::HTTP::Get.new(path))
|
164
|
-
|
156
|
+
structize(http_request(@host, req))
|
165
157
|
end
|
166
158
|
|
167
159
|
def post(path, params = {})
|
168
160
|
path += '.json'
|
169
|
-
param_str =
|
161
|
+
param_str = to_param_str(params)
|
170
162
|
req = create_request(Net::HTTP::Post.new(path))
|
171
|
-
|
163
|
+
structize(http_request(@host, req, param_str))
|
172
164
|
end
|
173
165
|
|
174
166
|
def delete(path, params = {})
|
175
167
|
path += '.json'
|
176
|
-
param_str =
|
168
|
+
param_str = to_param_str(params)
|
177
169
|
req = create_request(Net::HTTP::Delete.new(path))
|
178
|
-
|
170
|
+
structize(http_request(@host, req, param_str))
|
179
171
|
end
|
180
172
|
|
181
173
|
def search(query, params = {})
|
182
174
|
path = '/search.json'
|
183
|
-
param_str = '?' +
|
175
|
+
param_str = '?' + to_param_str(params.merge({:q => query}))
|
184
176
|
path = path + param_str unless param_str.empty?
|
185
177
|
req = create_request(Net::HTTP::Get.new(path), false)
|
186
178
|
|
187
179
|
json_data = http_request("search.#{@host}", req, nil, @connection_for_search)
|
188
|
-
|
180
|
+
structize(
|
189
181
|
json_data['results'].map do |result|
|
190
|
-
|
182
|
+
search_result_to_hash(result)
|
191
183
|
end
|
192
184
|
)
|
193
185
|
end
|
194
186
|
|
195
|
-
def
|
196
|
-
path = '/1/users/search.json'
|
197
|
-
param_str = '?' + self.class.to_param_str(params.merge({:q => query}))
|
198
|
-
path = path + param_str unless param_str.empty?
|
199
|
-
req = create_request(Net::HTTP::Get.new(path))
|
200
|
-
self.class.structize(http_request("api.#{@host}", req))
|
201
|
-
end
|
202
|
-
|
203
|
-
def self.search_result_to_hash(json)
|
187
|
+
def search_result_to_hash(json)
|
204
188
|
{
|
205
189
|
'id' => json['id'],
|
206
190
|
'text' => json['text'],
|
@@ -242,7 +226,7 @@ class Rubytter
|
|
242
226
|
req
|
243
227
|
end
|
244
228
|
|
245
|
-
def
|
229
|
+
def structize(data)
|
246
230
|
case data
|
247
231
|
when Array
|
248
232
|
data.map{|i| structize(i)}
|
@@ -283,7 +267,7 @@ class Rubytter
|
|
283
267
|
end
|
284
268
|
end
|
285
269
|
|
286
|
-
def
|
270
|
+
def to_param_str(hash)
|
287
271
|
raise ArgumentError, 'Argument must be a Hash object' unless hash.is_a?(Hash)
|
288
272
|
hash.to_a.map{|i| i[0].to_s + '=' + CGI.escape(i[1].to_s) }.join('&')
|
289
273
|
end
|
data/spec/rubytter_spec.rb
CHANGED
@@ -129,16 +129,16 @@ class Rubytter
|
|
129
129
|
end
|
130
130
|
|
131
131
|
it 'should respond to to_param_str' do
|
132
|
-
param_str =
|
132
|
+
param_str = @rubytter.to_param_str(:page => 2, :foo => 'bar')
|
133
133
|
param_str.should =~ /^.+?=.+?&.+?=.+?$/
|
134
134
|
param_str.should =~ /page=2/
|
135
135
|
param_str.should =~ /foo=bar/
|
136
136
|
end
|
137
137
|
|
138
138
|
it 'should raise when call to_param_str with invalid arg' do
|
139
|
-
lambda {
|
140
|
-
lambda {
|
141
|
-
lambda {
|
139
|
+
lambda { @rubytter.to_param_str(nil) }.should raise_error(ArgumentError)
|
140
|
+
lambda { @rubytter.to_param_str('foo') }.should raise_error(ArgumentError)
|
141
|
+
lambda { @rubytter.to_param_str(:bar) }.should raise_error(ArgumentError)
|
142
142
|
end
|
143
143
|
|
144
144
|
it 'should set default header' do
|
@@ -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 =
|
183
|
+
struct = @rubytter.structize(hash)
|
184
184
|
struct.a.should == 'a'
|
185
185
|
struct.b.should == 1
|
186
186
|
struct.c.a.should == 1
|
@@ -198,7 +198,7 @@ class Rubytter
|
|
198
198
|
{"status" => {"text" => "foo", "user" => {"screen_name" => "jugyo_foo"}}},
|
199
199
|
{"status" => {"text" => "bar", "user" => {"screen_name" => "jugyo_bar"}}},
|
200
200
|
]
|
201
|
-
struct =
|
201
|
+
struct = @rubytter.structize(data)
|
202
202
|
struct[0].status.text.should == 'foo'
|
203
203
|
struct[0].status.user.screen_name.should == 'jugyo_foo'
|
204
204
|
struct[1].status.text.should == 'bar'
|
@@ -216,7 +216,7 @@ class Rubytter
|
|
216
216
|
:d => {:a => {:a => 1, :b => 2}, :b => 1},
|
217
217
|
:e => [{:a => 1, :b => 2}, {:c => '"<>&'}]
|
218
218
|
}
|
219
|
-
struct =
|
219
|
+
struct = @rubytter.structize(hash)
|
220
220
|
struct.to_hash.should == {
|
221
221
|
:a => "a",
|
222
222
|
"b" => 1,
|
@@ -232,7 +232,7 @@ class Rubytter
|
|
232
232
|
hash = {
|
233
233
|
:e => [{:a => 1, :b => 2}, {:c => '"<>&'}]
|
234
234
|
}
|
235
|
-
struct =
|
235
|
+
struct = @rubytter.structize(hash)
|
236
236
|
struct.to_hash(true).should == {"e"=>[{"a"=>1, "b"=>2}, {"c"=>""<>&"}]}
|
237
237
|
end
|
238
238
|
|
@@ -248,7 +248,7 @@ class Rubytter
|
|
248
248
|
:d => {:a => {:a => 1, :b => 2}, :b => 1},
|
249
249
|
:e => [{:a => 1, :b => 2}, {:c => '"<>&'}]
|
250
250
|
}
|
251
|
-
struct =
|
251
|
+
struct = @rubytter.structize(hash)
|
252
252
|
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":"\"<>&"}]}'
|
253
253
|
end
|
254
254
|
|
@@ -262,9 +262,9 @@ class Rubytter
|
|
262
262
|
end
|
263
263
|
|
264
264
|
it 'should create same structs from same datas' do
|
265
|
-
|
266
|
-
|
267
|
-
|
265
|
+
@rubytter.structize({:a => 'a'}).should == @rubytter.structize({:a => 'a'})
|
266
|
+
@rubytter.structize({:a => 'a', :b => {:c => 'c'}}).should ==
|
267
|
+
@rubytter.structize({:a => 'a', :b => {:c => 'c'}})
|
268
268
|
end
|
269
269
|
|
270
270
|
it 'should be set app_name' do
|
@@ -285,8 +285,7 @@ class Rubytter
|
|
285
285
|
'from_user' => 'jugyo',
|
286
286
|
'profile_image_url' => 'http://s3.amazonaws.com/twitter_production/profile_images/63467667/megane2_normal.png'
|
287
287
|
}
|
288
|
-
|
289
|
-
result = Rubytter.search_result_to_hash(json_data)
|
288
|
+
result = @rubytter.search_result_to_hash(json_data)
|
290
289
|
result['id'].should == '123'
|
291
290
|
result['text'].should == 'foo foo bar bar'
|
292
291
|
result['created_at'].should == 'Sat, 21 Mar 2009 09:48:20 +0000'
|
@@ -355,7 +354,7 @@ class Rubytter
|
|
355
354
|
response = simple_mock(:body => '{}', :code => '200')
|
356
355
|
access_token.should_receive(:post).with(
|
357
356
|
"/statuses/update.json",
|
358
|
-
{
|
357
|
+
{'status' => 'test'},
|
359
358
|
{"User-Agent"=>"Rubytter/#{Rubytter::VERSION} (http://github.com/jugyo/rubytter)"}
|
360
359
|
).and_return(response)
|
361
360
|
rubytter.update('test')
|
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: 1.0.0
|
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:
|
12
|
+
date: 2010-01-31 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -49,15 +49,16 @@ files:
|
|
49
49
|
- examples/favorite.rb
|
50
50
|
- examples/follow.rb
|
51
51
|
- examples/friends_timeline.rb
|
52
|
-
- examples/home_timeline.rb
|
53
52
|
- examples/limit.rb
|
54
53
|
- examples/lists.rb
|
55
54
|
- examples/replies.rb
|
56
55
|
- examples/search.rb
|
57
56
|
- examples/update_status.rb
|
57
|
+
- examples/use_oauth.rb
|
58
58
|
- examples/user.rb
|
59
59
|
- lib/rubytter.rb
|
60
60
|
- lib/rubytter/connection.rb
|
61
|
+
- lib/rubytter/core_ext.rb
|
61
62
|
- lib/rubytter/oauth_rubytter.rb
|
62
63
|
- spec/rubytter_spec.rb
|
63
64
|
- spec/search.json
|
@@ -97,10 +98,10 @@ test_files:
|
|
97
98
|
- examples/favorite.rb
|
98
99
|
- examples/follow.rb
|
99
100
|
- examples/friends_timeline.rb
|
100
|
-
- examples/home_timeline.rb
|
101
101
|
- examples/limit.rb
|
102
102
|
- examples/lists.rb
|
103
103
|
- examples/replies.rb
|
104
104
|
- examples/search.rb
|
105
105
|
- examples/update_status.rb
|
106
|
+
- examples/use_oauth.rb
|
106
107
|
- examples/user.rb
|
data/examples/home_timeline.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# -*- coding: utf-8 -*-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'rubytter'
|
5
|
-
|
6
|
-
if ARGV.size < 2
|
7
|
-
puts "Usage: ruby #{File.basename(__FILE__)} user_id password"
|
8
|
-
exit
|
9
|
-
end
|
10
|
-
|
11
|
-
client = Rubytter.new(ARGV[0], ARGV[1])
|
12
|
-
client.home_timeline.each do |status|
|
13
|
-
puts "#{status.user.screen_name}: #{status.text}"
|
14
|
-
end
|