twitter 8.2.0 → 8.3.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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +172 -10
  4. data/lib/twitter/arguments.rb +14 -1
  5. data/lib/twitter/base.rb +72 -11
  6. data/lib/twitter/basic_user.rb +7 -1
  7. data/lib/twitter/client.rb +94 -3
  8. data/lib/twitter/creatable.rb +11 -2
  9. data/lib/twitter/cursor.rb +58 -11
  10. data/lib/twitter/direct_message.rb +32 -4
  11. data/lib/twitter/direct_message_event.rb +34 -10
  12. data/lib/twitter/direct_messages/welcome_message.rb +22 -1
  13. data/lib/twitter/direct_messages/welcome_message_rule.rb +7 -0
  14. data/lib/twitter/direct_messages/welcome_message_rule_wrapper.rb +26 -3
  15. data/lib/twitter/direct_messages/welcome_message_wrapper.rb +36 -11
  16. data/lib/twitter/entities.rb +84 -8
  17. data/lib/twitter/entity/hashtag.rb +7 -1
  18. data/lib/twitter/entity/symbol.rb +7 -1
  19. data/lib/twitter/entity/uri.rb +2 -1
  20. data/lib/twitter/entity/user_mention.rb +20 -1
  21. data/lib/twitter/entity.rb +7 -1
  22. data/lib/twitter/enumerable.rb +20 -3
  23. data/lib/twitter/error.rb +137 -61
  24. data/lib/twitter/factory.rb +9 -5
  25. data/lib/twitter/geo/point.rb +37 -5
  26. data/lib/twitter/geo/polygon.rb +1 -0
  27. data/lib/twitter/geo.rb +16 -2
  28. data/lib/twitter/geo_factory.rb +7 -3
  29. data/lib/twitter/geo_results.rb +39 -8
  30. data/lib/twitter/headers.rb +44 -7
  31. data/lib/twitter/identity.rb +13 -3
  32. data/lib/twitter/language.rb +21 -1
  33. data/lib/twitter/list.rb +101 -11
  34. data/lib/twitter/media/animated_gif.rb +1 -0
  35. data/lib/twitter/media/photo.rb +19 -3
  36. data/lib/twitter/media/video.rb +21 -3
  37. data/lib/twitter/media/video_info.rb +15 -1
  38. data/lib/twitter/media_factory.rb +7 -3
  39. data/lib/twitter/metadata.rb +14 -1
  40. data/lib/twitter/null_object.rb +16 -14
  41. data/lib/twitter/oembed.rb +56 -2
  42. data/lib/twitter/place.rb +74 -6
  43. data/lib/twitter/premium_search_results.rb +87 -18
  44. data/lib/twitter/profile.rb +100 -44
  45. data/lib/twitter/profile_banner.rb +9 -4
  46. data/lib/twitter/rate_limit.rb +32 -3
  47. data/lib/twitter/relationship.rb +8 -5
  48. data/lib/twitter/rest/account_activity.rb +55 -26
  49. data/lib/twitter/rest/api.rb +2 -0
  50. data/lib/twitter/rest/client.rb +18 -0
  51. data/lib/twitter/rest/direct_messages/welcome_messages.rb +89 -18
  52. data/lib/twitter/rest/direct_messages.rb +158 -94
  53. data/lib/twitter/rest/favorites.rb +57 -21
  54. data/lib/twitter/rest/form_encoder.rb +57 -17
  55. data/lib/twitter/rest/friends_and_followers.rb +101 -35
  56. data/lib/twitter/rest/help.rb +13 -3
  57. data/lib/twitter/rest/lists.rb +133 -45
  58. data/lib/twitter/rest/oauth.rb +23 -17
  59. data/lib/twitter/rest/places_and_geo.rb +44 -28
  60. data/lib/twitter/rest/premium_search.rb +18 -13
  61. data/lib/twitter/rest/request.rb +171 -53
  62. data/lib/twitter/rest/saved_searches.rb +22 -7
  63. data/lib/twitter/rest/search.rb +20 -16
  64. data/lib/twitter/rest/spam_reporting.rb +5 -1
  65. data/lib/twitter/rest/suggested_users.rb +14 -5
  66. data/lib/twitter/rest/timelines.rb +92 -52
  67. data/lib/twitter/rest/trends.rb +31 -12
  68. data/lib/twitter/rest/tweets.rb +145 -88
  69. data/lib/twitter/rest/undocumented.rb +11 -2
  70. data/lib/twitter/rest/upload_utils.rb +42 -26
  71. data/lib/twitter/rest/users.rb +150 -71
  72. data/lib/twitter/rest/utils.rb +135 -39
  73. data/lib/twitter/saved_search.rb +23 -2
  74. data/lib/twitter/search_results.rb +62 -17
  75. data/lib/twitter/settings.rb +37 -11
  76. data/lib/twitter/size.rb +37 -3
  77. data/lib/twitter/source_user.rb +4 -3
  78. data/lib/twitter/streaming/client.rb +60 -8
  79. data/lib/twitter/streaming/connection.rb +55 -8
  80. data/lib/twitter/streaming/deleted_tweet.rb +8 -0
  81. data/lib/twitter/streaming/event.rb +43 -1
  82. data/lib/twitter/streaming/friend_list.rb +1 -0
  83. data/lib/twitter/streaming/message_parser.rb +20 -10
  84. data/lib/twitter/streaming/response.rb +31 -5
  85. data/lib/twitter/streaming/stall_warning.rb +23 -0
  86. data/lib/twitter/suggestion.rb +25 -1
  87. data/lib/twitter/target_user.rb +2 -1
  88. data/lib/twitter/trend.rb +29 -1
  89. data/lib/twitter/trend_results.rb +50 -7
  90. data/lib/twitter/tweet.rb +180 -21
  91. data/lib/twitter/user.rb +289 -53
  92. data/lib/twitter/utils.rb +12 -13
  93. data/lib/twitter/variant.rb +12 -1
  94. data/lib/twitter/version.rb +66 -29
  95. data/lib/twitter.rb +6 -1
  96. metadata +23 -57
  97. data/.yardopts +0 -16
  98. data/CHANGELOG.md +0 -1040
  99. data/CONTRIBUTING.md +0 -49
  100. data/twitter.gemspec +0 -40
