mparticle 1.0.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 (80) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +73 -0
  3. data/docs/ApiResponse.md +8 -0
  4. data/docs/ApiResponseErrors.md +9 -0
  5. data/docs/AppEvent.md +18 -0
  6. data/docs/ApplicationInformation.md +11 -0
  7. data/docs/ApplicationStateTransitionEvent.md +20 -0
  8. data/docs/AttributionInfo.md +10 -0
  9. data/docs/Batch.md +18 -0
  10. data/docs/BreadcrumbEvent.md +17 -0
  11. data/docs/CommerceEvent.md +22 -0
  12. data/docs/CrashReportEvent.md +26 -0
  13. data/docs/DeviceCurrentState.md +23 -0
  14. data/docs/DeviceInformation.md +41 -0
  15. data/docs/EventBase.md +9 -0
  16. data/docs/EventData.md +15 -0
  17. data/docs/EventsApi.md +124 -0
  18. data/docs/FirstRunEvent.md +15 -0
  19. data/docs/GeoLocation.md +10 -0
  20. data/docs/MediaInfo.md +15 -0
  21. data/docs/NetworkPerformanceEvent.md +22 -0
  22. data/docs/OptOutEvent.md +16 -0
  23. data/docs/Product.md +19 -0
  24. data/docs/ProductAction.md +19 -0
  25. data/docs/ProductImpression.md +9 -0
  26. data/docs/ProfileEvent.md +18 -0
  27. data/docs/Promotion.md +11 -0
  28. data/docs/PromotionAction.md +9 -0
  29. data/docs/PushMessageEvent.md +22 -0
  30. data/docs/PushRegistrationEvent.md +17 -0
  31. data/docs/ScreenViewEvent.md +17 -0
  32. data/docs/SessionEndEvent.md +16 -0
  33. data/docs/SessionStartEvent.md +15 -0
  34. data/docs/ShoppingCart.md +8 -0
  35. data/docs/SourceInformation.md +11 -0
  36. data/docs/UserIdentities.md +17 -0
  37. data/example/main.rb +32 -0
  38. data/lib/.DS_Store +0 -0
  39. data/lib/mparticle/.DS_Store +0 -0
  40. data/lib/mparticle/api/events_api.rb +129 -0
  41. data/lib/mparticle/api_client.rb +398 -0
  42. data/lib/mparticle/api_error.rb +26 -0
  43. data/lib/mparticle/configuration.rb +160 -0
  44. data/lib/mparticle/models/api_response.rb +178 -0
  45. data/lib/mparticle/models/api_response_errors.rb +185 -0
  46. data/lib/mparticle/models/app_event.rb +311 -0
  47. data/lib/mparticle/models/application_information.rb +203 -0
  48. data/lib/mparticle/models/application_state_transition_event.rb +352 -0
  49. data/lib/mparticle/models/attribution_info.rb +209 -0
  50. data/lib/mparticle/models/batch.rb +348 -0
  51. data/lib/mparticle/models/breadcrumb_event.rb +269 -0
  52. data/lib/mparticle/models/commerce_event.rb +306 -0
  53. data/lib/mparticle/models/crash_report_event.rb +362 -0
  54. data/lib/mparticle/models/device_current_state.rb +356 -0
  55. data/lib/mparticle/models/device_information.rb +506 -0
  56. data/lib/mparticle/models/event_base.rb +228 -0
  57. data/lib/mparticle/models/event_data.rb +241 -0
  58. data/lib/mparticle/models/first_run_event.rb +241 -0
  59. data/lib/mparticle/models/geo_location.rb +204 -0
  60. data/lib/mparticle/models/media_info.rb +296 -0
  61. data/lib/mparticle/models/network_performance_event.rb +334 -0
  62. data/lib/mparticle/models/opt_out_event.rb +255 -0
  63. data/lib/mparticle/models/product.rb +297 -0
  64. data/lib/mparticle/models/product_action.rb +330 -0
  65. data/lib/mparticle/models/product_impression.rb +197 -0
  66. data/lib/mparticle/models/profile_event.rb +316 -0
  67. data/lib/mparticle/models/promotion.rb +223 -0
  68. data/lib/mparticle/models/promotion_action.rb +230 -0
  69. data/lib/mparticle/models/push_message_event.rb +369 -0
  70. data/lib/mparticle/models/push_registration_event.rb +269 -0
  71. data/lib/mparticle/models/screen_view_event.rb +264 -0
  72. data/lib/mparticle/models/session_end_event.rb +255 -0
  73. data/lib/mparticle/models/session_start_event.rb +241 -0
  74. data/lib/mparticle/models/shopping_cart.rb +183 -0
  75. data/lib/mparticle/models/source_information.rb +246 -0
  76. data/lib/mparticle/models/user_identities.rb +257 -0
  77. data/lib/mparticle/version.rb +3 -0
  78. data/lib/mparticle.rb +61 -0
  79. data/mparticle.gemspec +19 -0
  80. metadata +163 -0
