twitter 6.1.0 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +22 -15
  3. data/README.md +69 -394
  4. data/lib/twitter/base.rb +2 -16
  5. data/lib/twitter/basic_user.rb +0 -3
  6. data/lib/twitter/client.rb +5 -19
  7. data/lib/twitter/configuration.rb +3 -2
  8. data/lib/twitter/creatable.rb +1 -1
  9. data/lib/twitter/cursor.rb +0 -1
  10. data/lib/twitter/entity/uri.rb +0 -4
  11. data/lib/twitter/error.rb +81 -96
  12. data/lib/twitter/geo_results.rb +0 -1
  13. data/lib/twitter/headers.rb +11 -10
  14. data/lib/twitter/media/photo.rb +4 -0
  15. data/lib/twitter/media/video.rb +4 -1
  16. data/lib/twitter/media/video_info.rb +1 -1
  17. data/lib/twitter/null_object.rb +2 -2
  18. data/lib/twitter/profile.rb +3 -2
  19. data/lib/twitter/rate_limit.rb +1 -1
  20. data/lib/twitter/rest/api.rb +0 -2
  21. data/lib/twitter/rest/client.rb +0 -78
  22. data/lib/twitter/rest/direct_messages.rb +3 -3
  23. data/lib/twitter/rest/favorites.rb +25 -4
  24. data/lib/twitter/rest/friends_and_followers.rb +1 -3
  25. data/lib/twitter/rest/lists.rb +18 -29
  26. data/lib/twitter/rest/oauth.rb +15 -15
  27. data/lib/twitter/rest/request.rb +105 -16
  28. data/lib/twitter/rest/saved_searches.rb +0 -2
  29. data/lib/twitter/rest/search.rb +2 -0
  30. data/lib/twitter/rest/trends.rb +1 -0
  31. data/lib/twitter/rest/tweets.rb +80 -15
  32. data/lib/twitter/rest/undocumented.rb +3 -4
  33. data/lib/twitter/rest/users.rb +20 -34
  34. data/lib/twitter/rest/utils.rb +13 -20
  35. data/lib/twitter/search_results.rb +1 -2
  36. data/lib/twitter/streaming/client.rb +17 -23
  37. data/lib/twitter/streaming/connection.rb +23 -10
  38. data/lib/twitter/streaming/deleted_tweet.rb +0 -1
  39. data/lib/twitter/streaming/event.rb +6 -6
  40. data/lib/twitter/streaming/message_parser.rb +1 -1
  41. data/lib/twitter/streaming/response.rb +2 -2
  42. data/lib/twitter/trend_results.rb +1 -2
  43. data/lib/twitter/tweet.rb +1 -5
  44. data/lib/twitter/user.rb +0 -2
  45. data/lib/twitter/utils.rb +1 -16
  46. data/lib/twitter/version.rb +1 -1
  47. data/twitter.gemspec +13 -13
  48. metadata +35 -27
  49. data/lib/twitter/rest/media.rb +0 -30
  50. data/lib/twitter/rest/request/multipart_with_file.rb +0 -47
  51. data/lib/twitter/rest/response/parse_error_json.rb +0 -13
  52. data/lib/twitter/rest/response/parse_json.rb +0 -31
  53. data/lib/twitter/rest/response/raise_error.rb +0 -32
  54. data/lib/twitter/token.rb +0 -20
@@ -16,7 +16,7 @@ module Twitter
16
16
  #
17
17
  # @return [Array<Twitter::Variant>]
18
18
  def variants
19
- @attrs.fetch(:variants, []).map do |variant|
19
+ @attrs.fetch(:variants, []).collect do |variant|
20
20
  Variant.new(variant)
21
21
  end
22
22
  end
@@ -18,12 +18,12 @@ module Twitter
18
18
  end
19
19
 
20
20
  def instance_of?(klass)
21
- raise(TypeError.new('class or module required')) unless klass.is_a?(Class)
21
+ raise(TypeError, 'class or module required') unless klass.is_a?(Class)
22
22
  self.class == klass
23
23
  end
24
24
 
25
25
  def kind_of?(mod)
26
- raise(TypeError.new('class or module required')) unless mod.is_a?(Module)
26
+ raise(TypeError, 'class or module required') unless mod.is_a?(Module)
27
27
  self.class.ancestors.include?(mod)
