x 0.9.1 → 0.11.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -27
  3. data/README.md +6 -2
  4. data/lib/x/authenticator.rb +8 -0
  5. data/lib/x/bearer_token_authenticator.rb +5 -3
  6. data/lib/x/cgi.rb +15 -0
  7. data/lib/x/client.rb +40 -37
  8. data/lib/x/connection.rb +42 -65
  9. data/lib/x/errors/bad_gateway.rb +5 -0
  10. data/lib/x/errors/{not_found_error.rb → bad_request.rb} +1 -1
  11. data/lib/x/errors/connection_exception.rb +5 -0
  12. data/lib/x/errors/error.rb +1 -9
  13. data/lib/x/errors/{forbidden_error.rb → forbidden.rb} +1 -1
  14. data/lib/x/errors/gateway_timeout.rb +5 -0
  15. data/lib/x/errors/{bad_request_error.rb → gone.rb} +1 -1
  16. data/lib/x/errors/internal_server_error.rb +5 -0
  17. data/lib/x/errors/network_error.rb +1 -1
  18. data/lib/x/errors/not_acceptable.rb +5 -0
  19. data/lib/x/errors/not_found.rb +5 -0
  20. data/lib/x/errors/payload_too_large.rb +5 -0
  21. data/lib/x/errors/service_unavailable.rb +5 -0
  22. data/lib/x/errors/too_many_redirects.rb +5 -0
  23. data/lib/x/errors/too_many_requests.rb +29 -0
  24. data/lib/x/errors/unauthorized.rb +5 -0
  25. data/lib/x/errors/unprocessable_entity.rb +5 -0
  26. data/lib/x/media_uploader.rb +122 -0
  27. data/lib/x/oauth_authenticator.rb +10 -15
  28. data/lib/x/redirect_handler.rb +26 -24
  29. data/lib/x/request_builder.rb +22 -28
  30. data/lib/x/response_parser.rb +92 -0
  31. data/lib/x/version.rb +1 -1
  32. data/sig/x.rbs +160 -71
  33. metadata +22 -11
  34. data/lib/x/errors/authentication_error.rb +0 -5
  35. data/lib/x/errors/service_unavailable_error.rb +0 -5
  36. data/lib/x/errors/too_many_redirects_error.rb +0 -5
  37. data/lib/x/errors/too_many_requests_error.rb +0 -29
  38. data/lib/x/response_handler.rb +0 -54
data/sig/x.rbs CHANGED
@@ -1,13 +1,17 @@
1
1
  module X
2
2
  VERSION: Gem::Version
3
3
 
4
+ class Authenticator
5
+ def header: (Net::HTTPRequest? request) -> Hash[String, String]
6
+ end
7
+
4
8
  class BearerTokenAuthenticator
5
9
  attr_accessor bearer_token: String
6
- def initialize: (String bearer_token) -> void
7
- def header: (Net::HTTPRequest _request) -> String
10
+ def initialize: (bearer_token: String) -> void
11
+ def header: (Net::HTTPRequest? request) -> Hash[String, String]
8
12
  end
9
13
 
10
- class OauthAuthenticator
14
+ class OAuthAuthenticator
11
15
  OAUTH_VERSION: String
12
16
  OAUTH_SIGNATURE_METHOD: String
13
17
  OAUTH_SIGNATURE_ALGORITHM: String
@@ -16,8 +20,8 @@ module X
16
20
  attr_accessor api_key_secret: String
17
21
  attr_accessor access_token: String
18
22
  attr_accessor access_token_secret: String
19
- def initialize: (String api_key, String api_key_secret, String access_token, String access_token_secret) -> void
20
- def header: (Net::HTTPRequest request) -> String
23
+ def initialize: (api_key: String, api_key_secret: String, access_token: String, access_token_secret: String) -> void
24
+ def header: (Net::HTTPRequest request) -> Hash[String, String]
21
25
 
22
26
  private
23
27
  def parse_request: (Net::HTTPRequest request) -> [String, String, Hash[String, String]]