@@ -1,32 +1,49 @@
1
1
  module Twitter
2
+ # Provides iteration support for collections
2
3
  module Enumerable
3
4
  include ::Enumerable
4
5
 
6
+ # Iterates over the collection
7
+ #
8
+ # @api public
9
+ # @example
10
+ # cursor.each { |item| puts item }
11
+ # @param start [Integer] The starting index
12
+ # @yield [Object] Each item in the collection
5
13
  # @return [Enumerator]
6
14
  def each(start = 0, &block)
7
15
  return to_enum(:each, start) unless block
8
16
 
9
- Array(@collection[start..]).each(&block)
17
+ Array(@collection[start..]).each(&block) # steep:ignore FallbackAny
10
18
  unless finished?
11
- start = [@collection.size, start].max
19
+ start = [@collection.size, start].max # steep:ignore FallbackAny
12
20
  fetch_next_page
13
21
  each(start, &block)
14
22
  end
15
23
  self
16
24
  end
17
25
 
18
- private
26
+ private
19
27
 
28
+ # Returns true if this is the last page
29
+ #
30
+ # @api private
20
31
  # @return [Boolean]
21
32
  def last?
22
33
  true
23
34
  end
24
35
 
36
+ # Returns true if the limit has been reached
37
+ #
38
+ # @api private
25
39
  # @return [Boolean]
26
40
  def reached_limit?
27
41
  false
28
42
  end
29
43
 
44
+ # Returns true if iteration is finished
45
+ #
46
+ # @api private
30
47
  # @return [Boolean]
31
48
  def finished?
32
49
  last? || reached_limit?
data/lib/twitter/error.rb CHANGED
@@ -3,77 +3,107 @@ require "twitter/rate_limit"
3
3
  module Twitter
4
4
  # Custom error class for rescuing from all Twitter errors
