rubytter 1.3.2 → 1.4.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.
Files changed (4) hide show
  1. data/VERSION +1 -1
  2. data/lib/rubytter.rb +80 -74
  3. data/spec/rubytter_spec.rb +40 -29
  4. metadata +16 -5
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.2
1
+ 1.4.0
data/lib/rubytter.rb CHANGED
@@ -13,9 +13,6 @@ require 'rubytter/oauth_rubytter'
13
13
  class Rubytter
14
14
  VERSION = File.read(File.join(File.dirname(__FILE__), '../VERSION')).strip
15
15
 
16
- HOST = 'api.twitter.com'
17
- SEARCH_HOST = 'search.twitter.com'
18
-
19
16
  class APIError < StandardError
20
17
  attr_reader :response
21
18
  def initialize(msg, response = nil)
@@ -25,7 +22,7 @@ class Rubytter
25
22
  end
26
23
 
27
24
  attr_reader :login
28
- attr_accessor :header
25
+ attr_accessor :host, :header, :path_prefix
29
26
 
30
27
  def initialize(login = nil, password = nil, options = {})
31
28
  @login = login
@@ -34,75 +31,77 @@ class Rubytter
34
31
  end
35
32
 
36
33
  def setup(options)
34
+ @host = options[:host] || 'api.twitter.com'
37
35
  @header = {'User-Agent' => "Rubytter/#{VERSION} (http://github.com/jugyo/rubytter)"}
38
36
  @header.merge!(options[:header]) if options[:header]
39
37
  @app_name = options[:app_name]
40
38
  @connection = Connection.new(options)
41
39
  @connection_for_search = Connection.new(options.merge({:enable_ssl => false}))
40
+ @path_prefix = options[:path_prefix] || '/1'
42
41
  end
43
42
 
44
43
  def self.api_settings
45
44
  # method name path for API http method
46
45
  "