@@ -0,0 +1,398 @@
1
+ require 'date'
2
+ require 'json'
3
+ require 'logger'
4
+ require 'tempfile'
5
+ require 'typhoeus'
6
+ require 'uri'
7
+
8
+ module MParticle
9
+ class ApiClient
10
+ # The Configuration object holding settings to be used in the API client.
11
+ attr_accessor :config
12
+
13
+ # Defines the headers to be used in HTTP requests of all API calls by default.
14
+ #
15
+ # @return [Hash]
16
+ attr_accessor :default_headers
17
+
18
+ # Initializes the ApiClient
19
+ # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
20
+ def initialize(config)
21
+ @config = config
22
+ @user_agent = "mParticle Ruby client/1.0.0"
23
+ @default_headers = {
24
+ 'Content-Type' => "application/json",
25
+ 'User-Agent' => @user_agent
26
+ }
27
+ end
28
+
29
+ def self.default
30
+ @@default ||= ApiClient.new
31
+ end
32
+
33
+ # Call an API with given options.
34
+ #
35
+ # @return [Array<(Object, Fixnum, Hash)>] an array of 3 elements:
36
+ # the data deserialized from response body (could be nil), response status code and response headers.
37
+ def call_api(http_method, path, opts = {}, &callback)
38
+ request = build_request(http_method, path, opts)
39
+ if (callback.nil?)
40
+ response = request.run
41
+ if @config.debugging
42
+ @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
43
+ end
44
+
45
+ unless response.success?
46
+ if response.timed_out?
47
+ fail ApiError.new('Connection timed out')
48
+ elsif response.code == 0
49
+ # Errors from libcurl will be made visible here
50
+ fail ApiError.new(:code => 0,
51
+ :message => response.return_message)
52
+ else
53
+ fail ApiError.new(:code => response.code,
54
+ :response_headers => response.headers,
55
+ :response_body => response.body),
56
+ response.status_message
57
+ end
58
+ end
59
+
60
+ if opts[:return_type]
61
+ data = deserialize(response, opts[:return_type])
62
+ else
63
+ data = nil
64
+ end
65
+ return data, response.code, response.headers
66
+ else
67
+ request.on_complete do |response|
68
+ if @config.debugging
69
+ @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
70
+ end
71
+
72
+ unless response.success?
73
+ if response.timed_out?
74
+ fail ApiError.new('Connection timed out')
75
+ elsif response.code == 0
76
+ # Errors from libcurl will be made visible here
77
+ fail ApiError.new(:code => 0,
78
+ :message => response.return_message)
79
+ else
80
+ fail ApiError.new(:code => response.code,
81
+ :response_headers => response.headers,
82
+ :response_body => response.body),
83
+ response.status_message
84
+ end
85
+ end
86
+
87
+ if opts[:return_type]
88
+ data = deserialize(response, opts[:return_type])
89
+ else
90
+ data = nil
91
+ end
92
+ yield data, response.code, response.headers
93
+ end
94
+ hydra = Typhoeus::Hydra.hydra
95
+ hydra.queue(request)
96
+ thread = Thread.new { hydra.run }
97
+ return thread
98
+ end
99
+ end
100
+
101
+ # Builds the HTTP request
102
+ #
103
+ # @param [String] http_method HTTP method/verb (e.g. POST)
104
+ # @param [String] path URL path (e.g. /account/new)
105
+ # @option opts [Hash] :header_params Header parameters
106
+ # @option opts [Hash] :query_params Query parameters
107
+ # @option opts [Hash] :form_params Query parameters
108
+ # @option opts [Object] :body HTTP body (JSON/XML)
109
+ # @return [Typhoeus::Request] A Typhoeus Request
110
+ def build_request(http_method, path, opts = {})
111
+ url = build_request_url(path)
112
+ http_method = http_method.to_sym.downcase
113
+
114
+ header_params = @default_headers.merge(opts[:header_params] || {})
115
+ query_params = opts[:query_params] || {}
116
+ form_params = opts[:form_params] || {}
117
+
118
+ update_params_for_auth! header_params, query_params, opts[:auth_names]
119
+
120
+ # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false)
121
+ _verify_ssl_host = @config.verify_ssl_host ? 2 : 0
122
+
123
+ req_opts = {
124
+ :method => http_method,
125
+ :headers => header_params,
126
+ :params => query_params,
127
+ :params_encoding => @config.params_encoding,
128
+ :timeout => @config.timeout,
129
+ :ssl_verifypeer => @config.verify_ssl,
130
+ :ssl_verifyhost => _verify_ssl_host,
131
+ :sslcert => @config.cert_file,
132
+ :sslkey => @config.key_file,
133
+ :verbose => @config.debugging
134
+ }
135
+
136
+ # set custom cert, if provided
137
+ req_opts[:cainfo] = @config.ssl_ca_cert if @config.ssl_ca_cert
138
+
139
+ if [:post, :patch, :put, :delete].include?(http_method)
140
+ req_body = build_request_body(header_params, form_params, opts[:body])
141
+ req_opts.update :body => req_body
142
+ if @config.debugging
143
+ @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
144
+ end
145
+ end
146
+
147
+ Typhoeus::Request.new(url, req_opts)
148
+ end
149
+
150
+ # Check if the given MIME is a JSON MIME.
151
+ # JSON MIME examples:
152
+ # application/json
153
+ # application/json; charset=UTF8
154
+ # APPLICATION/JSON
155
+ # */*
156
+ # @param [String] mime MIME
157
+ # @return [Boolean] True if the MIME is application/json
158
+ def json_mime?(mime)
159
+ (mime == "*/*") || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil?
160
+ end
161
+
162
+ # Deserialize the response to the given return type.
163
+ #
164
+ # @param [Response] response HTTP response
165
+ # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]"
166
+ def deserialize(response, return_type)
167
+ body = response.body
168
+ return nil if body.nil? || body.empty?
169
+
170
+ # return response body directly for String return type
171
+ return body if return_type == 'String'
172
+
173
+ # handle file downloading - save response body into a tmp file and return the File instance
174
+ return download_file(response) if return_type == 'File'
175
+
176
+ # ensuring a default content type
177
+ content_type = response.headers['Content-Type'] || 'application/json'
178
+
179
+ fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
180
+
181
+ begin
182
+ data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
183
+ rescue JSON::ParserError => e
184
+ if %w(String Date DateTime).include?(return_type)
185
+ data = body
186
+ else
187
+ raise e
188
+ end
189
+ end
190
+
191
+ convert_to_type data, return_type
192
+ end
193
+
194
+ # Convert data to the given return type.
195
+ # @param [Object] data Data to be converted
196
+ # @param [String] return_type Return type
197
+ # @return [Mixed] Data in a particular type
198
+ def convert_to_type(data, return_type)
199
+ return nil if data.nil?
200
+ case return_type
201
+ when 'String'
202
+ data.to_s
203
+ when 'Integer'
204
+ data.to_i
205
+ when 'Float'
206
+ data.to_f
207
+ when 'BOOLEAN'
208
+ data == true
209
+ when 'DateTime'
210
+ # parse date time (expecting ISO 8601 format)
211
+ DateTime.parse data
212
+ when 'Date'
213
+ # parse date time (expecting ISO 8601 format)
214
+ Date.parse data
215
+ when 'Object'
216
+ # generic object (usually a Hash), return directly
217
+ data
218
+ when /\AArray<(.+)>\z/
219
+ # e.g. Array<Pet>
220
+ sub_type = $1
221
+ data.map {|item| convert_to_type(item, sub_type) }
222
+ when /\AHash\<String, (.+)\>\z/
223
+ # e.g. Hash<String, Integer>
224
+ sub_type = $1
225
+ {}.tap do |hash|
226
+ data.each {|k, v| hash[k] = convert_to_type(v, sub_type) }
227
+ end
228
+ else
229
+ # models, e.g. Pet
230
+ MParticle.const_get(return_type).new.tap do |model|
231
+ model.build_from_hash data
232
+ end
233
+ end
234
+ end
235
+
236
+ # Save response body into a file in (the defined) temporary folder, using the filename
237
+ # from the "Content-Disposition" header if provided, otherwise a random filename.
238
+ #
239
+ # @see Configuration#temp_folder_path
240
+ # @return [Tempfile] the file downloaded
241
+ def download_file(response)
242
+ content_disposition = response.headers['Content-Disposition']
243
+ if content_disposition and content_disposition =~ /filename=/i
244
+ filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
245
+ prefix = sanitize_filename(filename)
246
+ else
247
+ prefix = 'download-'
248
+ end
249
+ prefix = prefix + '-' unless prefix.end_with?('-')
250
+
251
+ tempfile = nil
252
+ encoding = response.body.encoding
253
+ Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) do |file|
254
+ file.write(response.body)
255
+ tempfile = file
256
+ end
257
+ @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\
258
+ "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\
259
+ "will be deleted automatically with GC. It's also recommended to delete the temp file "\
260
+ "explicitly with `tempfile.delete`"
261
+ tempfile
262
+ end
263
+
264
+ # Sanitize filename by removing path.
265
+ # e.g. ../../sun.gif becomes sun.gif
266
+ #
267
+ # @param [String] filename the filename to be sanitized
268
+ # @return [String] the sanitized filename
269
+ def sanitize_filename(filename)
270
+ filename.gsub(/.*[\/\\]/, '')
271
+ end
272
+
273
+ def build_request_url(path)
274
+ # Add leading and trailing slashes to path
275
+ path = "/#{path}".gsub(/\/+/, '/')
276
+ URI.encode(@config.base_url + path)
277
+ end
278
+
279
+ # Builds the HTTP request body
280
+ #
281
+ # @param [Hash] header_params Header parameters
282
+ # @param [Hash] form_params Query parameters
283
+ # @param [Object] body HTTP body (JSON/XML)
284
+ # @return [String] HTTP body data in the form of string
285
+ def build_request_body(header_params, form_params, body)
286
+ # http form
287
+ if header_params['Content-Type'] == 'application/x-www-form-urlencoded' ||
288
+ header_params['Content-Type'] == 'multipart/form-data'
289
+ data = {}
290
+ form_params.each do |key, value|
291
+ case value
292
+ when File, Array, nil
293
+ # let typhoeus handle File, Array and nil parameters
294
+ data[key] = value
295
+ else
296
+ data[key] = value.to_s
297
+ end
298
+ end
299
+ elsif body
300
+ data = body.is_a?(String) ? body : body.to_json
301
+ else
302
+ data = nil
303
+ end
304
+ data
305
+ end
306
+
307
+ # Update hearder and query params based on authentication settings.
308
+ #
309
+ # @param [Hash] header_params Header parameters
310
+ # @param [Hash] query_params Query parameters
311
+ # @param [String] auth_names Authentication scheme name
312
+ def update_params_for_auth!(header_params, query_params, auth_names)
313
+ Array(auth_names).each do |auth_name|
314
+ auth_setting = @config.auth_settings[auth_name]
315
+ next unless auth_setting
316
+ case auth_setting[:in]
317
+ when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
318
+ when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
319
+ else fail ArgumentError, 'Authentication token must be in `query` of `header`'
320
+ end
321
+ end
322
+ end
323
+
324
+ # Sets user agent in HTTP header
325
+ #
326
+ # @param [String] user_agent User agent (e.g. swagger-codegen/ruby/1.0.0)
327
+ def user_agent=(user_agent)
328
+ @user_agent = user_agent
329
+ @default_headers['User-Agent'] = @user_agent
330
+ end
331
+
332
+ # Return Accept header based on an array of accepts provided.
333
+ # @param [Array] accepts array for Accept
334
+ # @return [String] the Accept header (e.g. application/json)
335
+ def select_header_accept(accepts)
336
+ return nil if accepts.nil? || accepts.empty?
337
+ # use JSON when present, otherwise use all of the provided
338
+ json_accept = accepts.find { |s| json_mime?(s) }
339
+ return json_accept || accepts.join(',')
340
+ end
341
+
342
+ # Return Content-Type header based on an array of content types provided.
343
+ # @param [Array] content_types array for Content-Type
344
+ # @return [String] the Content-Type header (e.g. application/json)
345
+ def select_header_content_type(content_types)
346
+ # use application/json by default
347
+ return 'application/json' if content_types.nil? || content_types.empty?
348
+ # use JSON when present, otherwise use the first one
349
+ json_content_type = content_types.find { |s| json_mime?(s) }
350
+ return json_content_type || content_types.first
351
+ end
352
+
353
+ # Convert object (array, hash, object, etc) to JSON string.
354
+ # @param [Object] model object to be converted into JSON string
355
+ # @return [String] JSON string representation of the object
356
+ def self.object_to_json(model)
357
+ return model if model.nil? || model.is_a?(String)
358
+ local_body = nil
359
+ if model.is_a?(Array)
360
+ local_body = model.map{|m| self.object_to_hash(m) }
361
+ else
362
+ local_body = self.object_to_hash(model)
363
+ end
364
+ local_body.to_json
365
+ end
366
+
367
+ # Convert object(non-array) to hash.
368
+ # @param [Object] obj object to be converted into JSON string
369
+ # @return [String] JSON string representation of the object
370
+ def self.object_to_hash(obj)
371
+ if obj.respond_to?(:to_hash)
372
+ obj.to_hash
373
+ else
374
+ obj
375
+ end
376
+ end
377
+
378
+ # Build parameter value according to the given collection format.
379
+ # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
380
+ def build_collection_param(param, collection_format)
381
+ case collection_format
382
+ when :csv
383
+ param.join(',')
384
+ when :ssv
385
+ param.join(' ')
386
+ when :tsv
387
+ param.join("\t")
388
+ when :pipes
389
+ param.join('|')
390
+ when :multi
391
+ # return the array directly as typhoeus will handle it as expected
392
+ param
393
+ else
394
+ fail "unknown collection format: #{collection_format.inspect}"
395
+ end
396
+ end
397
+ end
398
+ end
@@ -0,0 +1,26 @@
1
+ module MParticle
2
+ class ApiError < StandardError
3
+ attr_reader :code, :response_headers, :response_body
4
+
5
+ # Usage examples:
6
+ # ApiError.new
7
+ # ApiError.new("message")
8
+ # ApiError.new(:code => 500, :response_headers => {}, :response_body => "")
9
+ # ApiError.new(:code => 404, :message => "Not Found")
10
+ def initialize(arg = nil)
11
+ if arg.is_a? Hash
12
+ if arg.key?(:message) || arg.key?('message')
13
+ super(arg[:message] || arg['message'])
14
+ else
15
+ super arg
16
+ end
17
+
18
+ arg.each do |k, v|
19
+ instance_variable_set "@#{k}", v
20
+ end
21
+ else
22
+ super arg
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,160 @@
1
+ require 'uri'
2
+
3
+ module MParticle
4
+ class Configuration
5
+ # Defines url scheme
6
+ attr_accessor :scheme
7
+
8
+ # Defines url host
9
+ attr_accessor :host
10
+
11
+ # Defines url base path
12
+ attr_accessor :base_path
13
+
14
+ # Sets the mParticle API key
15
+ #
16
+ # @return [String]
17
+ attr_accessor :api_key
18
+
19
+ # Sets the mParticle API secret
20
+ #
21
+ # @return [String]
22
+ attr_accessor :api_secret
23
+
24
+ # Set this to enable/disable debugging. When enabled (set to true), HTTP request/response
25
+ # details will be logged with `logger.debug` (see the `logger` attribute).
26
+ # Default to false.
27
+ #
28
+ # @return [true, false]
29
+ attr_accessor :debugging
30
+
31
+ # Defines the logger used for debugging.
32
+ # Default to `Rails.logger` (when in Rails) or logging to STDOUT.
33
+ #
34
+ # @return [#debug]
35
+ attr_accessor :logger
36
+
37
+ # Defines the temporary folder to store downloaded files
38
+ # (for API endpoints that have file response).
39
+ # Default to use `Tempfile`.
40
+ #
41
+ # @return [String]
42
+ attr_accessor :temp_folder_path
43
+
44
+ # The time limit for HTTP request in seconds.
45
+ # Default to 0 (never times out).
46
+ attr_accessor :timeout
47
+
48
+ ### TLS/SSL setting
49
+ # Set this to false to skip verifying SSL certificate when calling API from https server.
50
+ # Default to true.
51
+ #
52
+ # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
53
+ #
54
+ # @return [true, false]
55
+ attr_accessor :verify_ssl
56
+
57
+ ### TLS/SSL setting
58
+ # Set this to false to skip verifying SSL host name
59
+ # Default to true.
60
+ #
61
+ # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
62
+ #
63
+ # @return [true, false]
64
+ attr_accessor :verify_ssl_host
65
+
66
+ ### TLS/SSL setting
67
+ # Set this to customize the certificate file to verify the peer.
68
+ #
69
+ # @return [String] the path to the certificate file
70
+ #
71
+ # @see The `cainfo` option of Typhoeus, `--cert` option of libcurl. Related source code:
72
+ # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145
73
+ attr_accessor :ssl_ca_cert
74
+
75
+ ### TLS/SSL setting
76
+ # Client certificate file (for client certificate)
77
+ attr_accessor :cert_file
78
+
79
+ ### TLS/SSL setting
80
+ # Client private key file (for client certificate)
81
+ attr_accessor :key_file
82
+
83
+ # Set this to customize parameters encoding of array parameter with multi collectionFormat.
84
+ # Default to nil.
85
+ #
86
+ # @see The params_encoding option of Ethon. Related source code:
87
+ # https://github.com/typhoeus/ethon/blob/master/lib/ethon/easy/queryable.rb#L96
88
+ attr_accessor :params_encoding
89
+
90
+ attr_accessor :inject_format
91
+
92
+ attr_accessor :force_ending_format
93
+
94
+ def initialize
95
+ @scheme = 'https'
96
+ @host = 's2s.mparticle.com'
97
+ @base_path = '/v2'
98
+ @timeout = 0
99
+ @verify_ssl = true
100
+ @verify_ssl_host = true
101
+ @params_encoding = nil
102
+ @cert_file = nil
103
+ @key_file = nil
104
+ @debugging = false
105
+ @inject_format = false
106
+ @force_ending_format = false
107
+ @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
108
+
109
+ yield(self) if block_given?
110
+ end
111
+
112
+ # The default Configuration object.
113
+ def self.default
114
+ @@default ||= Configuration.new
115
+ end
116
+
117
+ def configure
118
+ yield(self) if block_given?
119
+ end
120
+
121
+ def scheme=(scheme)
122
+ # remove :// from scheme
123
+ @scheme = scheme.sub(/:\/\//, '')
124
+ end
125
+
126
+ def host=(host)
127
+ # remove http(s):// and anything after a slash
128
+ @host = host.sub(/https?:\/\//, '').split('/').first
129
+ end
130
+
131
+ def base_path=(base_path)
132
+ # Add leading and trailing slashes to base_path
133
+ @base_path = "/#{base_path}".gsub(/\/+/, '/')
134
+ @base_path = "" if @base_path == "/"
135
+ end
136
+
137
+ def base_url
138
+ url = "#{scheme}://#{[host, base_path].join('/').gsub(/\/+/, '/')}".sub(/\/+\z/, '')
139
+ URI.encode(url)
140
+ end
141
+
142
+ # Gets Basic Auth token string
143
+ def basic_auth_token
144
+ 'Basic ' + ["#{api_key}:#{api_secret}"].pack('m').delete("\r\n")
145
+ end
146
+
147
+ # Returns Auth Settings hash for api client.
148
+ def auth_settings
149
+ {
150
+ 'basic' =>
151
+ {
152
+ type: 'basic',
153
+ in: 'header',
154
+ key: 'Authorization',
155
+ value: basic_auth_token
156
+ },
157
+ }
158
+ end
159
+ end
160
+ end