5
5
  class Error < StandardError
6
+ # The error code from Twitter
7
+ #
8
+ # @api public
9
+ # @example
10
+ # error.code
6
11
  # @return [Integer]
7
12
  attr_reader :code
13
+
14
+ # The rate limit information from the response
15
+ #
16
+ # @api public
17
+ # @example
18
+ # error.rate_limit
8
19
  # @return [Twitter::RateLimit]
9
20
  attr_reader :rate_limit
10
21
 
11
22
  # Raised when Twitter returns a 4xx HTTP status code
12
- ClientError = Class.new(self)
23
+ ClientError = Class.new(self) # steep:ignore IncompatibleAssignment
13
24
 
14
25
  # Raised when Twitter returns the HTTP status code 400
15
- BadRequest = Class.new(ClientError)
26
+ class BadRequest < ClientError
27
+ end # steep:ignore IncompatibleAssignment
16
28
 
17
29
  # Raised when Twitter returns the HTTP status code 401
18
- Unauthorized = Class.new(ClientError)
30
+ class Unauthorized < ClientError
31
+ end # steep:ignore IncompatibleAssignment
19
32
 
20
33
  # Raised when Twitter returns the HTTP status code 403
21
- Forbidden = Class.new(ClientError)
34
+ class Forbidden < ClientError
35
+ end # steep:ignore IncompatibleAssignment
22
36
 
23
37
  # Raised when Twitter returns the HTTP status code 413
24
- RequestEntityTooLarge = Class.new(ClientError)
38
+ class RequestEntityTooLarge < ClientError
39
+ end # steep:ignore IncompatibleAssignment
25
40
 
26
41
  # Raised when a Tweet has already been favorited
27
- AlreadyFavorited = Class.new(Forbidden)
42
+ class AlreadyFavorited < Forbidden
43
+ end # steep:ignore IncompatibleAssignment
28
44
 
29
45
  # Raised when a Tweet has already been retweeted
30
- AlreadyRetweeted = Class.new(Forbidden)
46
+ class AlreadyRetweeted < Forbidden
47
+ end # steep:ignore IncompatibleAssignment
31
48
 
32
49
  # Raised when a Tweet has already been posted
33
- DuplicateStatus = Class.new(Forbidden)
50
+ class DuplicateStatus < Forbidden
51
+ end # steep:ignore IncompatibleAssignment
34
52
 
35
53
  # Raised when Twitter returns the HTTP status code 404
36
- NotFound = Class.new(ClientError)
54
+ class NotFound < ClientError
55
+ end # steep:ignore IncompatibleAssignment
37
56
 
38
57
  # Raised when Twitter returns the HTTP status code 406
39
- NotAcceptable = Class.new(ClientError)
58
+ class NotAcceptable < ClientError
59
+ end # steep:ignore IncompatibleAssignment
40
60
 
41
61
  # Raised when Twitter returns the HTTP status code 422
42
- UnprocessableEntity = Class.new(ClientError)
62
+ class UnprocessableEntity < ClientError
63
+ end # steep:ignore IncompatibleAssignment
43
64
 
44
65
  # Raised when Twitter returns the HTTP status code 429
45
- TooManyRequests = Class.new(ClientError)
66
+ class TooManyRequests < ClientError
67
+ end # steep:ignore IncompatibleAssignment
46
68
 
47
69
  # Raised when Twitter returns a 5xx HTTP status code
48
- ServerError = Class.new(self)
70
+ ServerError = Class.new(self) # steep:ignore IncompatibleAssignment
49
71
 
50
72
  # Raised when Twitter returns the HTTP status code 500
51
- InternalServerError = Class.new(ServerError)
73
+ class InternalServerError < ServerError
74
+ end # steep:ignore IncompatibleAssignment
52
75
 
53
76
  # Raised when Twitter returns the HTTP status code 502
54
- BadGateway = Class.new(ServerError)
77
+ class BadGateway < ServerError
78
+ end # steep:ignore IncompatibleAssignment
55
79
 
56
80
  # Raised when Twitter returns the HTTP status code 503