28
28
  end
29
29
 
@@ -1,4 +1,5 @@
1
1
  require 'addressable/uri'
2
+ require 'cgi'
2
3
  require 'memoizable'
3
4
 
4
5
  module Twitter
@@ -11,7 +12,7 @@ module Twitter
11
12
  private
12
13
 
13
14
  def alias_predicate_uri_methods(method)
14
- %w(_url? _uri_https? _url_https?).each do |replacement|
15
+ %w[_url? _uri_https? _url_https?].each do |replacement|
15
16
  alias_method_sub(method, PREDICATE_URI_METHOD_REGEX, replacement)
16
17
  end
17
18
  end
@@ -88,7 +89,7 @@ module Twitter
88
89
  end
89
90
 
90
91
  def profile_image_suffix(size)
91
- :original == size.to_sym ? '\\1' : "_#{size}\\1"
92
+ size.to_sym == :original ? '\\1' : "_#{size}\\1"
92
93
  end
93
94
  end
94
95
  end
@@ -21,7 +21,7 @@ module Twitter
21
21
  # @return [Time]
22
22
  def reset_at
23
23
  reset = @attrs['x-rate-limit-reset']
24
- Time.at(reset.to_i) if reset
24
+ Time.at(reset.to_i).utc if reset
25
25
  end
26
26
  memoize :reset_at
27
27
 
@@ -3,7 +3,6 @@ require 'twitter/rest/favorites'
3
3
  require 'twitter/rest/friends_and_followers'
4
4
  require 'twitter/rest/help'
5
5
  require 'twitter/rest/lists'
6
- require 'twitter/rest/media'
7
6
  require 'twitter/rest/oauth'
8
7
  require 'twitter/rest/places_and_geo'
9
8
  require 'twitter/rest/saved_searches'
@@ -26,7 +25,6 @@ module Twitter
26
25
  include Twitter::REST::FriendsAndFollowers
27
26
  include Twitter::REST::Help
28
27
  include Twitter::REST::Lists
29
- include Twitter::REST::Media
30
28
  include Twitter::REST::OAuth
31
29
  include Twitter::REST::PlacesAndGeo
32
30
  include Twitter::REST::SavedSearches
@@ -1,85 +1,14 @@
1
- require 'faraday'
2
- require 'faraday/request/multipart'
3
1
  require 'twitter/client'
4
2
  require 'twitter/rest/api'
5
3
  require 'twitter/rest/request'
6
- require 'twitter/rest/request/multipart_with_file'
7
- require 'twitter/rest/response/parse_json'
8
- require 'twitter/rest/response/raise_error'
9
4
  require 'twitter/rest/utils'
10
5
 
11
6
  module Twitter
12
7
  module REST
13
8
  class Client < Twitter::Client
14
9
  include Twitter::REST::API
15
- BASE_URL = 'https://api.twitter.com'.freeze
16
- URL_PREFIX = BASE_URL
17
- ENDPOINT = BASE_URL
18
10
  attr_accessor :bearer_token
19
11
 