47
- update_status /1/statuses/update post
48
- remove_status /1/statuses/destroy/%s delete
49
- public_timeline /1/statuses/public_timeline
50
- home_timeline /1/statuses/home_timeline
51
- friends_timeline /1/statuses/friends_timeline
52
- replies /1/statuses/replies
53
- mentions /1/statuses/mentions
54
- user_timeline /1/statuses/user_timeline/%s
55
- show /1/statuses/show/%s
56
- friends /1/statuses/friends/%s
57
- followers /1/statuses/followers/%s
58
- retweet /1/statuses/retweet/%s post
59
- retweets /1/statuses/retweets/%s
60
- retweeted_by_me /1/statuses/retweeted_by_me
61
- retweeted_to_me /1/statuses/retweeted_to_me
62
- retweets_of_me /1/statuses/retweets_of_me
63
- user /1/users/show/%s
64
- direct_messages /1/direct_messages
65
- sent_direct_messages /1/direct_messages/sent
66
- send_direct_message /1/direct_messages/new post
67
- remove_direct_message /1/direct_messages/destroy/%s delete
68
- follow /1/friendships/create/%s post
69
- leave /1/friendships/destroy/%s delete
70
- friendship_exists /1/friendships/exists
71
- followers_ids /1/followers/ids/%s
72
- friends_ids /1/friends/ids/%s
73
- favorites /1/favorites/%s
74
- favorite /1/favorites/create/%s post
75
- remove_favorite /1/favorites/destroy/%s delete
76
- verify_credentials /1/account/verify_credentials get
77
- end_session /1/account/end_session post
78
- update_delivery_device /1/account/update_delivery_device post
79
- update_profile_colors /1/account/update_profile_colors post
80
- limit_status /1/account/rate_limit_status
81
- update_profile /1/account/update_profile post
82
- enable_notification /1/notifications/follow/%s post
83
- disable_notification /1/notifications/leave/%s post
84
- block /1/blocks/create/%s post
85
- unblock /1/blocks/destroy/%s delete
86
- block_exists /1/blocks/exists/%s get
87
- blocking /1/blocks/blocking get
88
- blocking_ids /1/blocks/blocking/ids get
89
- saved_searches /1/saved_searches get
90
- saved_search /1/saved_searches/show/%s get
91
- create_saved_search /1/saved_searches/create post
92
- remove_saved_search /1/saved_searches/destroy/%s delete
93
- create_list /1/:user/lists post
94
- update_list /1/:user/lists/%s put
95
- delete_list /1/:user/lists/%s delete
96
- lists /1/%s/lists
97
- lists_followers /1/%s/lists/memberships
98
- list_statuses /1/%s/lists/%s/statuses
99
- list /1/%s/lists/%s
100
- list_members /1/%s/%s/members
101
- add_member_to_list /1/:user/%s/members post
102
- remove_member_from_list /1/:user/%s/members delete
103
- list_following /1/%s/%s/subscribers
104
- follow_list /1/%s/%s/subscribers post
105
- remove_list /1/%s/%s/subscribers delete
46
+ update_status /statuses/update post
47
+ remove_status /statuses/destroy/%s delete
48
+ public_timeline /statuses/public_timeline
49
+ home_timeline /statuses/home_timeline
50
+ friends_timeline /statuses/friends_timeline
51
+ replies /statuses/replies
52
+ mentions /statuses/mentions
53
+ user_timeline /statuses/user_timeline/%s
54
+ show /statuses/show/%s
55
+ friends /statuses/friends/%s
56
+ followers /statuses/followers/%s
57
+ retweet /statuses/retweet/%s post
58
+ retweets /statuses/retweets/%s
59
+ retweeted_by_me /statuses/retweeted_by_me
60
+ retweeted_to_me /statuses/retweeted_to_me
61
+ retweets_of_me /statuses/retweets_of_me
62
+ user /users/show/%s
63
+ direct_messages /direct_messages
64
+ sent_direct_messages /direct_messages/sent
65
+ send_direct_message /direct_messages/new post
66
+ remove_direct_message /direct_messages/destroy/%s delete
67
+ follow /friendships/create/%s post
68
+ leave /friendships/destroy/%s delete
69
+ friendship_exists /friendships/exists
70
+ followers_ids /followers/ids/%s
71
+ friends_ids /friends/ids/%s
72
+ favorites /favorites/%s
73
+ favorite /favorites/create/%s post
74
+ remove_favorite /favorites/destroy/%s delete
75
+ verify_credentials /account/verify_credentials get
76
+ end_session /account/end_session post
77
+ update_delivery_device /account/update_delivery_device post
78
+ update_profile_colors /account/update_profile_colors post
79
+ limit_status /account/rate_limit_status
80
+ update_profile /account/update_profile post
81
+ enable_notification /notifications/follow/%s post
82
+ disable_notification /notifications/leave/%s post
83
+ block /blocks/create/%s post
84
+ unblock /blocks/destroy/%s delete
85
+ block_exists /blocks/exists/%s get
86
+ blocking /blocks/blocking get
87
+ blocking_ids /blocks/blocking/ids get
88
+ saved_searches /saved_searches get
89
+ saved_search /saved_searches/show/%s get
90
+ create_saved_search /saved_searches/create post
91
+ remove_saved_search /saved_searches/destroy/%s delete
92
+ create_list /:user/lists post
93
+ update_list /:user/lists/%s put
94
+ delete_list /:user/lists/%s delete
95
+ lists /%s/lists
96
+ lists_followers /%s/lists/memberships
97
+ list_statuses /%s/lists/%s/statuses
98
+ list /%s/lists/%s
99
+ list_members /%s/%s/members
100
+ add_member_to_list /:user/%s/members post
101
+ remove_member_from_list /:user/%s/members delete
102
+ list_following /%s/%s/subscribers
103
+ follow_list /%s/%s/subscribers post
104
+ remove_list /%s/%s/subscribers delete
106
105
  ".strip.split("\n").map{|line| line.strip.split(/\s+/)}
107
106
  end
108
107
 