57
- ServiceUnavailable = Class.new(ServerError)
81
+ class ServiceUnavailable < ServerError
82
+ end # steep:ignore IncompatibleAssignment
58
83
 
59
84
  # Raised when Twitter returns the HTTP status code 504
60
- GatewayTimeout = Class.new(ServerError)
85
+ class GatewayTimeout < ServerError
86
+ end # steep:ignore IncompatibleAssignment
61
87
 
62
88
  # Raised when Twitter returns a media related error
63
- MediaError = Class.new(self)
89
+ MediaError = Class.new(self) # steep:ignore IncompatibleAssignment
64
90
 
65
91
  # Raised when Twitter returns an InvalidMedia error
66
- InvalidMedia = Class.new(MediaError)
92
+ class InvalidMedia < MediaError
93
+ end # steep:ignore IncompatibleAssignment
67
94
 
68
95
  # Raised when Twitter returns a media InternalError error
69
- MediaInternalError = Class.new(MediaError)
96
+ class MediaInternalError < MediaError
97
+ end # steep:ignore IncompatibleAssignment
70
98
 
71
99
  # Raised when Twitter returns an UnsupportedMedia error
72
- UnsupportedMedia = Class.new(MediaError)
100
+ class UnsupportedMedia < MediaError
101
+ end # steep:ignore IncompatibleAssignment
73
102
 
74
103
  # Raised when an operation subject to timeout takes too long
75
- TimeoutError = Class.new(self)
104
+ TimeoutError = Class.new(self) # steep:ignore IncompatibleAssignment
76
105
 
106
+ # Maps HTTP status codes to error classes
77
107
  ERRORS = {
78
108
  400 => Twitter::Error::BadRequest,
79
109
  401 => Twitter::Error::Unauthorized,
@@ -87,9 +117,10 @@ module Twitter
87
117
  500 => Twitter::Error::InternalServerError,
88
118
  502 => Twitter::Error::BadGateway,
89
119
  503 => Twitter::Error::ServiceUnavailable,
90
- 504 => Twitter::Error::GatewayTimeout,
120
+ 504 => Twitter::Error::GatewayTimeout
91
121
  }.freeze
92
122
 
123
+ # Maps forbidden message patterns to error classes
93
124
  FORBIDDEN_MESSAGES = proc do |message|
94
125
  case message
95
126
  when /(?=.*status).*duplicate/i
@@ -106,57 +137,89 @@ module Twitter
106
137
  end
107
138
  end
108
139
 
140
+ # Maps media error names to error classes
109
141
  MEDIA_ERRORS = {
110
142
  "InternalError" => Twitter::Error::MediaInternalError,
111
143
  "InvalidMedia" => Twitter::Error::InvalidMedia,
112
- "UnsupportedMedia" => Twitter::Error::UnsupportedMedia,
144
+ "UnsupportedMedia" => Twitter::Error::UnsupportedMedia
113
145
  }.freeze
114
146
 
115
- # If error code is missing see https://developer.twitter.com/en/docs/basics/response-codes
147
+ # Twitter API error codes
148
+ # @see https://developer.twitter.com/en/docs/basics/response-codes
116
149
  module Code
117
- AUTHENTICATION_PROBLEM = 32
118
- RESOURCE_NOT_FOUND = 34
119
- SUSPENDED_ACCOUNT = 64
120
- DEPRECATED_CALL = 68
121
- RATE_LIMIT_EXCEEDED = 88
122
- INVALID_OR_EXPIRED_TOKEN = 89
123
- SSL_REQUIRED = 92
124
- UNABLE_TO_VERIFY_CREDENTIALS = 99
125
- OVER_CAPACITY = 130
126
- INTERNAL_ERROR = 131
150
+ # Authentication problem error code
151
+ AUTHENTICATION_PROBLEM = 32
152
+ # Resource not found error code
153
+ RESOURCE_NOT_FOUND = 34
154
+ # Suspended account error code
155
+ SUSPENDED_ACCOUNT = 64
156
+ # Deprecated call error code
157
+ DEPRECATED_CALL = 68
158
+ # Rate limit exceeded error code
159
+ RATE_LIMIT_EXCEEDED = 88
160
+ # Invalid or expired token error code
161
+ INVALID_OR_EXPIRED_TOKEN = 89
162
+ # SSL required error code
163
+ SSL_REQUIRED = 92
164
+ # Unable to verify credentials error code
165
+ UNABLE_TO_VERIFY_CREDENTIALS = 99
166
+ # Over capacity error code
167
+ OVER_CAPACITY = 130
168
+ # Internal error code
169
+ INTERNAL_ERROR = 131
170
+ # OAuth timestamp out of range error code
127
171
  OAUTH_TIMESTAMP_OUT_OF_RANGE = 135