@@ -33,152 +37,237 @@ module X
33
37
  def escape: (String value) -> String
34
38
  end
35
39
 
40
+ class ClientError < Error
41
+ end
42
+
43
+ class BadGateway < ClientError
44
+ end
45
+
46
+ class BadRequest < ClientError
47
+ end
48
+
49
+ class ConnectionException < ClientError
50
+ end
51
+
36
52
  class Error < StandardError
37
- JSON_CONTENT_TYPE_REGEXP: Regexp
53
+ def initialize: (String msg, ?Net::HTTPResponse? response) -> void
54
+ end
38
55
 
39
- attr_reader object: Hash[String, untyped]
40
- def initialize: (String msg, response: Net::HTTPResponse) -> void
56
+ class Forbidden < ClientError
57
+ end
41
58
 
42
- private
43
- def json_response?: (Net::HTTPResponse response) -> bool
59
+ class GatewayTimeout < ClientError
44
60
  end
45
61
 
46
- class ClientError < Error
62
+ class Gone < ClientError
63
+ end
64
+
65
+ class InternalServerError < ServerError
66
+ end
67
+
68
+ class NetworkError < Error
69
+ end
70
+
71
+ class NotAcceptable < ClientError
47
72
  end
48
73
 
49
- class BadRequestError < ClientError
74
+ class NotFound < ClientError
50
75
  end
51
76
 
52
- class AuthenticationError < ClientError
77
+ class PayloadTooLarge < ClientError
53
78
  end
54
79
 
55
- class ForbiddenError < ClientError
80
+ class ServerError < Error
56
81
  end
57
82
 
58
- class NotFoundError < ClientError
83
+ class ServiceUnavailable < ServerError
59
84
  end
60
85
 
61
- class TooManyRedirectsError < ClientError
86
+ class TooManyRedirects < ClientError
62
87
  end
63
88
 
64
- class TooManyRequestsError < ClientError
89
+ class TooManyRequests < ClientError
65
90
  @response: Net::HTTPResponse
66
91
 
67
- def initialize: (String msg, response: Net::HTTPResponse) -> void
92
+ def initialize: (String msg, Net::HTTPResponse response) -> void
68
93
  def limit: -> Integer
69
94
  def remaining: -> Integer
70
95
  def reset_at: -> Time
71
96
  def reset_in: -> Integer?
72
97
  end
73
98
 
74
- class ServerError < Error
75
- end
76
-
77
- class ServiceUnavailableError < ServerError
99
+ class Unauthorized < ClientError
78
100
  end
79
101
 
80
- class NetworkError < Error
102
+ class UnprocessableEntity < ClientError
81
103
  end
82
104
 
83
105
  class Connection
84
- DEFAULT_BASE_URL: String
85
106
  DEFAULT_HOST: String
86
107
  DEFAULT_PORT: Integer
87
108
  DEFAULT_OPEN_TIMEOUT: Integer
88
109
  DEFAULT_READ_TIMEOUT: Integer
89
110
  DEFAULT_WRITE_TIMEOUT: Integer
90
- NETWORK_ERRORS: Array[(singleton(::Errno::ECONNREFUSED) | singleton(::Net::OpenTimeout) | singleton(::Net::ReadTimeout))]
111
+ DEFAULT_DEBUG_OUTPUT: IO
112
+ NETWORK_ERRORS: Array[(singleton(Errno::ECONNREFUSED) | singleton(Errno::ECONNRESET) | singleton(Net::OpenTimeout) | singleton(Net::ReadTimeout) | singleton(OpenSSL::SSL::SSLError))]
113
+
91
114
  extend Forwardable
92
- @http_client: Net::HTTP
93
115
 
94
- attr_reader base_uri: URI::Generic
116
+ attr_accessor open_timeout : Float | Integer
117
+ attr_accessor read_timeout : Float | Integer
118
+ attr_accessor write_timeout : Float | Integer
119
+ attr_accessor debug_output : IO
120
+
95
121
  attr_reader proxy_uri: URI::Generic?