@@ -168,31 +167,31 @@ class Rubytter
168
167
  path += '.json'
169
168
  param_str = '?' + to_param_str(params)
170
169
  path = path + param_str unless param_str.empty?
171
- req = create_request(Net::HTTP::Get.new(path))
172
- structize(http_request(HOST, req))
170
+ req = create_request(Net::HTTP::Get.new(path_prefix + path))
171
+ structize(http_request(@host, req))
173
172
  end
174
173
 
175
174
  def post(path, params = {})
176
175
  path += '.json'
177
176
  param_str = to_param_str(params)
178
- req = create_request(Net::HTTP::Post.new(path))
179
- structize(http_request(HOST, req, param_str))
177
+ req = create_request(Net::HTTP::Post.new(path_prefix + path))
178
+ structize(http_request(@host, req, param_str))
180
179
  end
181
180
 
182
181
  def delete(path, params = {})
183
182
  path += '.json'
184
183
  param_str = to_param_str(params)
185
- req = create_request(Net::HTTP::Delete.new(path))
186
- structize(http_request(HOST, req, param_str))
184
+ req = create_request(Net::HTTP::Delete.new(path_prefix + path))
185
+ structize(http_request(@host, req, param_str))
187
186
  end
188
187
 
189
188
  def search(query, params = {})
190
189
  path = '/search.json'
191
190
  param_str = '?' + to_param_str(params.merge({:q => query}))
192
191
  path = path + param_str unless param_str.empty?
193
- req = create_request(Net::HTTP::Get.new(path), false)
192
+ req = create_request(Net::HTTP::Get.new(path_prefix + path), false)
194
193
 