128
- ALREADY_FAVORITED = 139
129
- FOLLOW_ALREADY_REQUESTED = 160
130
- FOLLOW_LIMIT_EXCEEDED = 161
131
- PROTECTED_STATUS = 179
132
- OVER_UPDATE_LIMIT = 185
133
- DUPLICATE_STATUS = 187
134
- BAD_AUTHENTICATION_DATA = 215
135
- SPAM = 226
136
- LOGIN_VERIFICATION_NEEDED = 231
137
- ENDPOINT_RETIRED = 251
138
- CANNOT_WRITE = 261
139
- CANNOT_MUTE = 271
140
- CANNOT_UNMUTE = 272
172
+ # Already favorited error code
173
+ ALREADY_FAVORITED = 139
174
+ # Follow already requested error code
175
+ FOLLOW_ALREADY_REQUESTED = 160
176
+ # Follow limit exceeded error code
177
+ FOLLOW_LIMIT_EXCEEDED = 161
178
+ # Protected status error code
179
+ PROTECTED_STATUS = 179
180
+ # Over update limit error code
181
+ OVER_UPDATE_LIMIT = 185
182
+ # Duplicate status error code
183
+ DUPLICATE_STATUS = 187
184
+ # Bad authentication data error code
185
+ BAD_AUTHENTICATION_DATA = 215
186
+ # Spam error code
187
+ SPAM = 226
188
+ # Login verification needed error code
189
+ LOGIN_VERIFICATION_NEEDED = 231
190
+ # Endpoint retired error code
191
+ ENDPOINT_RETIRED = 251
192
+ # Cannot write error code
193
+ CANNOT_WRITE = 261
194
+ # Cannot mute error code
195
+ CANNOT_MUTE = 271
196
+ # Cannot unmute error code
197
+ CANNOT_UNMUTE = 272
141
198
  end
142
199
 
143
200
  class << self
144
201
  include Twitter::Utils
145
202
 
146
- # Create a new error from an HTTP response
203
+ # Creates a new error from an HTTP response
147
204
  #
148
- # @param body [String]
149
- # @param headers [Hash]
205
+ # @api public
206
+ # @example
207
+ # Twitter::Error.from_response(body, headers)
208
+ # @param body [String] The response body
209
+ # @param headers [Hash] The response headers
150
210
  # @return [Twitter::Error]
151
211
  def from_response(body, headers)
152
212
  message, code = parse_error(body)
153
213
  new(message, headers, code)
154
214
  end
155
215
 
156
- # Create a new error from a media error hash
216
+ # Creates a new error from a media error hash
157
217
  #
158
- # @param error [Hash]
159
- # @param headers [Hash]
218
+ # @api public
219
+ # @example
220
+ # Twitter::Error.from_processing_response(error, headers)
221
+ # @param error [Hash] The error hash from the response
222
+ # @param headers [Hash] The response headers
160
223
  # @return [Twitter::MediaError]
161
224
  def from_processing_response(error, headers)
162
225
  klass = MEDIA_ERRORS[error[:name]] || self
@@ -165,37 +228,50 @@ module Twitter
165
228
  klass.new(message, headers, code)
166
229
  end
167
230
 
168
- private
231
+ private
169
232
 
233
+ # Parses an error from the response body
234
+ #
235
+ # @api private
236
+ # @param body [Hash, nil] The response body
237
+ # @return [Array]
170
238
  def parse_error(body)