96
- attr_reader open_timeout : Float | Integer
97
- attr_reader read_timeout : Float | Integer
98
- attr_reader write_timeout : Float | Integer
99
- def initialize: (?base_url: URI::Generic | String, ?open_timeout: Float | Integer, ?read_timeout: Float | Integer, ?write_timeout: Float | Integer, ?proxy_url: URI::Generic? | String?, ?debug_output: IO?) -> void
100
- def send_request: (Net::HTTPRequest request) -> Net::HTTPResponse
101
- def base_uri=: (URI::Generic | String base_url) -> void
102
- def debug_output: -> IO?
122
+ attr_reader proxy_host : String?
123
+ attr_reader proxy_port : Integer?
124
+ attr_reader proxy_user : String?
125
+ attr_reader proxy_pass : String?
126
+
127
+ def initialize: (?open_timeout: Float | Integer, ?read_timeout: Float | Integer, ?write_timeout: Float | Integer, ?proxy_url: URI::Generic? | String?, ?debug_output: IO) -> void
128
+ def proxy_url=: (URI::Generic | String proxy_url) -> void
129
+ def perform: (request: Net::HTTPRequest) -> Net::HTTPResponse
103
130
 
104
131
  private
105
- def apply_http_client_settings: (open_timeout: Float | Integer, read_timeout: Float | Integer, write_timeout: Float | Integer, debug_output: IO?) -> untyped
106
- def current_http_client_settings: -> {open_timeout: Float | Integer, read_timeout: Float | Integer, write_timeout: Float | Integer, debug_output: IO?}
107
- def update_http_client_settings: -> untyped
108
- def build_http_client: (host: String, port: Integer) -> (Net::HTTP)
109
- def conditionally_apply_http_client_settings: { -> untyped } -> untyped
132
+ def build_http_client: (?String host, ?Integer port) -> Net::HTTP
133
+ def configure_http_client: (Net::HTTP http_client) -> Net::HTTP
110
134
  end
111
135
 
112
136
  class RequestBuilder
113
- HTTP_METHODS: Hash[::Symbol, (singleton(::Net::HTTP::Get) | singleton(::Net::HTTP::Post) | singleton(::Net::HTTP::Put) | singleton(::Net::HTTP::Delete))]
114
- DEFAULT_CONTENT_TYPE: String
115
- DEFAULT_USER_AGENT: String
116
- AUTHORIZATION_HEADER: String
117
- CONTENT_TYPE_HEADER: String
118
- USER_AGENT_HEADER: String
119
-
120
- attr_accessor content_type: String
121
- attr_accessor user_agent: String
137
+ HTTP_METHODS: Hash[Symbol, (singleton(Net::HTTP::Get) | singleton(Net::HTTP::Post) | singleton(Net::HTTP::Put) | singleton(Net::HTTP::Delete))]
138
+ DEFAULT_HEADERS: Hash[String, String]
139
+
122
140
  def initialize: (?content_type: String, ?user_agent: String) -> void
123
- def build: (BearerTokenAuthenticator | OauthAuthenticator authenticator, Symbol http_method, URI::Generic uri, ?body: String?) -> (Net::HTTPRequest)
141
+ def build: (authenticator: Authenticator, http_method: Symbol, uri: URI::Generic, ?body: String?, ?headers: Hash[String, String]) -> (Net::HTTPRequest)
124
142
 
125
143
  private
126
- def create_request: (Symbol http_method, URI::Generic uri, String? body) -> (Net::HTTPRequest)
127
- def add_authorization: (Net::HTTPRequest request, BearerTokenAuthenticator | OauthAuthenticator authenticator) -> void
128
- def add_content_type: (Net::HTTPRequest request) -> void
129
- def add_user_agent: (Net::HTTPRequest request) -> void
144
+ def create_request: (http_method: Symbol, uri: URI::Generic, body: String?) -> (Net::HTTPRequest)
145
+ def add_authentication: (request: Net::HTTPRequest, authenticator: Authenticator) -> void
146
+ def add_headers: (request: Net::HTTPRequest, headers: Hash[String, String]) -> void
130
147
  def escape_query_params: (URI::Generic uri) -> URI::Generic