20
- # @param connection_options [Hash]
21
- # @return [Hash]
22
- def connection_options=(connection_options)
23
- warn "#{Kernel.caller.first}: [DEPRECATION] #{self.class.name}##{__method__} is deprecated and will be removed."
24
- @connection_options = connection_options
25
- end
26
-
27
- # @return [Hash]
28
- def connection_options
29
- @connection_options ||= {
30
- builder: middleware,
31
- headers: {
32
- accept: 'application/json',
33
- user_agent: user_agent,
34
- },
35
- request: {
36
- open_timeout: 10,
37
- timeout: 30,
38
- },
39
- proxy: proxy,
40
- }
41
- end
42
-
43
- # @params middleware [Faraday::RackBuilder]
44
- # @return [Faraday::RackBuilder]
45
- def middleware=(middleware)
46
- warn "#{Kernel.caller.first}: [DEPRECATION] #{self.class.name}##{__method__} is deprecated and will be removed."
47
- @middleware = middleware
48
- end
49
-
50
- # @note Faraday's middleware stack implementation is comparable to that of Rack middleware. The order of middleware is important: the first middleware on the list wraps all others, while the last middleware is the innermost one.
51
- # @see https://github.com/technoweenie/faraday#advanced-middleware-usage
52
- # @see http://mislav.uniqpath.com/2011/07/faraday-advanced-http/
53
- # @return [Faraday::RackBuilder]
54
- def middleware
55
- @middleware ||= Faraday::RackBuilder.new do |faraday|
56
- # Convert file uploads to Faraday::UploadIO objects
57
- faraday.request :twitter_multipart_with_file
58
- # Checks for files in the payload, otherwise leaves everything untouched
59
- faraday.request :multipart
60
- # Encodes as "application/x-www-form-urlencoded" if not already encoded
61
- faraday.request :url_encoded
62
- # Handle error responses
63
- faraday.response :twitter_raise_error
64
- # Parse JSON response bodies
65
- faraday.response :twitter_parse_json
66
- # Set default HTTP adapter
67
- faraday.adapter :net_http
68
- end
69
- end
70
-
71
- # Perform an HTTP GET request
72
- def get(path, options = {})
73
- warn "#{Kernel.caller.first}: [DEPRECATION] #{self.class.name}##{__method__} is deprecated. Use Twitter::REST::Request#perform instead."
74
- perform_get(path, options)
75
- end
76
-
77
- # Perform an HTTP POST request
78
- def post(path, options = {})
79
- warn "#{Kernel.caller.first}: [DEPRECATION] #{self.class.name}##{__method__} is deprecated. Use Twitter::REST::Request#perform instead."
80
- perform_post(path, options)
81
- end
82
-
83
12
  # @return [Boolean]
84
13
  def bearer_token?
85
14
  !!bearer_token
@@ -89,13 +18,6 @@ module Twitter
89
18
  def credentials?
90
19
  super || bearer_token?
91
20
  end
92
-
93
- # Returns a Faraday::Connection object
94
- #
95
- # @return [Faraday::Connection]
96
- def connection
97
- @connection ||= Faraday.new(BASE_URL, connection_options)
98
- end
99
21
  end
100
22
  end
101
23
  end
@@ -55,6 +55,7 @@ module Twitter
55
55
  # @param id [Integer] A direct message ID.
56
56
  # @param options [Hash] A customizable set of options.
57
57
  def direct_message(id, options = {})
58
+ options = options.dup
58
59
  options[:id] = id
59
60
  perform_get_with_object('/1.1/direct_messages/show.json', options, Twitter::DirectMessage)
60
61
  end
@@ -111,7 +112,6 @@ module Twitter
111
112
  def destroy_direct_message(*args)
112
113
  parallel_objects_from_response(Twitter::DirectMessage, :post, '/1.1/direct_messages/destroy.json', args)
113
114
  end
114
- deprecate_alias :direct_message_destroy, :destroy_direct_message
115
115
 
116
116
  # Sends a new direct message to the specified user from the authenticating user
117
117
  #
@@ -121,9 +121,10 @@ module Twitter
121
121
  # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
122
122
  # @return [Twitter::DirectMessage] The sent message.
123
123
  # @param user [Integer, String, Twitter::User] A Twitter user ID, screen name, URI, or object.
124
- # @param text [String] The text of your direct message, up to 140 characters.
124
+ # @param text [String] The text of your direct message, up to 10,000 characters.
125
125
  # @param options [Hash] A customizable set of options.
126
126
  def create_direct_message(user, text, options = {})
127
+ options = options.dup
127
128
  merge_user!(options, user)
128
129
  options[:text] = text
129
130
  perform_post_with_object('/1.1/direct_messages/new.json', options, Twitter::DirectMessage)
@@ -131,7 +132,6 @@ module Twitter
131
132
  alias d create_direct_message
132
133
  alias m create_direct_message
133
134
  alias dm create_direct_message
134
- deprecate_alias :direct_message_create, :create_direct_message
135
135
  end
136
136
  end
137
137
  end
@@ -48,10 +48,33 @@ module Twitter
48
48
  # @param tweets [Enumerable<Integer, String, URI, Twitter::Tweet>] A collection of Tweet IDs, URIs, or objects.
49
49
  # @param options [Hash] A customizable set of options.
