twitter 4.7.0 → 4.8.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.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,10 @@
1
+ 4.8.0
2
+ -----
3
+ * [Add `Twitter::SearchResults#refresh_url`](https://github.com/sferik/twitter/commit/6bf08c008de139aad3ec173461e8633bfa5a3bd8) ([@mustafaturan](https://twitter.com/mustafaturan))
4
+ * [Fix issue with wrong signature being generated when multipart data is posted](https://github.com/sferik/twitter/commit/65ab90a6d51755e5901434a3568f8163ca3e262f) ([@mustafaturan](https://twitter.com/mustafaturan))
5
+ * [Restore compatibility with Ruby 1.8.7](https://github.com/sferik/twitter/commit/fb63970c1bd19792955d092a38b6adf53b558ec7)
6
+ * [Remove undocumented methods, retired in the APIpocalypse](https://github.com/sferik/twitter/commit/cf6a91f8df833dce5bffc7a0292402860e7d4da7)
7
+
1
8
  4.7.0
2
9
  -----
3
10
  * [Add support for application-only authentication](https://github.com/sferik/twitter/pull/387) ([@paracycle](https://twitter.com/paracycle))
@@ -260,7 +260,7 @@ module Twitter
260
260
  # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
261
261
  # @return [Twitter::Cursor]
262
262
  # @overload followers(options={})
263
- # Returns an array of numeric IDs for every user the authenticated user is following
263
+ # Returns a cursored collection of user objects for users following the authenticated user.
264
264
  #
265
265
  # @param options [Hash] A customizable set of options.
266
266
  # @option options [Integer] :cursor (-1) Breaks the results into pages. This is recommended for users who are following many users. Provide a value of -1 to begin paging. Provide values as returned in the response body's next_cursor and previous_cursor attributes to page back and forth in the list.
@@ -269,7 +269,7 @@ module Twitter
269
269
  # @example Return the authenticated user's friends' IDs
270
270
  # Twitter.followers
271
271
  # @overload followers(user, options={})
272
- # Returns an array of numeric IDs for every user the specified user is following
272
+ # Returns a cursored collection of user objects for users following the specified user.
273
273
  #
274
274
  # @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, or object.
275
275
  # @param options [Hash] A customizable set of options.
@@ -291,7 +291,7 @@ module Twitter
291
291
  # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
292
292
  # @return [Twitter::Cursor]
293
293
  # @overload friends(options={})
294
- # Returns an array of numeric IDs for every user the authenticated user is following
294
+ # Returns a cursored collection of user objects for every user the authenticated user is following (otherwise known as their "friends").
295
295
  #
296
296
  # @param options [Hash] A customizable set of options.
297
297
  # @option options [Integer] :cursor (-1) Breaks the results into pages. This is recommended for users who are following many users. Provide a value of -1 to begin paging. Provide values as returned in the response body's next_cursor and previous_cursor attributes to page back and forth in the list.
@@ -300,7 +300,7 @@ module Twitter
300
300
  # @example Return the authenticated user's friends' IDs
301
301
  # Twitter.friends
302
302
  # @overload friends(user, options={})
303
- # Returns an array of numeric IDs for every user the specified user is following
303
+ # Returns a cursored collection of user objects for every user the specified user is following (otherwise known as their "friends").
304
304
  #
305
305
  # @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, or object.
306
306
  # @param options [Hash] A customizable set of options.
@@ -69,7 +69,7 @@ module Twitter
69
69
  def list_timeline(*args)
70
70
  arguments = Twitter::API::Arguments.new(args)
71
71
  merge_list!(arguments.options, arguments.pop)
72
- merge_owner!(arguments.options, arguments.pop || screen_name) unless arguments.options[:owner_id] || arguments.options[:owner_screen_name]
72
+ merge_owner!(arguments.options, arguments.pop)
73
73
  objects_from_response(Twitter::Tweet, :get, "/1.1/lists/statuses.json", arguments.options)
74
74
  end
75
75
 
@@ -541,14 +541,14 @@ module Twitter
541
541
  def list_from_response(request_method, path, args)
542
542
  arguments = Twitter::API::Arguments.new(args)
543
543
  merge_list!(arguments.options, arguments.pop)
544
- merge_owner!(arguments.options, arguments.pop || screen_name) unless arguments.options[:owner_id] || arguments.options[:owner_screen_name]
544
+ merge_owner!(arguments.options, arguments.pop)
545
545
  object_from_response(Twitter::List, request_method, path, arguments.options)
546
546
  end
547
547
 
548
548
  def cursor_from_response_with_list(request_method, path, args, calling_method)
549
549
  arguments = Twitter::API::Arguments.new(args)
550
550
  merge_list!(arguments.options, arguments.pop)
551
- merge_owner!(arguments.options, arguments.pop || screen_name) unless arguments.options[:owner_id] || arguments.options[:owner_screen_name]
551
+ merge_owner!(arguments.options, arguments.pop)
552
552
  cursor_from_response(:users, Twitter::User, request_method, path, arguments.options, calling_method)
553
553
  end
554
554
 
@@ -556,7 +556,7 @@ module Twitter
556
556
  arguments = Twitter::API::Arguments.new(args)
557
557
  merge_user!(arguments.options, arguments.pop)
558
558
  merge_list!(arguments.options, arguments.pop)
559
- merge_owner!(arguments.options, arguments.pop || screen_name) unless arguments.options[:owner_id] || arguments.options[:owner_screen_name]
559
+ merge_owner!(arguments.options, arguments.pop)
560
560
  send(request_method.to_sym, path, arguments.options)
561
561
  true
562
562
  rescue Twitter::Error::NotFound, Twitter::Error::Forbidden
@@ -567,7 +567,7 @@ module Twitter
567
567
  arguments = Twitter::API::Arguments.new(args)
568
568
  merge_user!(arguments.options, arguments.pop)
569
569
  merge_list!(arguments.options, arguments.pop)
570
- merge_owner!(arguments.options, arguments.pop || screen_name) unless arguments.options[:owner_id] || arguments.options[:owner_screen_name]
570
+ merge_owner!(arguments.options, arguments.pop)
571
571
  object_from_response(Twitter::List, request_method, path, arguments.options)
572
572
  end
573
573
 
@@ -575,7 +575,7 @@ module Twitter
575
575
  arguments = Twitter::API::Arguments.new(args)
576
576
  members = arguments.pop
577
577
  merge_list!(arguments.options, arguments.pop)
578
- merge_owner!(arguments.options, arguments.pop || screen_name) unless arguments.options[:owner_id] || arguments.options[:owner_screen_name]
578
+ merge_owner!(arguments.options, arguments.pop)
579
579
  members.flatten.each_slice(MAX_USERS_PER_REQUEST).threaded_map do |users|
580
580
  object_from_response(Twitter::List, request_method, path, merge_users(arguments.options, users))
581
581
  end.last
@@ -605,8 +605,11 @@ module Twitter
605
605
  # @param user[Integer, String, Twitter::User] A Twitter user ID, screen_name, or object.
606
606
  # @return [Hash]
607
607
  def merge_owner!(hash, user)
608
- merge_user!(hash, user, "owner")
609
- hash[:owner_id] = hash.delete(:owner_user_id) unless hash[:owner_user_id].nil?
608
+ unless hash[:owner_id] || hash[:owner_screen_name]
609
+ user ||= screen_name
610
+ merge_user!(hash, user, "owner")
611
+ hash[:owner_id] = hash.delete(:owner_user_id) unless hash[:owner_user_id].nil?
612
+ end
610
613
  hash
611
614
  end
612
615
 
@@ -10,38 +10,6 @@ module Twitter
10
10
  module Undocumented
11
11
  include Twitter::API::Utils
12
12
 
13
- # Returns activity about me
14
- #
15
- # @note Undocumented
16
- # @rate_limited Yes
17
- # @authentication Requires user context
18
- # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
19
- # @return [Array] An array of actions
20
- # @param options [Hash] A customizable set of options.
21
- # @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 100.
22
- # @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID.
23
- # @example Return activity about me
24
- # Twitter.activity_about_me
25
- def activity_about_me(options={})
26
- objects_from_response(Twitter::ActionFactory, :get, "/i/activity/about_me.json", options)
27
- end
28
-
29
- # Returns activity by friends
30
- #
31
- # @note Undocumented
32
- # @rate_limited Yes
33
- # @authentication Requires user context
34
- # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid./
35
- # @return [Array] An array of actions
36
- # @param options [Hash] A customizable set of options.
37
- # @option options [Integer] :count Specifies the number of records to retrieve. Must be less than or equal to 100.
38
- # @option options [Integer] :since_id Returns results with an ID greater than (that is, more recent than) the specified ID.
39
- # @example Return activity by friends
40
- # Twitter.activity_by_friends
41
- def activity_by_friends(options={})
42
- objects_from_response(Twitter::ActionFactory, :get, "/i/activity/by_friends.json", options)
43
- end
44
-
45
13
  # @note Undocumented
46
14
  # @rate_limited Yes
47
15
  # @authentication Requires user context
@@ -20,7 +20,6 @@ require 'twitter/configurable'
20
20
  require 'twitter/error/client_error'
21
21
  require 'twitter/error/decode_error'
22
22
  require 'simple_oauth'
23
- require 'base64'
24
23
  require 'uri'
25
24
 
26
25
  module Twitter
@@ -86,7 +85,7 @@ module Twitter
86
85
  # @param path [String]
87
86
  # @param params [Hash]
88
87
  # @return [Proc]
89
- def request_setup(method, path, params)
88
+ def request_setup(method, path, params, signature_params)
90
89
  Proc.new do |request|
91
90
  if params.delete(:bearer_token_request)
92
91
  request.headers[:authorization] = bearer_token_credentials_auth_header
@@ -99,13 +98,13 @@ module Twitter
99
98
  end
100
99
  request.headers[:authorization] = bearer_auth_header
101
100
  else
102
- request.headers[:authorization] = oauth_auth_header(method, path, params).to_s
101
+ request.headers[:authorization] = oauth_auth_header(method, path, signature_params).to_s
103
102
  end
104
103
  end
105
104
  end
106
105
 
107
106
  def request(method, path, params={}, signature_params=params)
108
- request_setup = request_setup(method, path, params)
107
+ request_setup = request_setup(method, path, params, signature_params)
109
108
  connection.send(method.to_sym, path, params, &request_setup).env
110
109
  rescue Faraday::Error::ClientError
111
110
  raise Twitter::Error::ClientError
@@ -124,10 +123,14 @@ module Twitter
124
123
  #
125
124
  # @return [String]
126
125
  def bearer_token_credentials_auth_header
127
- basic_auth_token = Base64.strict_encode64("#{@consumer_key}:#{@consumer_secret}")
126
+ basic_auth_token = encode_value("#{@consumer_key}:#{@consumer_secret}")
128
127
  "Basic #{basic_auth_token}"
129
128
  end
130
129
 
130
+ def encode_value(value)
131
+ [value].pack("m0").gsub("\n", '')
132
+ end
133
+
131
134
  def bearer_auth_header
132
135
  "Bearer #{@bearer_token}"
133
136
  end
@@ -2,7 +2,7 @@ require 'twitter/error/client_error'
2
2
 
3
3
  module Twitter
4
4
  class Error
5
- # Raised when Twitter returns the HTTP status code 404
5
+ # Raised when Twitter returns the HTTP status code 422
6
6
  class UnprocessableEntity < Twitter::Error::ClientError
7
7
  HTTP_STATUS_CODE = 422
8
8
  end
@@ -63,5 +63,16 @@ module Twitter
63
63
  Faraday::Utils.parse_nested_query(@attrs[:search_metadata][:next_results][1..-1]).inject({}) { |memo, (k,v)| memo[k.to_sym] = v; memo} if next_results?
64
64
  end
65
65
  alias next_page next_results
66
+
67
+ # Returns a Hash of query parameters for the refresh URL in the search
68
+ #
69
+ # Returned Hash can be merged into the previous search options list
70
+ # to easily access the refresh page
71
+ #
72
+ # @return [Hash]
73
+ def refresh_url
74
+ Faraday::Utils.parse_nested_query(@attrs[:search_metadata][:refresh_url][1..-1]).inject({}) { |memo, (k,v)| memo[k.to_sym] = v; memo}
75
+ end
76
+ alias refresh_page refresh_url
66
77
  end
67
78
  end
@@ -1,7 +1,7 @@
1
1
  module Twitter
2
2
  class Version
3
3
  MAJOR = 4 unless defined? Twitter::Version::MAJOR
4
- MINOR = 7 unless defined? Twitter::Version::MINOR
4
+ MINOR = 8 unless defined? Twitter::Version::MINOR
5
5
  PATCH = 0 unless defined? Twitter::Version::PATCH
6
6
  PRE = nil unless defined? Twitter::Version::PRE
7
7
 
@@ -8,7 +8,7 @@ describe Twitter::API::OAuth do
8
8
 
9
9
  describe "#token" do
10
10
  before do
11
- # WebMock treats Basic Auth differently so we have to chack against the full url with credentials.
11
+ # WebMock treats Basic Auth differently so we have to chack against the full URL with credentials.
12
12
  @oauth2_token_url = "https://CK:CS@api.twitter.com/oauth2/token"
13
13
  stub_request(:post, @oauth2_token_url).with(:body => "grant_type=client_credentials").to_return(:body => fixture("bearer_token.json"), :headers => {:content_type => "application/json; charset=utf-8"})
14
14
  end
@@ -6,34 +6,6 @@ describe Twitter::API::Undocumented do
6
6
  @client = Twitter::Client.new
7
7
  end
8
8
 
9
- describe "#activity_about_me" do
10
- before do
11
- stub_get("/i/activity/about_me.json").to_return(:body => fixture("about_me.json"), :headers => {:content_type => "application/json; charset=utf-8"})
12
- end
13
- it "requests the correct resource" do
14
- @client.activity_about_me
15
- expect(a_get("/i/activity/about_me.json")).to have_been_made
16
- end
17
- it "returns activity about me" do
18
- activity_about_me = @client.activity_about_me
19
- expect(activity_about_me.first).to be_a Twitter::Action::Mention
20
- end
21
- end
22
-
23
- describe "#activity_by_friends" do
24
- before do
25
- stub_get("/i/activity/by_friends.json").to_return(:body => fixture("by_friends.json"), :headers => {:content_type => "application/json; charset=utf-8"})
26
- end
27
- it "requests the correct resource" do
28
- @client.activity_by_friends
29
- expect(a_get("/i/activity/by_friends.json")).to have_been_made
30
- end
31
- it "returns activity by friends" do
32
- activity_by_friends = @client.activity_by_friends
33
- expect(activity_by_friends.first).to be_a Twitter::Action::Favorite
34
- end
35
- end
36
-
37
9
  describe "#following_followers_of" do
38
10
  context "with a screen_name passed" do
39
11
  before do
@@ -173,6 +173,32 @@ describe Twitter::Client do
173
173
  expect(authorization.options[:token]).to eq "OT"
174
174
  expect(authorization.options[:token_secret]).to eq "OS"
175
175
  end
176
+ it "submits the correct auth header when no media is present" do
177
+ # We use static values for nounce and timestamp to get a stable signature
178
+ secret = {:consumer_key => 'CK', :consumer_secret => 'CS',
179
+ :token => 'OT', :token_secret => 'OS',
180
+ :nonce => 'b6ebe4c2a11af493f8a2290fe1296965', :timestamp => '1370968658'}
181
+ header = {"Authorization" => /oauth_signature="FbthwmgGq02iQw%2FuXGEWaL6V6eM%3D"/}
182
+
183
+ subject.stub(:credentials).and_return(secret)
184
+ stub_post("/1.1/statuses/update.json")
185
+ subject.update("Just a test")
186
+ expect(a_post("/1.1/statuses/update.json").
187
+ with(:headers => header)).to have_been_made
188
+ end
189
+ it "submits the correct auth header when media is present" do
190
+ # We use static values for nounce and timestamp to get a stable signature
191
+ secret = {:consumer_key => 'CK', :consumer_secret => 'CS',
192
+ :token => 'OT', :token_secret => 'OS',
193
+ :nonce => 'e08201ad0dab4897c99445056feefd95', :timestamp => '1370967652'}
194
+ header = {"Authorization" => /oauth_signature="9ziouUPwZT9IWWRbJL8r0BerKYA%3D"/}
195
+
196
+ subject.stub(:credentials).and_return(secret)
197
+ stub_post("/1.1/statuses/update_with_media.json")
198
+ subject.update_with_media("Just a test", fixture("pbjt.gif"))
199
+ expect(a_post("/1.1/statuses/update_with_media.json").
200
+ with(:headers => header)).to have_been_made
201
+ end
176
202
  end
177
203
 
178
204
  describe "#bearer_auth_header" do
@@ -191,7 +217,7 @@ describe Twitter::Client do
191
217
  it "creates the correct auth header with supplied consumer_key and consumer_secret" do
192
218
  uri = "/1.1/direct_messages.json"
193
219
  authorization = subject.send(:bearer_token_credentials_auth_header)
194
- expect(authorization).to eq "Basic #{Base64.strict_encode64("CK:CS")}"
220
+ expect(authorization).to eq "Basic Q0s6Q1M="
195
221
  end
196
222
  end
197
223
  end
@@ -113,10 +113,7 @@ describe Twitter::SearchResults do
113
113
  end
114
114
 
115
115
  describe "#next_results" do
116
- let(:next_results) {Twitter::SearchResults.new(:search_metadata =>
117
- {:next_results => "?max_id=249279667666817023&q=%23freebandnames&count=4&include_entities=1&result_type=mixed"
118
- }).next_results
119
- }
116
+ let(:next_results) {Twitter::SearchResults.new(:search_metadata => {:next_results => "?max_id=249279667666817023&q=%23freebandnames&count=4&include_entities=1&result_type=mixed"}).next_results}
120
117
 
121
118
  it "returns a hash of query parameters" do
122
119
  expect(next_results).to be_a Hash
@@ -127,4 +124,16 @@ describe Twitter::SearchResults do
127
124
  end
128
125
  end
129
126
 
127
+ describe "#refresh_url" do
128
+ let(:refresh_url) {Twitter::SearchResults.new(:search_metadata => {:refresh_url => "?since_id=249279667666817023&q=%23freebandnames&count=4&include_entities=1&result_type=recent"}).refresh_url}
129
+
130
+ it "returns a hash of query parameters" do
131
+ expect(refresh_url).to be_a Hash
132
+ end
133
+
134
+ it "returns a since_id" do
135
+ expect(refresh_url[:since_id]).to eq "249279667666817023"
136
+ end
137
+ end
138
+
130
139
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.7.0
4
+ version: 4.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -40,7 +40,7 @@ cert_chain:
40
40
  U0xxV3ZRUnNCbHlwSGZoczZKSnVMbHlaUEdoVTNSL3YKU2YzbFZLcEJDV2dS
41
41
  cEdUdnk0NVhWcEIrNTl5MzNQSm1FdVExUFRFT1l2UXlhbzlVS01BQWFBTi83
42
42
  cVdRdGpsMApobHc9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
43
- date: 2013-05-30 00:00:00.000000000 Z
43
+ date: 2013-06-12 00:00:00.000000000 Z
44
44
  dependencies:
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: faraday
metadata.gz.sig CHANGED
@@ -1 +1,2 @@
1
- O(�ӓa݌�i[fb��M�h��ĉ�eƆ��5�؄�$oWg�2Vf�:��� ���u�O���T>ܺ�����1
1
+ �x����N
2
+ c�ڴ��۝1������P?���Kݐnzx�A��փ@48ڏD�"S� �1d�T��ꍫ��䦐�T�2Y�Dm?�ͷ������?1~2X��L������� &���������[2[�s+n5�ӱ=7��x�Ƞ��w��"و�p�3м���>�=�� �R� ���Q�]p(`�P��?ö߀�j$���)�.��L�fM�0�HcD�ѽ�=�R�uȀzR2֓���ꔢ!hzb`uy�B