171
239
  if body.nil? || body.empty?
172
240
  ["", nil]
173
241
  elsif body[:error]
174
- [body[:error], nil]
242
+ [body.fetch(:error), nil]
175
243
  elsif body[:errors]
176
244
  extract_message_from_errors(body)
177
245
  end
178
246
  end
179
247
 
248
+ # Extracts error message from errors array
249
+ #
250
+ # @api private
251
+ # @param body [Hash] The response body with errors
252
+ # @return [Array]
180
253
  def extract_message_from_errors(body)
181
254
  first = Array(body[:errors]).first
182
255
  if first.is_a?(Hash)
183
256
  [first[:message].chomp, first[:code]]
184
257
  else
185
- [first.chomp, nil]
258
+ [first.chomp, nil] # steep:ignore NoMethod
186
259
  end
187
260
  end
188
261
  end
189
262
 
190
263
  # Initializes a new Error object
191
264
  #
192
- # @param message [Exception, String]
193
- # @param rate_limit [Hash]
194
- # @param code [Integer]
265
+ # @api public
266
+ # @example
267
+ # Twitter::Error.new("Something went wrong", {}, 123)
268
+ # @param message [Exception, String] The error message
269
+ # @param rate_limit [Hash] The rate limit headers
270
+ # @param code [Integer] The error code
195
271
  # @return [Twitter::Error]
196
272
  def initialize(message = "", rate_limit = {}, code = nil)
197
273
  super(message)
198
- @rate_limit = Twitter::RateLimit.new(rate_limit)
274
+ @rate_limit = RateLimit.new(rate_limit)
199
275
  @code = code
200
276
  end
201
277
  end
@@ -1,12 +1,16 @@
1
1
  module Twitter
2
+ # Factory for creating Twitter objects based on type
2
3
  class Factory
3
4
  class << self
4
- # Construct a new object
5
+ # Constructs a new object based on type
5
6
  #
6
- # @param method [Symbol]
7
- # @param klass [Class]
8
- # @param attrs [Hash]
9
- # @raise [IndexError] Error raised when supplied argument is missing a key.
7
+ # @api public
8
+ # @example
9
+ # Twitter::Factory.new(:type, Twitter::Geo, attrs)
10
+ # @param method [Symbol] The key to look up the type
11
+ # @param klass [Class] The base class for the type
12
+ # @param attrs [Hash] The attributes hash
13
+ # @raise [IndexError] Error raised when argument is missing a key
10
14
  # @return [Twitter::Base]
11
15
  def new(method, klass, attrs = {})
12
16
  type = attrs.fetch(method.to_sym)
@@ -2,19 +2,51 @@ require "twitter/geo"
2
2
 
3
3
  module Twitter
4
4
  class Geo
5
+ # Represents a geographic point with latitude and longitude
5
6
  class Point < Twitter::Geo
6
- # @return [Integer]
7
+ # Returns the latitude of this point
8
+ #
9
+ # @api public
10
+ # @example
11
+ # point.latitude
12
+ # @return [Float]
7
13
  def latitude
8
14
  coordinates[0]
9
15
  end
10
- alias lat latitude
11
16
 
12
- # @return [Integer]
17
+ # @!method lat
18
+ # Returns the latitude of this point
19
+ # @api public
20
+ # @example
21
+ # point.lat
22
+ # @return [Float]
23
+ alias_method :lat, :latitude
24
+
25
+ # Returns the longitude of this point
26
+ #
27
+ # @api public
28
+ # @example
29
+ # point.longitude
30
+ # @return [Float]
13
31
  def longitude
14
32
  coordinates[1]
15
33
  end
16
- alias long longitude
17
- alias lng longitude
34
+
35
+ # @!method long
36
+ # Returns the longitude of this point
37
+ # @api public
38
+ # @example
39
+ # point.long
40
+ # @return [Float]
41
+ alias_method :long, :longitude
42
+
43
+ # @!method lng
44
+ # Returns the longitude of this point
45
+ # @api public
46
+ # @example
47
+ # point.lng
48
+ # @return [Float]
49
+ alias_method :lng, :longitude
18
50
  end