50
50
  def unfavorite(*args)
51
- parallel_objects_from_response(Twitter::Tweet, :post, '/1.1/favorites/destroy.json', args)
51
+ arguments = Twitter::Arguments.new(args)
52
+ pmap(arguments) do |tweet|
53
+ begin
54
+ perform_post_with_object('/1.1/favorites/destroy.json', arguments.options.merge(id: extract_id(tweet)), Twitter::Tweet)
55
+ rescue Twitter::Error::NotFound
56
+ next
57
+ end
58
+ end.compact
52
59
  end
53
60
  alias destroy_favorite unfavorite
54
- deprecate_alias :favorite_destroy, :unfavorite
61
+
62
+ # Un-favorites the specified Tweets as the authenticating user and raises an error if one is not found
63
+ #
64
+ # @see https://dev.twitter.com/rest/reference/post/favorites/destroy
65
+ # @rate_limited No
66
+ # @authentication Requires user context
67
+ # @raise [Twitter::Error::NotFound] Error raised when tweet does not exist or has been deleted.
68
+ # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
69
+ # @return [Array<Twitter::Tweet>] The un-favorited Tweets.
70
+ # @overload unfavorite!(*tweets)
71
+ # @param tweets [Enumerable<Integer, String, URI, Twitter::Tweet>] A collection of Tweet IDs, URIs, or objects.
72
+ # @overload unfavorite!(*tweets, options)
73
+ # @param tweets [Enumerable<Integer, String, URI, Twitter::Tweet>] A collection of Tweet IDs, URIs, or objects.
74
+ # @param options [Hash] A customizable set of options.
75
+ def unfavorite!(*args)
76
+ parallel_objects_from_response(Twitter::Tweet, :post, '/1.1/favorites/destroy.json', args)
77
+ end
55
78
 
56
79
  # Favorites the specified Tweets as the authenticating user
57
80
  #
@@ -77,7 +100,6 @@ module Twitter
77
100
  end
78
101
  alias fav favorite
79
102
  alias fave favorite
80
- deprecate_alias :favorite_create, :favorite
81
103
 
82
104
  # Favorites the specified Tweets as the authenticating user and raises an error if one has already been favorited
83
105
  #
@@ -102,7 +124,6 @@ module Twitter
102
124
  alias create_favorite! favorite!
103
125
  alias fav! favorite!
104
126
  alias fave! favorite!
105
- deprecate_alias :favorite_create!, :favorite!
106
127
  end
107
128
  end
108
129
  end
@@ -114,7 +114,6 @@ module Twitter
114
114
  follow!(new_friends.value - existing_friends.value, arguments.options)
115
115
  end
116
116
  alias create_friendship follow
117
- deprecate_alias :friendship_create, :follow
118
117
 
119
118
  # Allows the authenticating user to follow the specified users
120
119
  #
@@ -136,7 +135,6 @@ module Twitter
136
135
  end.compact
137
136
  end
138
137
  alias create_friendship! follow!
139
- deprecate_alias :friendship_create!, :follow!
140
138
 
141
139
  # Allows the authenticating user to unfollow the specified users
142
140
  #
@@ -154,7 +152,6 @@ module Twitter
154
152
  parallel_users_from_response(:post, '/1.1/friendships/destroy.json', args)
155
153
  end
156
154
  alias destroy_friendship unfollow
157
- deprecate_alias :friendship_destroy, :unfollow
158
155
 
159
156
  # Allows one to enable or disable retweets and device notifications from the specified user.
160
157
  #
@@ -183,6 +180,7 @@ module Twitter
183
180
  # @param target [Integer, String, Twitter::User] The Twitter user ID, screen name, or object of the target user.
184
181
  # @param options [Hash] A customizable set of options.
185
182
  def friendship(source, target, options = {})
183
+ options = options.dup
186
184
  merge_user!(options, source, 'source')
187
185
  options[:source_id] = options.delete(:source_user_id) unless options[:source_user_id].nil?
188
186
  merge_user!(options, target, 'target')
@@ -1,3 +1,4 @@
1
+ require 'addressable/uri'
1
2
  require 'twitter/arguments'
2
3
  require 'twitter/cursor'
3
4
  require 'twitter/error'