131
148
  end
132
149
 
133
150
  class RedirectHandler
134
151
  DEFAULT_MAX_REDIRECTS: Integer
135
152
 
136
- attr_reader authenticator: BearerTokenAuthenticator | OauthAuthenticator
153
+ attr_reader authenticator: Authenticator
137
154
  attr_reader connection: Connection
138
155
  attr_reader request_builder: RequestBuilder
139
156
  attr_reader max_redirects: Integer
140
- def initialize: (BearerTokenAuthenticator | OauthAuthenticator authenticator, Connection connection, RequestBuilder request_builder, ?max_redirects: Integer) -> void
141
- def handle_redirects: (Net::HTTPResponse response, Net::HTTPRequest original_request, URI::Generic | String original_base_url, ?Integer redirect_count) -> Net::HTTPResponse
157
+ def initialize: (authenticator: Authenticator, connection: Connection, request_builder: RequestBuilder, ?max_redirects: Integer) -> void
158
+ def handle: (response: Net::HTTPResponse, request: Net::HTTPRequest, base_url: String, ?redirect_count: Integer) -> Net::HTTPResponse
142
159
 
143
160
  private
144
- def build_new_uri: (Net::HTTPResponse response, URI::Generic | String original_base_url) -> URI::Generic
145
- def build_request: (Net::HTTPRequest original_request, URI::Generic new_uri) -> Net::HTTPRequest
161
+ def build_new_uri: (Net::HTTPResponse response, String base_url) -> URI::Generic
162
+ def build_request: (Net::HTTPRequest request, URI::Generic new_uri, Integer response_code) -> Net::HTTPRequest
146
163
  def send_new_request: (URI::Generic new_uri, Net::HTTPRequest new_request) -> Net::HTTPResponse
147
164
  end
148
165
 
149
- class ResponseHandler
166
+ class ResponseParser
150
167
  DEFAULT_ARRAY_CLASS: Class
151
168
  DEFAULT_OBJECT_CLASS: Class
152
- ERROR_CLASSES: Hash[Integer, singleton(AuthenticationError) | singleton(BadRequestError) | singleton(ForbiddenError) | singleton(NotFoundError) | singleton(ServerError) | singleton(ServiceUnavailableError) | singleton(TooManyRequestsError)]
169
+ ERROR_CLASSES: Hash[Integer, singleton(Unauthorized) | singleton(BadRequest) | singleton(Forbidden) | singleton(InternalServerError) | singleton(NotFound) | singleton(PayloadTooLarge) | singleton(ServiceUnavailable) | singleton(TooManyRequests)]
153
170
  JSON_CONTENT_TYPE_REGEXP: Regexp
154
171
 
155
172
  attr_accessor array_class: Class
156
173
  attr_accessor object_class: Class
157
174
  def initialize: (?array_class: Class, ?object_class: Class) -> void
158
- def handle: (Net::HTTPResponse response) -> Hash[String, untyped]?
175
+ def parse: (response: Net::HTTPResponse) -> untyped
159
176
 
160
177
  private
161
178
  def success?: (Net::HTTPResponse response) -> bool
179
+ def error: (Net::HTTPResponse response) -> (Unauthorized | BadRequest | Forbidden | InternalServerError | NotFound | PayloadTooLarge | ServiceUnavailable | TooManyRequests)
180
+ def error_class: (Net::HTTPResponse response) -> (singleton(Unauthorized) | singleton(BadRequest) | singleton(Forbidden) | singleton(InternalServerError) | singleton(NotFound) | singleton(PayloadTooLarge) | singleton(ServiceUnavailable) | singleton(TooManyRequests))
181
+ def error_message: (Net::HTTPResponse response) -> String
182
+ def message_from_json_response: (Net::HTTPResponse response) -> String
162
183
  def json?: (Net::HTTPResponse response) -> bool
163
184
  end
164
185
 
165
186
  class Client
187
+ DEFAULT_BASE_URL: String
188
+
166
189
  extend Forwardable