19
51
  end
20
52
  end
@@ -2,6 +2,7 @@ require "twitter/geo"
2
2
 
3
3
  module Twitter
4
4
  class Geo
5
+ # Represents a polygon geographic area
5
6
  class Polygon < Twitter::Geo
6
7
  end
7
8
  end
data/lib/twitter/geo.rb CHANGED
@@ -2,10 +2,24 @@ require "equalizer"
2
2
  require "twitter/base"
3
3
 
4
4
  module Twitter
5
- class Geo < Twitter::Base
5
+ # Represents geographic information
6
+ class Geo < Base
6
7
  include Equalizer.new(:coordinates)
8
+
9
+ # The coordinates of this geographic location
10
+ #
11
+ # @api public
12
+ # @example
13
+ # geo.coordinates
7
14
  # @return [Array<Float>]
8
15
  attr_reader :coordinates
9
- alias coords coordinates
16
+
17
+ # @!method coords
18
+ # The coordinates of this geographic location
19
+ # @api public
20
+ # @example
21
+ # geo.coords
22
+ # @return [Array<Float>]
23
+ alias_method :coords, :coordinates
10
24
  end
11
25
  end
@@ -3,12 +3,16 @@ require "twitter/geo/point"
3
3
  require "twitter/geo/polygon"
4
4
 
5
5
  module Twitter
6
+ # Factory for creating geo objects based on type
6
7
  class GeoFactory < Twitter::Factory
7
8
  class << self
8
- # Construct a new geo object
9
+ # Constructs a new geo object
9
10
  #
10
- # @param attrs [Hash]
11
- # @raise [IndexError] Error raised when supplied argument is missing a :type key.
11
+ # @api public
12
+ # @example
13
+ # Twitter::GeoFactory.new(type: "Point", coordinates: [1.0, 2.0])
14
+ # @param attrs [Hash] The attributes hash with a :type key
15
+ # @raise [IndexError] Error raised when argument is missing a :type key
12
16
  # @return [Twitter::Geo]
13
17
  def new(attrs = {})
14
18
  super(:type, Geo, attrs)
@@ -2,25 +2,56 @@ require "twitter/enumerable"
2
2
  require "twitter/utils"
3
3
 
4
4
  module Twitter
5
+ # Represents a collection of geo search results
5
6
  class GeoResults
6
- include Twitter::Enumerable
7
- include Twitter::Utils
7
+ include Enumerable
8
+ include Utils
9
+
10
+ # The raw attributes hash
11
+ #
12
+ # @api public
13
+ # @example
14
+ # results.attrs
8
15
  # @return [Hash]
9
16
  attr_reader :attrs
10
- alias to_h attrs
11
- alias to_hash to_h
17
+
18
+ # @!method to_h
19
+ # Returns the attributes as a hash
20
+ # @api public
21
+ # @example
22
+ # results.to_h
23
+ # @return [Hash]
24
+ alias_method :to_h, :attrs
25
+
26
+ # @!method to_hash
27
+ # Returns the attributes as a hash
28
+ # @api public
29
+ # @example
30
+ # results.to_hash
31
+ # @return [Hash]
32
+ alias_method :to_hash, :to_h
12
33
 
13
34
  # Initializes a new GeoResults object
14
35
  #
15
- # @param attrs [Hash]
36
+ # @api public
37
+ # @example
38
+ # Twitter::GeoResults.new(result: {places: []})
39
+ # @param attrs [Hash] The attributes hash from the API response
16
40
  # @return [Twitter::GeoResults]
17
- def initialize(attrs = {})
18
- @attrs = attrs
19
- @collection = @attrs[:result].fetch(:places, []).collect do |place|
41
+ def initialize(attrs = nil)
42
+ @attrs = attrs || {}
43
+ empty_hash = {} # : Hash[Symbol, untyped]
44
+ empty_array = [] # : Array[untyped]
45
+ @collection = @attrs.fetch(:result, empty_hash).fetch(:places, empty_array).collect do |place| # steep:ignore ArgumentTypeMismatch
20
46
  Place.new(place)