@@ -7,6 +8,7 @@ require 'twitter/rest/utils'
7
8
  require 'twitter/tweet'
8
9
  require 'twitter/user'
9
10
  require 'twitter/utils'
11
+ require 'uri'
10
12
 
11
13
  module Twitter
12
14
  module REST
@@ -14,7 +16,6 @@ module Twitter
14
16
  include Twitter::REST::Utils
15
17
  include Twitter::Utils
16
18
  MAX_USERS_PER_REQUEST = 100
17
- URI_SUBSTRING = '://'.freeze
18
19
 
19
20
  # Returns all lists the authenticating or specified user subscribes to, including their own
20
21
  #
@@ -83,7 +84,6 @@ module Twitter
83
84
  def remove_list_member(*args)
84
85
  list_from_response_with_user('/1.1/lists/members/destroy.json', args)
85
86
  end
86
- deprecate_alias :list_remove_member, :remove_list_member
87
87
 
88
88
  # List the lists the specified user has been added to
89
89
  #
@@ -206,7 +206,6 @@ module Twitter
206
206
  def add_list_members(*args)
207
207
  list_from_response_with_users('/1.1/lists/members/create_all.json', args)
208
208
  end
209
- deprecate_alias :list_add_members, :add_list_members
210
209
 
211
210
  # Check if a user is a member of the specified list
212
211
  #
@@ -269,7 +268,6 @@ module Twitter
269
268
  def add_list_member(*args)
270
269
  list_from_response_with_user('/1.1/lists/members/create.json', args)
271
270
  end
272
- deprecate_alias :list_add_member, :add_list_member
273
271
 
274
272
  # Deletes the specified list
275
273
  #
@@ -290,7 +288,6 @@ module Twitter
290
288
  def destroy_list(*args)
291
289
  list_from_response(:post, '/1.1/lists/destroy.json', args)
292
290
  end
293
- deprecate_alias :list_destroy, :destroy_list
294
291
 
295
292
  # Updates the specified list
296
293
  #
@@ -330,7 +327,6 @@ module Twitter
330
327
  def create_list(name, options = {})
331
328
  perform_post_with_object('/1.1/lists/create.json', options.merge(name: name), Twitter::List)
332
329
  end
333
- deprecate_alias :list_create, :create_list
334
330
 
335
331
  # Show the specified list
336
332
  #
@@ -388,7 +384,6 @@ module Twitter
388
384
  def remove_list_members(*args)
389
385
  list_from_response_with_users('/1.1/lists/members/destroy_all.json', args)
390
386
  end
391
- deprecate_alias :list_remove_members, :remove_list_members
392
387
 
393
388
  # Returns the lists owned by the specified Twitter user
394
389
  #
@@ -407,8 +402,6 @@ module Twitter
407
402
  def owned_lists(*args)
408
403
  cursor_from_response_with_user(:lists, Twitter::List, '/1.1/lists/ownerships.json', args)
409
404
  end
410
- deprecate_alias :lists_ownerships, :owned_lists
411
- deprecate_alias :lists_owned, :owned_lists
412
405
 
413
406
  private
414
407
 
@@ -464,28 +457,24 @@ module Twitter
464
457
  #
465
458
  # @param hash [Hash]
466
459
  # @param list [Integer, String, URI, Twitter::List] A Twitter list ID, slug, URI, or object.
467
- # @return [Hash]
468
- def merge_list!(hash, list) # rubocop:disable MethodLength
460
+ def merge_list!(hash, list)
469
461
  case list
470
- when Integer
471
- hash[:list_id] = list
472
- when String
473
- if list[URI_SUBSTRING]
474
- list = list.split('/')
475
- hash[:slug] = list.pop
476
- hash[:owner_screen_name] = list.pop
477
- else
478
- hash[:slug] = list
479
- end
480
- when URI
481
- list = list.path.split('/')
482
- hash[:slug] = list.pop
483
- hash[:owner_screen_name] = list.pop
484
- when Twitter::List
485
- hash[:list_id] = list.id
486
- merge_owner!(hash, list.user)
462
+ when Integer then hash[:list_id] = list
463
+ when Twitter::List then merge_list_and_owner!(hash, list)
464
+ when String then merge_slug_and_owner!(hash, list)
465
+ when URI, Addressable::URI then merge_slug_and_owner!(hash, list.path)
487
466
  end