167
- @authenticator: BearerTokenAuthenticator | OauthAuthenticator
190
+ @authenticator: Authenticator
168
191
  @connection: Connection
169
192
  @request_builder: RequestBuilder
170
193
  @redirect_handler: RedirectHandler
171
- @response_handler: ResponseHandler
194
+ @response_parser: ResponseParser
172
195
 
173
- attr_reader base_uri: URI::Generic
174
- def initialize: (?bearer_token: String?, ?api_key: String?, ?api_key_secret: String?, ?access_token: String?, ?access_token_secret: String?, ?base_url: URI::Generic | String, ?content_type: String, ?user_agent: String, ?open_timeout: Float | Integer, ?read_timeout: Float | Integer, ?write_timeout: Float | Integer, ?proxy_url: URI::Generic? | String?, ?debug_output: IO?, ?array_class: Class, ?object_class: Class, ?max_redirects: Integer) -> void
175
- def get: (String endpoint) -> Hash[String, untyped]?
176
- def post: (String endpoint, ?nil body) -> Hash[String, untyped]?
177
- def put: (String endpoint, ?nil body) -> Hash[String, untyped]?
178
- def delete: (String endpoint) -> Hash[String, untyped]?
196
+ attr_accessor access_token: String
197
+ attr_accessor access_token_secret: String
198
+ attr_accessor api_key: String
199
+ attr_accessor api_key_secret: String
200
+ attr_accessor bearer_token: String
201
+ attr_accessor base_url: String
202
+ attr_accessor open_timeout: Float | Integer
203
+ attr_accessor read_timeout: Float | Integer
204
+ attr_accessor write_timeout: Float | Integer
205
+ attr_accessor proxy_url: String
206
+ attr_accessor debug_output: IO
207
+ attr_accessor array_class: Class
208
+ attr_accessor object_class: Class
209
+ attr_accessor max_redirects: Integer
210
+ attr_accessor authenticator: Authenticator
211
+ attr_accessor connection: Connection
212
+ attr_accessor request_builder: RequestBuilder
213
+ attr_accessor redirect_handler: RedirectHandler
214
+ attr_accessor response_parser: ResponseParser
215
+
216
+ def initialize: (?bearer_token: String?, ?api_key: String?, ?api_key_secret: String?, ?access_token: String?, ?access_token_secret: String?, ?base_url: String, ?open_timeout: Float | Integer, ?read_timeout: Float | Integer, ?write_timeout: Float | Integer, ?proxy_url: URI::Generic? | String?, ?debug_output: IO, ?array_class: Class, ?object_class: Class, ?max_redirects: Integer) -> void
217
+ def get: (String endpoint, ?headers: Hash[String, String]) -> untyped
218
+ def post: (String endpoint, ?String? body, ?headers: Hash[String, String]) -> untyped
219
+ def put: (String endpoint, ?String? body, ?headers: Hash[String, String]) -> untyped
220
+ def delete: (String endpoint, ?headers: Hash[String, String]) -> untyped
221
+
222
+ private
223
+ def initialize_authenticator: (String? bearer_token, String? api_key, String? api_key_secret, String? access_token, String? access_token_secret) -> (BearerTokenAuthenticator | OAuthAuthenticator | Authenticator)
224
+ def execute_request: (Symbol http_method, String endpoint, headers: Hash[String, String], ?body: String?) -> untyped
225
+ end
226
+
227
+ module MediaUploader
228
+ MAX_RETRIES: Integer
229
+ BYTES_PER_MB: Integer
230
+ MEDIA_CATEGORIES: Array[String]
231
+ DM_GIF: String
232
+ DM_IMAGE: String
233
+ DM_VIDEO: String
234
+ SUBTITLES: String
235
+ TWEET_GIF: String
236
+ TWEET_IMAGE: String
237
+ TWEET_VIDEO: String
238
+ DEFAULT_MIME_TYPE: String
239
+ MIME_TYPES: Array[String]
240
+ GIF_MIME_TYPE: String
241
+ JPEG_MIME_TYPE: String
242
+ MP4_MIME_TYPE: String
243
+ PNG_MIME_TYPE: String
244
+ SUBRIP_MIME_TYPE: String
245
+ WEBP_MIME_TYPE: String
246
+ MIME_TYPE_MAP: Hash[String, String]
247
+ extend MediaUploader
248
+
249
+ def upload: (client: Client, file_path: String, media_category: String, ?media_type: String, ?boundary: String) -> untyped
250
+ def chunked_upload: (client: Client, file_path: String, media_category: String, ?media_type: String, ?boundary: String, ?chunk_size_mb: Integer) -> untyped
251
+ def await_processing: (client: Client, media: untyped) -> untyped
179
252
 