21
47
  end
22
48
  end
23
49
 
50
+ # Returns the token for pagination
51
+ #
52
+ # @api public
53
+ # @example
54
+ # results.token
24
55
  # @return [String]
25
56
  def token
26
57
  @attrs[:token]
@@ -1,30 +1,59 @@
1
- require "addressable/uri"
1
+ require "uri"
2
2
  require "base64"
3
3
  require "simple_oauth"
4
4
 
5
5
  module Twitter
6
+ # Builds HTTP headers for Twitter API requests
6
7
  class Headers
8
+ # Initializes a new Headers object
9
+ #
10
+ # @api public
11
+ # @example
12
+ # Twitter::Headers.new(client, :get, "https://api.twitter.com")
13
+ # @param client [Twitter::Client] The client making the request
14
+ # @param request_method [Symbol] The HTTP request method
15
+ # @param url [String] The request URL
16
+ # @param options [Hash] Additional options
17
+ # @return [Twitter::Headers]
7
18
  def initialize(client, request_method, url, options = {})
8
19
  @client = client
9
- @request_method = request_method.to_sym
10
- @uri = Addressable::URI.parse(url)
20
+ @request_method = request_method
21
+ @uri = URI.parse(url)
11
22
  @bearer_token_request = options.delete(:bearer_token_request)
12
23
  @options = options
13
24
  end
14
25
 
26
+ # Check if this is a bearer token request
27
+ #
28
+ # @api public
29
+ # @example
30
+ # headers.bearer_token_request? # => false
31
+ # @return [Boolean]
15
32
  def bearer_token_request?
16
33
  !!@bearer_token_request
17
34
  end
18
35
 
36
+ # Generate OAuth authentication header
37
+ #
38
+ # @api public
39
+ # @example
40
+ # headers.oauth_auth_header # => #<SimpleOAuth::Header>
41
+ # @return [SimpleOAuth::Header]
19
42
  def oauth_auth_header
20
- SimpleOAuth::Header.new(@request_method, @uri, @options, @client.credentials.merge(ignore_extra_keys: true))
43
+ SimpleOAuth::Header.new(@request_method, @uri.to_s, @options, @client.credentials.merge(ignore_extra_keys: true))
21
44
  end
22
45
 
46
+ # Build the request headers hash
47
+ #
48
+ # @api public
49
+ # @example
50
+ # headers.request_headers # => {user_agent: "...", authorization: "..."}
51
+ # @return [Hash]
23
52
  def request_headers
24
- headers = {}
53
+ headers = {} # : Hash[Symbol, String]
25
54
  headers[:user_agent] = @client.user_agent
26
55
  if bearer_token_request?
27
- headers[:accept] = "*/*"
56
+ headers[:accept] = "*/*"
28
57
  headers[:authorization] = bearer_token_credentials_auth_header
29
58
  else
30
59
  headers[:authorization] = auth_header
@@ -32,8 +61,12 @@ module Twitter
32
61
  headers
33
62
  end
34
63
 
35
- private
64
+ private
36
65
 
66
+ # Generate the appropriate auth header based on credentials
67
+ #
68
+ # @api private
69
+ # @return [String]
37
70
  def auth_header
38
71
  if @client.user_token?
39
72
  oauth_auth_header.to_s
@@ -43,6 +76,9 @@ module Twitter
43
76
  end
44
77
  end
45
78
 
79
+ # Generate a bearer auth header
80
+ #
81
+ # @api private
46
82
  # @return [String]
47
83
  def bearer_auth_header
48
84
  "Bearer #{@client.bearer_token}"
@@ -50,6 +86,7 @@ module Twitter
50
86
 
51
87
  # Generates authentication header for a bearer token request
52
88
  #
89
+ # @api private
53
90
  # @return [String]
54
91
  def bearer_token_credentials_auth_header
55
92
  "Basic #{Base64.strict_encode64("#{@client.consumer_key}:#{@client.consumer_secret}")}"