488
- hash
467
+ end
468
+
469
+ def merge_slug_and_owner!(hash, path)
470
+ list = path.split('/')
471
+ hash[:slug] = list.pop
472
+ hash[:owner_screen_name] = list.pop unless list.empty?
473
+ end
474
+
475
+ def merge_list_and_owner!(hash, list)
476
+ merge_list!(hash, list.id)
477
+ merge_owner!(hash, list.user)
489
478
  end
490
479
 
491
480
  # Take an owner and merge it into the hash with the correct key
@@ -1,7 +1,5 @@
1
1
  require 'twitter/headers'
2
2
  require 'twitter/rest/utils'
3
- require 'twitter/rest/response/parse_error_json'
4
- require 'twitter/token'
5
3
 
6
4
  module Twitter
7
5
  module REST
@@ -18,15 +16,19 @@ module Twitter
18
16
  # @rate_limited No
19
17
  # @authentication Required
20
18
  # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
21
- # @return [Twitter::Token] The Bearer Token. token_type should be 'bearer'.
19
+ # @return [String] The Bearer token.
22
20
  # @param options [Hash] A customizable set of options.
23
21
  # @example Generate a Bearer Token
24
- # client = Twitter::REST::Client.new(:consumer_key => "abc", :consumer_secret => 'def')
22
+ # client = Twitter::REST::Client.new(consumer_key: 'abc', consumer_secret: 'def')
25
23
  # bearer_token = client.token
26
24
  def token(options = {})
25
+ options = options.dup
27
26
  options[:bearer_token_request] = true
28
27
  options[:grant_type] ||= 'client_credentials'
29
- perform_post_with_object('/oauth2/token', options, Twitter::Token)
28
+ url = 'https://api.twitter.com/oauth2/token'
29
+ headers = Twitter::Headers.new(self, :post, url, options).request_headers
30
+ response = HTTP.headers(headers).post(url, form: options)
31
+ response.parse['access_token']
30
32
  end
31
33
  alias bearer_token token
32
34
 
@@ -36,13 +38,13 @@ module Twitter
36
38
  # @rate_limited No
37
39
  # @authentication Required
38
40
  # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
39
- # @param access_token [String, Twitter::Token] The bearer token to revoke.
41
+ # @param access_token [String] The bearer token to revoke.
40
42
  # @param options [Hash] A customizable set of options.
41
- # @return [Twitter::Token] The invalidated token. token_type should be nil.
43
+ # @return [String] The invalidated token. token_type should be nil.
42
44
  def invalidate_token(access_token, options = {})
43
- access_token = access_token.access_token if access_token.is_a?(Twitter::Token)
45
+ options = options.dup
44
46
  options[:access_token] = access_token
45
- perform_post_with_object('/oauth2/invalidate_token', options, Twitter::Token)
47
+ perform_post('/oauth2/invalidate_token', options)[:access_token]
46
48
  end
47
49
 
48
50
  # Allows a registered application to revoke an issued OAuth 2 Bearer Token by presenting its client credentials.
@@ -53,12 +55,10 @@ module Twitter
53
55
  # @raise [Twitter::Error::Unauthorized] Error raised when supplied user credentials are not valid.
54
56
  # @return [String] The token string.
55
57
  def reverse_token
56
- conn = connection.dup
57
- conn.builder.swap(4, Twitter::REST::Response::ParseErrorJson)
58
- response = conn.post('/oauth/request_token?x_auth_mode=reverse_auth') do |request|
59
- request.headers[:authorization] = Twitter::Headers.new(self, :post, 'https://api.twitter.com/oauth/request_token', x_auth_mode: 'reverse_auth').oauth_auth_header.to_s
60
- end
61
- response.body
58
+ options = {x_auth_mode: 'reverse_auth'}
59
+ url = 'https://api.twitter.com/oauth/request_token'
60
+ auth_header = Twitter::Headers.new(self, :post, url, options).oauth_auth_header.to_s
61
+ HTTP.headers(authorization: auth_header).post(url, params: options).to_s
62
62
  end
63
63
  end
64
64
  end