180
253
  private
181
- def initialize_authenticator: (String? bearer_token, String? api_key, String? api_key_secret, String? access_token, String? access_token_secret) -> (BearerTokenAuthenticator | OauthAuthenticator)
182
- def send_request: (Symbol http_method, String endpoint, ?nil body) -> Hash[String, untyped]?
254
+ def validate!: (file_path: String, media_category: String) -> nil
255
+ def infer_media_type: (String file_path, String media_category) -> String
256
+ def init: (Client upload_client, String file_path, String media_type, String media_category) -> untyped
257
+ def split: (String file_path, Integer chunk_size) -> Array[String]
258
+ def append: (Client upload_client, Array[String] chunk_paths, untyped media, String media_type, ?String boundary) -> Array[String]
259
+ def upload_chunk: (Client upload_client, String query, String chunk_path, String media_type, ?Hash[String, String] headers) -> Integer?
260
+ def cleanup_chunk: (String chunk_path) -> Integer?
261
+ def finalize: (Client upload_client, untyped media) -> untyped
262
+ def construct_upload_body: (String file_path, String media_type, ?String boundary) -> String
263
+ end
264
+
265
+ class CGI
266
+ def self.escape: (String value) -> String
267
+ def self.escape_params: (Hash[String, String] | Array[[String, String]] params) -> String
183
268
  end
184
269
  end
270
+
271
+ class Dir
272
+ def self.mktmpdir: (?String? prefix_suffix) -> String
273
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: x
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Berlin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-06 00:00:00.000000000 Z
11
+ date: 2023-10-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -23,24 +23,35 @@ files:
23
23
  - bin/console
24
24
  - bin/setup
25
25
  - lib/x.rb
26
+ - lib/x/authenticator.rb
26
27
  - lib/x/bearer_token_authenticator.rb
28
+ - lib/x/cgi.rb
27
29
  - lib/x/client.rb
28
30
  - lib/x/connection.rb
29
- - lib/x/errors/authentication_error.rb
30
- - lib/x/errors/bad_request_error.rb
31
+ - lib/x/errors/bad_gateway.rb
32
+ - lib/x/errors/bad_request.rb
31
33
  - lib/x/errors/client_error.rb
34
+ - lib/x/errors/connection_exception.rb
32
35
  - lib/x/errors/error.rb
33
- - lib/x/errors/forbidden_error.rb
36
+ - lib/x/errors/forbidden.rb
37
+ - lib/x/errors/gateway_timeout.rb
38
+ - lib/x/errors/gone.rb
39
+ - lib/x/errors/internal_server_error.rb
34
40
  - lib/x/errors/network_error.rb
35
- - lib/x/errors/not_found_error.rb
41
+ - lib/x/errors/not_acceptable.rb
42
+ - lib/x/errors/not_found.rb
43
+ - lib/x/errors/payload_too_large.rb
36
44
  - lib/x/errors/server_error.rb
37
- - lib/x/errors/service_unavailable_error.rb
38
- - lib/x/errors/too_many_redirects_error.rb
39
- - lib/x/errors/too_many_requests_error.rb
45
+ - lib/x/errors/service_unavailable.rb
46
+ - lib/x/errors/too_many_redirects.rb
47
+ - lib/x/errors/too_many_requests.rb
48
+ - lib/x/errors/unauthorized.rb
49
+ - lib/x/errors/unprocessable_entity.rb
50
+ - lib/x/media_uploader.rb
40
51
  - lib/x/oauth_authenticator.rb