195
- json_data = http_request(SEARCH_HOST, req, nil, @connection_for_search)
194
+ json_data = http_request("#{@host}", req, nil, @connection_for_search)
196
195
  structize(
197
196
  json_data['results'].map do |result|
198
197
  search_result_to_hash(result)
@@ -201,11 +200,11 @@ class Rubytter
201
200
  end
202
201
 
203
202
  def search_user(query, params = {})
204
- path = '/1/users/search.json'
203
+ path = '/users/search.json'
205
204
  param_str = '?' + to_param_str(params.merge({:q => query}))
206
205
  path = path + param_str unless param_str.empty?
207
- req = create_request(Net::HTTP::Get.new(path))
208
- structize(http_request(HOST, req))
206
+ req = create_request(Net::HTTP::Get.new(path_prefix + path))
207
+ structize(http_request(@host, req))
209
208
  end
210
209
 
211
210
  def search_result_to_hash(json)
@@ -260,6 +259,13 @@ class Rubytter
260
259
  self[:id]
261
260
  end
262
261
 
262
+ def to_hash(obj = self)
263
+ obj.inject({}) {|memo, (key, value)|
264
+ memo[key] = (value.kind_of? obj.class) ? to_hash(value) : value
265
+ memo
266
+ }
267
+ end
268
+
263
269
  def method_missing(name, *args)
264
270
  self[name]
265
271
  end
@@ -20,87 +20,87 @@ class Rubytter
20
20
 
21
21
  it 'should get or post' do
22
22
  # TODO: split specs
23
- @rubytter.should_receive(:get).with('/1/statuses/replies', {})
23
+ @rubytter.should_receive(:get).with('/statuses/replies', {})
24
24
  @rubytter.replies
25
25
 
26
- @rubytter.should_receive(:get).with('/1/statuses/replies', {:page => 2})
26
+ @rubytter.should_receive(:get).with('/statuses/replies', {:page => 2})
27
27
  @rubytter.replies(:page => 2)
28
28
 
29
- @rubytter.should_receive(:get).with('/1/statuses/user_timeline/1', {})
29
+ @rubytter.should_receive(:get).with('/statuses/user_timeline/1', {})
30
30
  @rubytter.user_timeline(1)
31
31
 
32
- @rubytter.should_receive(:get).with('/1/users/show/1', {})
32
+ @rubytter.should_receive(:get).with('/users/show/1', {})
33
33
  @rubytter.user(1)
34
34
 
35
- @rubytter.should_receive(:delete).with('/1/statuses/destroy/1', {})
35
+ @rubytter.should_receive(:delete).with('/statuses/destroy/1', {})
36
36
  @rubytter.remove_status(1)
37
37
  end
38
38
 
39
39
  # direct_messages
40
40
 
41
41
  it 'should respond to direct_messages' do
42
- @rubytter.should_receive(:get).with('/1/direct_messages', {})
42
+ @rubytter.should_receive(:get).with('/direct_messages', {})
43
43
  @rubytter.direct_messages()
44
44
  end
45
45
 
46
46
  it 'should respond to sent_direct_messages' do
47
- @rubytter.should_receive(:get).with('/1/direct_messages/sent', {})
47
+ @rubytter.should_receive(:get).with('/direct_messages/sent', {})
48
48
  @rubytter.sent_direct_messages()
49
49
  end
50
50
 
51
51
  it 'should respond to send_direct_message' do
52
- @rubytter.should_receive(:post).with('/1/direct_messages/new', {})
52
+ @rubytter.should_receive(:post).with('/direct_messages/new', {})
53
53
  @rubytter.send_direct_message()
54
54
  end
55
55
 
56
56
  it 'should respond to destroy_direct_message' do
57
- @rubytter.should_receive(:delete).with('/1/direct_messages/destroy/1', {})
57
+ @rubytter.should_receive(:delete).with('/direct_messages/destroy/1', {})
58
58
  @rubytter.remove_direct_message(1)
59
59
  end
60
60
 
61
61
  it 'should respond to direct_message' do
62
- @rubytter.should_receive(:post).with('/1/direct_messages/new', {:user => 'test', :text => 'aaaaaaaaaaaaa'})
62
+ @rubytter.should_receive(:post).with('/direct_messages/new', {:user => 'test', :text => 'aaaaaaaaaaaaa'})
63
63
  @rubytter.direct_message('test', 'aaaaaaaaaaaaa')
64
64
  end
65
65
 
66
66
  # statuses
67
67
 
68
68
  it 'should respond to update' do
69
- @rubytter.should_receive(:post).with('/1/statuses/update', {:status => 'test'})
69
+ @rubytter.should_receive(:post).with('/statuses/update', {:status => 'test'})
70
70
  @rubytter.update('test')
71
71
  end
72
72
 
73
73
  it 'should respond to update_status' do
74
- @rubytter.should_receive(:post).with('/1/statuses/update', {:status => 'test'})
74
+ @rubytter.should_receive(:post).with('/statuses/update', {:status => 'test'})
75
75
  @rubytter.update_status(:status => 'test')
76
76
  end
77
77
 
78
78
  # friendship
79
79
 
80
80
  it 'should respond to follow' do
81
- @rubytter.should_receive(:post).with('/1/friendships/create/test', {})
81
+ @rubytter.should_receive(:post).with('/friendships/create/test', {})
82
82
  @rubytter.follow('test')
83
83
  end
84
84
 
85
85
  it 'should respond to leave' do
86
- @rubytter.should_receive(:delete).with('/1/friendships/destroy/test', {})
86
+ @rubytter.should_receive(:delete).with('/friendships/destroy/test', {})
87
87
  @rubytter.leave('test')
88
88
  end
89
89
 
90
90
  it 'should respond to friendship_exists' do
91
- @rubytter.should_receive(:get).with('/1/friendships/exists', {:user_a => 'a', :user_b => 'b'})
91
+ @rubytter.should_receive(:get).with('/friendships/exists', {:user_a => 'a', :user_b => 'b'})
92
92
  @rubytter.friendship_exists(:user_a => 'a', :user_b => 'b')
93
93
  end
94
94
 
95
95
  # Social Graph Methods
96
96
 
97
97
  it 'should respond to followers_ids' do
98
- @rubytter.should_receive(:get).with('/1/friends/ids/test', {})
98
+ @rubytter.should_receive(:get).with('/friends/ids/test', {})
99
99
  @rubytter.friends_ids('test')
100
100
  end
101
101
 
102
102
  it 'should respond to followers_ids' do
103
- @rubytter.should_receive(:get).with('/1/followers/ids/test', {})
103
+ @rubytter.should_receive(:get).with('/followers/ids/test', {})
104
104
  @rubytter.followers_ids('test')
105
105
  end
106
106
 
@@ -111,8 +111,8 @@ class Rubytter
111
111
 
112
112
  it 'should respond to search (1)' do
113
113
  @rubytter.should_receive(:http_request) do |host, req, param_str|
114
- req.path.should == '/search.json?q=test'
115
- host.should == 'search.twitter.com'
114
+ req.path.should == '/1/search.json?q=test'
115
+ host.should == 'api.twitter.com'
116
116
  {'results' => []}
117
117
  end
118
118
  @rubytter.search('test')
@@ -193,6 +193,17 @@ class Rubytter
193
193
  struct.regex.should == nil
194
194
  end
195
195
 
196
+ it 'should convert to hash using to_hash' do
197
+ hash = {
198
+ :a => 'a',
199
+ 'b' => 1,
200
+ :c => {:a => 1, :b => 2}
201
+ }
202
+ struct = @rubytter.structize(hash)
203
+ new_hash = struct.to_hash
204
+ new_hash.should == {:a=>"a", :b=>1, :c=>{:a=>1, :b=>2}}
205
+ end
206
+
196
207
  it 'should create struct from json(Array)' do
197
208
  data = [
198
209
  {"status" => {"text" => "foo", "user" => {"screen_name" => "jugyo_foo"}}},
@@ -316,32 +327,32 @@ class Rubytter
316
327
  end
317
328
 
318
329
  it 'should POST /:user/list to create list' do
319
- @rubytter.should_receive(:post).with("/1/test/lists", {:name=>"foo"})
330
+ @rubytter.should_receive(:post).with("/test/lists", {:name=>"foo"})
320
331
  @rubytter.create_list('foo')
321
332
  end
322
333
 
323
334
  it 'should PUT /:user/list to update list' do
324
- @rubytter.should_receive(:put).with("/1/test/lists/foo", {})
335
+ @rubytter.should_receive(:put).with("/test/lists/foo", {})
325
336
  @rubytter.update_list('foo')
326
337
  end
327
338
 
328
339
  it 'should DELETE /:user/list to delete list' do
329
- @rubytter.should_receive(:delete).with("/1/test/lists/foo", {})
340
+ @rubytter.should_receive(:delete).with("/test/lists/foo", {})
330
341
  @rubytter.delete_list('foo')
331
342
  end
332
343
 
333
344
  it 'should GET lists for specified user' do
334
- @rubytter.should_receive(:get).with("/1/jugyo/lists", {})
345
+ @rubytter.should_receive(:get).with("/jugyo/lists", {})
335
346
  @rubytter.lists('jugyo')
336
347
  end
337
348
 
338
349
  it 'should add member to list' do
339
- @rubytter.should_receive(:post).with("/1/test/foo/members", {:id=>"jugyo"})
350
+ @rubytter.should_receive(:post).with("/test/foo/members", {:id=>"jugyo"})
340
351
  @rubytter.add_member_to_list('foo', 'jugyo')
341
352
  end
342
353
 
343
354
  it 'should remove member to list' do
344
- @rubytter.should_receive(:delete).with("/1/test/foo/members", {:id=>"jugyo"})
355
+ @rubytter.should_receive(:delete).with("/test/foo/members", {:id=>"jugyo"})
345
356
  @rubytter.remove_member_from_list('foo', 'jugyo')
346
357
  end
347
358
 
@@ -352,7 +363,7 @@ class Rubytter
352
363
  rubytter = OAuthRubytter.new(access_token)
353
364
  response = simple_mock(:body => '{}', :code => '200')
354
365
  access_token.should_receive(:post).with(
355
- "/1/statuses/update.json",
366
+ "/statuses/update.json",
356
367
  {'status' => 'test'},
357
368
  {"User-Agent"=>"Rubytter/#{Rubytter::VERSION} (http://github.com/jugyo/rubytter)"}
358
369
  ).and_return(response)
@@ -364,7 +375,7 @@ class Rubytter
364
375
  rubytter = OAuthRubytter.new(access_token)
365
376
  response = simple_mock(:body => '{}', :code => '200')
366
377
  access_token.should_receive(:get).with(
367
- '/1/statuses/friends_timeline.json',
378
+ '/statuses/friends_timeline.json',
368
379
  {"User-Agent"=>"Rubytter/#{Rubytter::VERSION} (http://github.com/jugyo/rubytter)"}
369
380
  ).and_return(response)
370
381
  rubytter.friends_timeline
@@ -375,7 +386,7 @@ class Rubytter
375
386
  rubytter = OAuthRubytter.new(access_token)
376
387
  response = simple_mock(:body => '{}', :code => '200')
377
388
  access_token.should_receive(:get).with(
378
- '/1/statuses/friends_timeline.json?page=2',
389
+ '/statuses/friends_timeline.json?page=2',
379
390
  {"User-Agent"=>"Rubytter/#{Rubytter::VERSION} (http://github.com/jugyo/rubytter)"}
380
391
  ).and_return(response)
381
392
  rubytter.friends_timeline(:page => 2)
@@ -403,7 +414,7 @@ class Rubytter
403
414
  connection_for_search.enable_ssl.should == false
404
415
 
405
416
  @ssl_rubytter.should_receive(:http_request).
406
- with('search.twitter.com', anything, nil, connection_for_search).
417
+ with('api.twitter.com', anything, nil, connection_for_search).
407
418
  and_return({'results' => []})
408
419
  @ssl_rubytter.search('rubytter')
409
420
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubytter
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 7
4
5
  prerelease: false
5
6
  segments:
6
7
  - 1
7
- - 3
8
- - 2
9
- version: 1.3.2
8
+ - 4
9
+ - 0
10
+ version: 1.4.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - jugyo
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-05-13 00:00:00 +09:00
18
+ date: 2010-06-22 00:00:00 +09:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: json
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 21
27
30
  segments:
28
31
  - 1
29
32
  - 1
@@ -35,9 +38,11 @@ dependencies:
35
38
  name: oauth
36
39
  prerelease: false
37
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
38
42
  requirements:
39
43
  - - ">="
40
44
  - !ruby/object:Gem::Version
45
+ hash: 31
41
46
  segments:
42
47
  - 0
43
48
  - 3
@@ -49,9 +54,11 @@ dependencies:
49
54
  name: rspec
50
55
  prerelease: false
51
56
  requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
52
58
  requirements:
53
59
  - - ">="
54
60
  - !ruby/object:Gem::Version
61
+ hash: 3
55
62
  segments:
56
63
  - 0
57
64
  version: "0"
@@ -102,23 +109,27 @@ rdoc_options:
102
109
  require_paths:
103
110
  - lib
104
111
  required_ruby_version: !ruby/object:Gem::Requirement
112
+ none: false
105
113
  requirements:
106
114
  - - ">="
107
115
  - !ruby/object:Gem::Version
116
+ hash: 3
108
117
  segments:
109
118
  - 0
110
119
  version: "0"
111
120
  required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
112
122
  requirements:
113
123
  - - ">="
114
124
  - !ruby/object:Gem::Version
125
+ hash: 3
115
126
  segments:
116
127
  - 0
117
128
  version: "0"
118
129
  requirements: []
119
130
 
120
131
  rubyforge_project: rubytter
121
- rubygems_version: 1.3.6
132
+ rubygems_version: 1.3.7
122
133
  signing_key:
123
134
  specification_version: 3
124
135
  summary: Simple twitter client.