41
52
  - lib/x/redirect_handler.rb
42
53
  - lib/x/request_builder.rb
43
- - lib/x/response_handler.rb
54
+ - lib/x/response_parser.rb
44
55
  - lib/x/version.rb
45
56
  - sig/x.rbs
46
57
  homepage: https://sferik.github.io/x-ruby
@@ -69,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
80
  - !ruby/object:Gem::Version
70
81
  version: '0'
71
82
  requirements: []
72
- rubygems_version: 3.4.20
83
+ rubygems_version: 3.4.21
73
84
  signing_key:
74
85
  specification_version: 4
75
86
  summary: A Ruby interface to the X API.
@@ -1,5 +0,0 @@
1
- require_relative "client_error"
2
-
3
- module X
4
- class AuthenticationError < ClientError; end
5
- end
@@ -1,5 +0,0 @@
1
- require_relative "server_error"
2
-
3
- module X
4
- class ServiceUnavailableError < ServerError; end
5
- end
@@ -1,5 +0,0 @@
1
- require_relative "client_error"
2
-
3
- module X
4
- class TooManyRedirectsError < ClientError; end
5
- end
@@ -1,29 +0,0 @@
1
- require_relative "client_error"
2
-
3
- module X
4
- # Rate limit error
5
- class TooManyRequestsError < ClientError
6
- def initialize(msg, response:)
7
- @response = response
8
- super
9
- end
10
-
11
- def limit
12
- @response.fetch("x-rate-limit-limit", 0).to_i
13
- end
14
-
15
- def remaining
16
- @response.fetch("x-rate-limit-remaining", 0).to_i
17
- end
18
-
19
- def reset_at
20
- Time.at(@response.fetch("x-rate-limit-reset", 0).to_i).utc
21
- end
22
-
23
- def reset_in
24
- [(reset_at - Time.now).ceil, 0].max if reset_at
25
- end
26
-
27
- alias_method :retry_after, :reset_in
28
- end
29
- end
@@ -1,54 +0,0 @@
1
- require "json"
2
- require "net/http"
3
- require_relative "errors/bad_request_error"
4
- require_relative "errors/authentication_error"
5
- require_relative "errors/forbidden_error"
6
- require_relative "errors/not_found_error"
7
- require_relative "errors/too_many_requests_error"
8
- require_relative "errors/server_error"
9
- require_relative "errors/service_unavailable_error"
10
-
11
- module X
12
- # Process HTTP responses
13
- class ResponseHandler
14
- DEFAULT_ARRAY_CLASS = Array
15
- DEFAULT_OBJECT_CLASS = Hash
16
- ERROR_CLASSES = {
17
- 400 => BadRequestError,
18
- 401 => AuthenticationError,
19
- 403 => ForbiddenError,
20
- 404 => NotFoundError,
21
- 429 => TooManyRequestsError,
22
- 500 => ServerError,
23
- 503 => ServiceUnavailableError
24
- }.freeze
25
- JSON_CONTENT_TYPE_REGEXP = %r{application/(problem\+|)json}
26
-
27
- attr_accessor :array_class, :object_class
28
-
29
- def initialize(array_class: DEFAULT_ARRAY_CLASS, object_class: DEFAULT_OBJECT_CLASS)
30
- @array_class = array_class
31
- @object_class = object_class
32
- end
33
-
34
- def handle(response)
35
- if success?(response)
36
- JSON.parse(response.body, array_class: array_class, object_class: object_class) if json?(response)
37
- else
38
- error_class = ERROR_CLASSES[response.code.to_i] || Error
39
- error_message = "#{response.code} #{response.message}"
40
- raise error_class.new(error_message, response: response)
41
- end
42
- end
43
-
44
- private
45
-
46
- def success?(response)
47
- response.is_a?(Net::HTTPSuccess)
48
- end
49
-
50
- def json?(response)
51
- response.body && JSON_CONTENT_TYPE_REGEXP.match?(response["content-type"])
52
- end
53
- end
54
- end