flow-reference 0.2.85

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1104 @@
1
+ # Generated by apidoc - http://www.apidoc.me
2
+ # Service version: 0.2.83
3
+ # apidoc:0.11.76 http://www.apidoc.me/flow/reference/0.2.83/ruby_client
4
+
5
+ require 'cgi'
6
+ require 'net/http'
7
+ require 'net/https'
8
+ require 'uri'
9
+ require 'base64'
10
+
11
+ require 'date'
12
+ require 'rubygems'
13
+ require 'json'
14
+ require 'bigdecimal'
15
+
16
+ # Reference data that changes infrequently including countries, currencies,
17
+ # languages, etc.
18
+ module Io
19
+ module Flow
20
+ module Reference
21
+ module V0
22
+
23
+ class Client
24
+
25
+ module Constants
26
+
27
+ BASE_URL = 'https://api.flow.io/reference' unless defined?(Constants::BASE_URL)
28
+ NAMESPACE = 'io.flow.reference.v0' unless defined?(Constants::NAMESPACE)
29
+ USER_AGENT = 'apidoc:0.11.76 http://www.apidoc.me/flow/reference/0.2.83/ruby_client' unless defined?(Constants::USER_AGENT)
30
+ VERSION = '0.2.85' unless defined?(Constants::VERSION)
31
+ VERSION_MAJOR = 0 unless defined?(VERSION_MAJOR)
32
+
33
+ end
34
+
35
+ attr_reader :url
36
+
37
+ def initialize(url, opts={})
38
+ @url = HttpClient::Preconditions.assert_class('url', url, String)
39
+ @base_url = URI(url)
40
+ @authorization = HttpClient::Preconditions.assert_class_or_nil('authorization', opts.delete(:authorization), HttpClient::Authorization)
41
+ @default_headers = HttpClient::Preconditions.assert_class('default_headers', opts.delete(:default_headers) || {}, Hash)
42
+ @http_handler = opts.delete(:http_handler) || HttpClient::DefaultHttpHandler.new
43
+
44
+ HttpClient::Preconditions.assert_empty_opts(opts)
45
+ HttpClient::Preconditions.check_state(url.match(/http.+/i), "URL[%s] must start with http" % url)
46
+ end
47
+
48
+ # Creates an instance of the client using the base url specified in the API spec.
49
+ def Client.at_base_url(opts={})
50
+ Client.new(Constants::BASE_URL, opts)
51
+ end
52
+
53
+ def request(path=nil)
54
+ HttpClient::Preconditions.assert_class_or_nil('path', path, String)
55
+ request = HttpClient::Request.new(@http_handler, @base_url, path.to_s).with_header('User-Agent', Constants::USER_AGENT).with_header('X-Apidoc-Version', Constants::VERSION).with_header('X-Apidoc-Version-Major', Constants::VERSION_MAJOR)
56
+
57
+ @default_headers.each do |key, value|
58
+ request = request.with_header(key, value)
59
+ end
60
+
61
+ if @authorization
62
+ request = request.with_auth(@authorization)
63
+ end
64
+
65
+ request
66
+ end
67
+
68
+ def countries
69
+ @countries ||= ::Io::Flow::Reference::V0::Clients::Countries.new(self)
70
+ end
71
+
72
+ def currencies
73
+ @currencies ||= ::Io::Flow::Reference::V0::Clients::Currencies.new(self)
74
+ end
75
+
76
+ def languages
77
+ @languages ||= ::Io::Flow::Reference::V0::Clients::Languages.new(self)
78
+ end
79
+
80
+ def locales
81
+ @locales ||= ::Io::Flow::Reference::V0::Clients::Locales.new(self)
82
+ end
83
+
84
+ def regions
85
+ @regions ||= ::Io::Flow::Reference::V0::Clients::Regions.new(self)
86
+ end
87
+
88
+ def timezones
89
+ @timezones ||= ::Io::Flow::Reference::V0::Clients::Timezones.new(self)
90
+ end
91
+ end
92
+
93
+ module Clients
94
+
95
+ class Countries
96
+
97
+ def initialize(client)
98
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
99
+ end
100
+
101
+ # Returns a list of countries.
102
+ def get(incoming={})
103
+ opts = HttpClient::Helper.symbolize_keys(incoming)
104
+ query = {
105
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
106
+ }.delete_if { |k, v| v.nil? }
107
+ r = @client.request("/reference/countries").with_query(query).get
108
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Country.new(x) }
109
+ end
110
+
111
+ end
112
+
113
+ class Currencies
114
+
115
+ def initialize(client)
116
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
117
+ end
118
+
119
+ # Returns a list of currencies.
120
+ def get(incoming={})
121
+ opts = HttpClient::Helper.symbolize_keys(incoming)
122
+ query = {
123
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
124
+ }.delete_if { |k, v| v.nil? }
125
+ r = @client.request("/reference/currencies").with_query(query).get
126
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Currency.new(x) }
127
+ end
128
+
129
+ end
130
+
131
+ class Languages
132
+
133
+ def initialize(client)
134
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
135
+ end
136
+
137
+ # Returns a list of languages.
138
+ def get(incoming={})
139
+ opts = HttpClient::Helper.symbolize_keys(incoming)
140
+ query = {
141
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
142
+ }.delete_if { |k, v| v.nil? }
143
+ r = @client.request("/reference/languages").with_query(query).get
144
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Language.new(x) }
145
+ end
146
+
147
+ end
148
+
149
+ class Locales
150
+
151
+ def initialize(client)
152
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
153
+ end
154
+
155
+ # Returns a list of locales.
156
+ def get(incoming={})
157
+ opts = HttpClient::Helper.symbolize_keys(incoming)
158
+ query = {
159
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
160
+ }.delete_if { |k, v| v.nil? }
161
+ r = @client.request("/reference/locales").with_query(query).get
162
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Locale.new(x) }
163
+ end
164
+
165
+ # Returns the locale with the specifed id.
166
+ def get_by_id(id)
167
+ HttpClient::Preconditions.assert_class('id', id, String)
168
+ r = @client.request("/reference/locales/#{CGI.escape(id)}").get
169
+ ::Io::Flow::Reference::V0::Models::Locale.new(r)
170
+ end
171
+
172
+ end
173
+
174
+ class Regions
175
+
176
+ def initialize(client)
177
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
178
+ end
179
+
180
+ # Returns a list of regions.
181
+ def get(incoming={})
182
+ opts = HttpClient::Helper.symbolize_keys(incoming)
183
+ query = {
184
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
185
+ }.delete_if { |k, v| v.nil? }
186
+ r = @client.request("/reference/regions").with_query(query).get
187
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Region.new(x) }
188
+ end
189
+
190
+ # Returns the region with the specifed id.
191
+ def get_by_id(id)
192
+ HttpClient::Preconditions.assert_class('id', id, String)
193
+ r = @client.request("/reference/regions/#{CGI.escape(id)}").get
194
+ ::Io::Flow::Reference::V0::Models::Region.new(r)
195
+ end
196
+
197
+ end
198
+
199
+ class Timezones
200
+
201
+ def initialize(client)
202
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
203
+ end
204
+
205
+ # Returns a list of timezones.
206
+ def get(incoming={})
207
+ opts = HttpClient::Helper.symbolize_keys(incoming)
208
+ query = {
209
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
210
+ }.delete_if { |k, v| v.nil? }
211
+ r = @client.request("/reference/timezones").with_query(query).get
212
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Timezone.new(x) }
213
+ end
214
+
215
+ end
216
+
217
+ end
218
+
219
+ module Models
220
+
221
+ class PaymentMethodType
222
+
223
+ attr_reader :value
224
+
225
+ def initialize(value)
226
+ @value = HttpClient::Preconditions.assert_class('value', value, String)
227
+ end
228
+
229
+ # Returns the instance of PaymentMethodType for this value, creating a new instance for an unknown value
230
+ def PaymentMethodType.apply(value)
231
+ if value.instance_of?(PaymentMethodType)
232
+ value
233
+ else
234
+ HttpClient::Preconditions.assert_class_or_nil('value', value, String)
235
+ value.nil? ? nil : (from_string(value) || PaymentMethodType.new(value))
236
+ end
237
+ end
238
+
239
+ # Returns the instance of PaymentMethodType for this value, or nil if not found
240
+ def PaymentMethodType.from_string(value)
241
+ HttpClient::Preconditions.assert_class('value', value, String)
242
+ PaymentMethodType.ALL.find { |v| v.value == value }
243
+ end
244
+
245
+ def PaymentMethodType.ALL
246
+ @@all ||= [PaymentMethodType.card, PaymentMethodType.online, PaymentMethodType.offline]
247
+ end
248
+
249
+ # Represents all form of card payment (e.g. credit, debit, etc.)
250
+ def PaymentMethodType.card
251
+ @@_card ||= PaymentMethodType.new('card')
252
+ end
253
+
254
+ # Represents the most common form of alternative payment methods which require
255
+ # some degree of integration online (e.g. a redirect) to complete payment.
256
+ def PaymentMethodType.online
257
+ @@_online ||= PaymentMethodType.new('online')
258
+ end
259
+
260
+ # Offline payment method types represent payments like Cash On Delivery which
261
+ # require offline collection
262
+ def PaymentMethodType.offline
263
+ @@_offline ||= PaymentMethodType.new('offline')
264
+ end
265
+
266
+ def to_hash
267
+ value
268
+ end
269
+
270
+ end
271
+
272
+ # ISO 3166 country codes. Note Flow APIs will accept either the 2 or 3 character
273
+ # country code, but internally we normalize data and store as the 3 character,
274
+ # upper case ISO code. See https://api.flow.io/reference/countries
275
+ class Country
276
+
277
+ attr_reader :name, :iso_3166_2, :iso_3166_3, :languages, :measurement_system, :default_currency, :timezones, :default_delivered_duty
278
+
279
+ def initialize(incoming={})
280
+ opts = HttpClient::Helper.symbolize_keys(incoming)
281
+ HttpClient::Preconditions.require_keys(opts, [:name, :iso_3166_2, :iso_3166_3, :languages, :measurement_system, :timezones], 'Country')
282
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
283
+ @iso_3166_2 = HttpClient::Preconditions.assert_class('iso_3166_2', opts.delete(:iso_3166_2), String)
284
+ @iso_3166_3 = HttpClient::Preconditions.assert_class('iso_3166_3', opts.delete(:iso_3166_3), String)
285
+ @languages = HttpClient::Preconditions.assert_class('languages', opts.delete(:languages), Array).map { |v| HttpClient::Preconditions.assert_class('languages', v, String) }
286
+ @measurement_system = HttpClient::Preconditions.assert_class('measurement_system', opts.delete(:measurement_system), String)
287
+ @default_currency = (x = opts.delete(:default_currency); x.nil? ? nil : HttpClient::Preconditions.assert_class('default_currency', x, String))
288
+ @timezones = HttpClient::Preconditions.assert_class('timezones', opts.delete(:timezones), Array).map { |v| HttpClient::Preconditions.assert_class('timezones', v, String) }
289
+ @default_delivered_duty = (x = opts.delete(:default_delivered_duty); x.nil? ? nil : HttpClient::Preconditions.assert_class('default_delivered_duty', x, String))
290
+ end
291
+
292
+ def to_json
293
+ JSON.dump(to_hash)
294
+ end
295
+
296
+ def copy(incoming={})
297
+ Country.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
298
+ end
299
+
300
+ def to_hash
301
+ {
302
+ :name => name,
303
+ :iso_3166_2 => iso_3166_2,
304
+ :iso_3166_3 => iso_3166_3,
305
+ :languages => languages,
306
+ :measurement_system => measurement_system,
307
+ :default_currency => default_currency,
308
+ :timezones => timezones,
309
+ :default_delivered_duty => default_delivered_duty
310
+ }
311
+ end
312
+
313
+ end
314
+
315
+ # ISO 4217 3-character currency code. See
316
+ # https://api.flow.io/reference/currencies
317
+ class Currency
318
+
319
+ attr_reader :name, :iso_4217_3, :number_decimals, :symbols, :default_locale
320
+
321
+ def initialize(incoming={})
322
+ opts = HttpClient::Helper.symbolize_keys(incoming)
323
+ HttpClient::Preconditions.require_keys(opts, [:name, :iso_4217_3, :number_decimals], 'Currency')
324
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
325
+ @iso_4217_3 = HttpClient::Preconditions.assert_class('iso_4217_3', opts.delete(:iso_4217_3), String)
326
+ @number_decimals = HttpClient::Preconditions.assert_class('number_decimals', opts.delete(:number_decimals), Integer)
327
+ @symbols = (x = opts.delete(:symbols); x.nil? ? nil : (x = x; x.is_a?(::Io::Flow::Reference::V0::Models::CurrencySymbols) ? x : ::Io::Flow::Reference::V0::Models::CurrencySymbols.new(x)))
328
+ @default_locale = (x = opts.delete(:default_locale); x.nil? ? nil : HttpClient::Preconditions.assert_class('default_locale', x, String))
329
+ end
330
+
331
+ def to_json
332
+ JSON.dump(to_hash)
333
+ end
334
+
335
+ def copy(incoming={})
336
+ Currency.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
337
+ end
338
+
339
+ def to_hash
340
+ {
341
+ :name => name,
342
+ :iso_4217_3 => iso_4217_3,
343
+ :number_decimals => number_decimals,
344
+ :symbols => symbols.nil? ? nil : symbols.to_hash,
345
+ :default_locale => default_locale
346
+ }
347
+ end
348
+
349
+ end
350
+
351
+ # Defines one or more symbols representing this currency
352
+ class CurrencySymbols
353
+
354
+ attr_reader :primary, :narrow
355
+
356
+ def initialize(incoming={})
357
+ opts = HttpClient::Helper.symbolize_keys(incoming)
358
+ HttpClient::Preconditions.require_keys(opts, [:primary], 'CurrencySymbols')
359
+ @primary = HttpClient::Preconditions.assert_class('primary', opts.delete(:primary), String)
360
+ @narrow = (x = opts.delete(:narrow); x.nil? ? nil : HttpClient::Preconditions.assert_class('narrow', x, String))
361
+ end
362
+
363
+ def to_json
364
+ JSON.dump(to_hash)
365
+ end
366
+
367
+ def copy(incoming={})
368
+ CurrencySymbols.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
369
+ end
370
+
371
+ def to_hash
372
+ {
373
+ :primary => primary,
374
+ :narrow => narrow
375
+ }
376
+ end
377
+
378
+ end
379
+
380
+ # ISO 639 2-character language code. See https://api.flow.io/reference/languages
381
+ class Language
382
+
383
+ attr_reader :name, :iso_639_2
384
+
385
+ def initialize(incoming={})
386
+ opts = HttpClient::Helper.symbolize_keys(incoming)
387
+ HttpClient::Preconditions.require_keys(opts, [:name, :iso_639_2], 'Language')
388
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
389
+ @iso_639_2 = HttpClient::Preconditions.assert_class('iso_639_2', opts.delete(:iso_639_2), String)
390
+ end
391
+
392
+ def to_json
393
+ JSON.dump(to_hash)
394
+ end
395
+
396
+ def copy(incoming={})
397
+ Language.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
398
+ end
399
+
400
+ def to_hash
401
+ {
402
+ :name => name,
403
+ :iso_639_2 => iso_639_2
404
+ }
405
+ end
406
+
407
+ end
408
+
409
+ # Locales defines standard conventions for presentation of content. See
410
+ # https://api.flow.io/reference/locales
411
+ class Locale
412
+
413
+ attr_reader :id, :name, :country, :language, :numbers
414
+
415
+ def initialize(incoming={})
416
+ opts = HttpClient::Helper.symbolize_keys(incoming)
417
+ HttpClient::Preconditions.require_keys(opts, [:id, :name, :country, :language, :numbers], 'Locale')
418
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
419
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
420
+ @country = HttpClient::Preconditions.assert_class('country', opts.delete(:country), String)
421
+ @language = HttpClient::Preconditions.assert_class('language', opts.delete(:language), String)
422
+ @numbers = (x = opts.delete(:numbers); x.is_a?(::Io::Flow::Reference::V0::Models::LocaleNumbers) ? x : ::Io::Flow::Reference::V0::Models::LocaleNumbers.new(x))
423
+ end
424
+
425
+ def to_json
426
+ JSON.dump(to_hash)
427
+ end
428
+
429
+ def copy(incoming={})
430
+ Locale.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
431
+ end
432
+
433
+ def to_hash
434
+ {
435
+ :id => id,
436
+ :name => name,
437
+ :country => country,
438
+ :language => language,
439
+ :numbers => numbers.to_hash
440
+ }
441
+ end
442
+
443
+ end
444
+
445
+ # Number formats defined for a given locale
446
+ class LocaleNumbers
447
+
448
+ attr_reader :decimal, :group
449
+
450
+ def initialize(incoming={})
451
+ opts = HttpClient::Helper.symbolize_keys(incoming)
452
+ HttpClient::Preconditions.require_keys(opts, [:decimal, :group], 'LocaleNumbers')
453
+ @decimal = HttpClient::Preconditions.assert_class('decimal', opts.delete(:decimal), String)
454
+ @group = HttpClient::Preconditions.assert_class('group', opts.delete(:group), String)
455
+ end
456
+
457
+ def to_json
458
+ JSON.dump(to_hash)
459
+ end
460
+
461
+ def copy(incoming={})
462
+ LocaleNumbers.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
463
+ end
464
+
465
+ def to_hash
466
+ {
467
+ :decimal => decimal,
468
+ :group => group
469
+ }
470
+ end
471
+
472
+ end
473
+
474
+ # Represents a single payment method - e.g VISA or Paypal - and any associated
475
+ # metadata required for processing
476
+ class PaymentMethod
477
+
478
+ attr_reader :id, :type, :name, :images, :regions
479
+
480
+ def initialize(incoming={})
481
+ opts = HttpClient::Helper.symbolize_keys(incoming)
482
+ HttpClient::Preconditions.require_keys(opts, [:id, :type, :name, :images, :regions], 'PaymentMethod')
483
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
484
+ @type = (x = opts.delete(:type); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodType) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodType.apply(x))
485
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
486
+ @images = (x = opts.delete(:images); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImages) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImages.new(x))
487
+ @regions = HttpClient::Preconditions.assert_class('regions', opts.delete(:regions), Array).map { |v| HttpClient::Preconditions.assert_class('regions', v, String) }
488
+ end
489
+
490
+ def to_json
491
+ JSON.dump(to_hash)
492
+ end
493
+
494
+ def copy(incoming={})
495
+ PaymentMethod.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
496
+ end
497
+
498
+ def to_hash
499
+ {
500
+ :id => id,
501
+ :type => type.value,
502
+ :name => name,
503
+ :images => images.to_hash,
504
+ :regions => regions
505
+ }
506
+ end
507
+
508
+ end
509
+
510
+ class PaymentMethodImage
511
+
512
+ attr_reader :url, :width, :height
513
+
514
+ def initialize(incoming={})
515
+ opts = HttpClient::Helper.symbolize_keys(incoming)
516
+ HttpClient::Preconditions.require_keys(opts, [:url, :width, :height], 'PaymentMethodImage')
517
+ @url = HttpClient::Preconditions.assert_class('url', opts.delete(:url), String)
518
+ @width = HttpClient::Preconditions.assert_class('width', opts.delete(:width), Integer)
519
+ @height = HttpClient::Preconditions.assert_class('height', opts.delete(:height), Integer)
520
+ end
521
+
522
+ def to_json
523
+ JSON.dump(to_hash)
524
+ end
525
+
526
+ def copy(incoming={})
527
+ PaymentMethodImage.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
528
+ end
529
+
530
+ def to_hash
531
+ {
532
+ :url => url,
533
+ :width => width,
534
+ :height => height
535
+ }
536
+ end
537
+
538
+ end
539
+
540
+ class PaymentMethodImages
541
+
542
+ attr_reader :small, :medium, :large
543
+
544
+ def initialize(incoming={})
545
+ opts = HttpClient::Helper.symbolize_keys(incoming)
546
+ HttpClient::Preconditions.require_keys(opts, [:small, :medium, :large], 'PaymentMethodImages')
547
+ @small = (x = opts.delete(:small); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImage) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImage.new(x))
548
+ @medium = (x = opts.delete(:medium); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImage) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImage.new(x))
549
+ @large = (x = opts.delete(:large); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImage) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImage.new(x))
550
+ end
551
+
552
+ def to_json
553
+ JSON.dump(to_hash)
554
+ end
555
+
556
+ def copy(incoming={})
557
+ PaymentMethodImages.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
558
+ end
559
+
560
+ def to_hash
561
+ {
562
+ :small => small.to_hash,
563
+ :medium => medium.to_hash,
564
+ :large => large.to_hash
565
+ }
566
+ end
567
+
568
+ end
569
+
570
+ # A region represents a geographic area of the world. Regions can be countries,
571
+ # continents or other political areas (like the Eurozone). See
572
+ # https://api.flow.io/reference/regions
573
+ class Region
574
+
575
+ attr_reader :id, :name, :countries, :currencies, :languages, :measurement_systems, :timezones
576
+
577
+ def initialize(incoming={})
578
+ opts = HttpClient::Helper.symbolize_keys(incoming)
579
+ HttpClient::Preconditions.require_keys(opts, [:id, :name, :countries, :currencies, :languages, :measurement_systems, :timezones], 'Region')
580
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
581
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
582
+ @countries = HttpClient::Preconditions.assert_class('countries', opts.delete(:countries), Array).map { |v| HttpClient::Preconditions.assert_class('countries', v, String) }
583
+ @currencies = HttpClient::Preconditions.assert_class('currencies', opts.delete(:currencies), Array).map { |v| HttpClient::Preconditions.assert_class('currencies', v, String) }
584
+ @languages = HttpClient::Preconditions.assert_class('languages', opts.delete(:languages), Array).map { |v| HttpClient::Preconditions.assert_class('languages', v, String) }
585
+ @measurement_systems = HttpClient::Preconditions.assert_class('measurement_systems', opts.delete(:measurement_systems), Array).map { |v| HttpClient::Preconditions.assert_class('measurement_systems', v, String) }
586
+ @timezones = HttpClient::Preconditions.assert_class('timezones', opts.delete(:timezones), Array).map { |v| HttpClient::Preconditions.assert_class('timezones', v, String) }
587
+ end
588
+
589
+ def to_json
590
+ JSON.dump(to_hash)
591
+ end
592
+
593
+ def copy(incoming={})
594
+ Region.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
595
+ end
596
+
597
+ def to_hash
598
+ {
599
+ :id => id,
600
+ :name => name,
601
+ :countries => countries,
602
+ :currencies => currencies,
603
+ :languages => languages,
604
+ :measurement_systems => measurement_systems,
605
+ :timezones => timezones
606
+ }
607
+ end
608
+
609
+ end
610
+
611
+ # Time zone data is provided by the public IANA time zone database. See
612
+ # http://www.iana.org/time-zones
613
+ class Timezone
614
+
615
+ attr_reader :name, :description, :offset
616
+
617
+ def initialize(incoming={})
618
+ opts = HttpClient::Helper.symbolize_keys(incoming)
619
+ HttpClient::Preconditions.require_keys(opts, [:name, :description, :offset], 'Timezone')
620
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
621
+ @description = HttpClient::Preconditions.assert_class('description', opts.delete(:description), String)
622
+ @offset = HttpClient::Preconditions.assert_class('offset', opts.delete(:offset), Integer)
623
+ end
624
+
625
+ def to_json
626
+ JSON.dump(to_hash)
627
+ end
628
+
629
+ def copy(incoming={})
630
+ Timezone.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
631
+ end
632
+
633
+ def to_hash
634
+ {
635
+ :name => name,
636
+ :description => description,
637
+ :offset => offset
638
+ }
639
+ end
640
+
641
+ end
642
+
643
+ end
644
+
645
+ # ===== END OF SERVICE DEFINITION =====
646
+ module HttpClient
647
+
648
+ class HttpHandler
649
+
650
+ # Returns a client instance to use
651
+ #
652
+ # @param base_uri The base URI for this API
653
+ # @param path the Requested full http path (including any query strings)
654
+ def instance(base_uri, path)
655
+ raise "Override in subclass"
656
+ end
657
+
658
+ end
659
+
660
+ class HttpHandlerInstance
661
+
662
+ # Executes a request. The provided request object will be an
663
+ # instance of Net::HTTP (e.g. Net::HTTP::Get)
664
+ def execute(request)
665
+ raise "Override in subclass"
666
+ end
667
+
668
+ end
669
+
670
+ class DefaultHttpHandler < HttpHandler
671
+
672
+ def instance(base_uri, path)
673
+ DefaultHttpHandlerInstance.new(base_uri)
674
+ end
675
+
676
+ end
677
+
678
+ class DefaultHttpHandlerInstance < HttpHandlerInstance
679
+
680
+ attr_reader :client
681
+
682
+ def initialize(base_uri)
683
+ @base_uri = Preconditions.assert_class('base_uri', base_uri, URI)
684
+ @client = Net::HTTP.new(@base_uri.host, @base_uri.port)
685
+ if @base_uri.scheme == "https"
686
+ configure_ssl
687
+ end
688
+ end
689
+
690
+ def execute(request)
691
+ response = begin
692
+ @client.request(request)
693
+ rescue SocketError => e
694
+ raise Exception.new("Error accessing uri[#{full_uri(request.path)}]: #{e}")
695
+ end
696
+
697
+ case response
698
+ when Net::HTTPSuccess
699
+ response.body
700
+ else
701
+ body = response.body rescue nil
702
+ raise HttpClient::ServerError.new(response.code.to_i, response.message, :body => body, :uri => full_uri(request.path).to_s)
703
+ end
704
+ end
705
+
706
+ def full_uri(path)
707
+ File.join(@base_uri.to_s, path)
708
+ end
709
+
710
+ # Called to configure SSL if the base uri requires it
711
+ def configure_ssl
712
+ @client.use_ssl = true
713
+ @client.verify_mode = OpenSSL::SSL::VERIFY_PEER
714
+ @client.cert_store = OpenSSL::X509::Store.new
715
+ @client.cert_store.set_default_paths
716
+ end
717
+
718
+ end
719
+
720
+ class Request
721
+
722
+ attr_reader :path
723
+
724
+ def initialize(http_handler, base_uri, path)
725
+ @http_handler = http_handler
726
+ @base_uri = Preconditions.assert_class('base_uri', base_uri, URI)
727
+ @path = Preconditions.assert_class('path', path, String)
728
+ @params = nil
729
+ @body = nil
730
+ @auth = nil
731
+ @headers = {}
732
+ @header_keys_lower_case = []
733
+ end
734
+
735
+ def with_header(name, value)
736
+ Preconditions.check_not_blank('name', name, "Header name is required")
737
+ Preconditions.check_not_blank('value', value, "Header value is required")
738
+ Preconditions.check_state(!@headers.has_key?(name),
739
+ "Duplicate header named[%s]" % name)
740
+ @headers[name] = value
741
+ @header_keys_lower_case << name.downcase
742
+ self
743
+ end
744
+
745
+ def with_auth(auth)
746
+ Preconditions.assert_class('auth', auth, HttpClient::Authorization)
747
+ Preconditions.check_state(@auth.nil?, "auth previously set")
748
+
749
+ if auth.scheme.name == AuthScheme::BASIC.name
750
+ @auth = auth
751
+ else
752
+ raise "Auth Scheme[#{auth.scheme.name}] not supported"
753
+ end
754
+ self
755
+ end
756
+
757
+ def with_query(params)
758
+ Preconditions.assert_class('params', params, Hash)
759
+ Preconditions.check_state(@params.nil?, "Already have query parameters")
760
+ @params = params
761
+ self
762
+ end
763
+
764
+ # Wrapper to set Content-Type header to application/json and set
765
+ # the provided json document as the body
766
+ def with_json(json)
767
+ @headers['Content-Type'] ||= 'application/json; charset=UTF-8'
768
+ with_body(json)
769
+ end
770
+
771
+ def with_body(body)
772
+ Preconditions.check_not_blank('body', body)
773
+ @body = body
774
+ self
775
+ end
776
+
777
+ def get(&block)
778
+ do_request(Net::HTTP::Get, &block)
779
+ end
780
+
781
+ def delete(&block)
782
+ do_request(Net::HTTP::Delete, &block)
783
+ end
784
+
785
+ def options(&block)
786
+ do_request(Net::HTTP::Options, &block)
787
+ end
788
+
789
+ def post(&block)
790
+ do_request(Net::HTTP::Post, &block)
791
+ end
792
+
793
+ def put(&block)
794
+ do_request(Net::HTTP::Put, &block)
795
+ end
796
+
797
+ class PATCH < Net::HTTP::Put
798
+ METHOD = "PATCH"
799
+ end
800
+
801
+ def patch(&block)
802
+ do_request(PATCH, &block)
803
+ end
804
+
805
+ def do_request(klass)
806
+ Preconditions.assert_class('klass', klass, Class)
807
+
808
+ uri = path.dup
809
+ if q = to_query(@params)
810
+ uri += "?%s" % q
811
+ end
812
+
813
+ request = klass.send(:new, uri)
814
+
815
+ curl = ['curl']
816
+ if klass != Net::HTTP::Get
817
+ curl << "-X%s" % klass.name.split("::").last.upcase
818
+ end
819
+
820
+ if @body
821
+ # DEBUG path = "/tmp/rest_client.tmp"
822
+ # DEBUG File.open(path, "w") { |os| os << @body.to_s }
823
+ # DEBUG curl << "-d@%s" % path
824
+ request.body = @body
825
+ end
826
+
827
+ if @auth
828
+ curl << "-u \"%s:%s\"" % [@auth.username, @auth.password]
829
+ Preconditions.check_state(!@header_keys_lower_case.include?("authorization"),
830
+ "Cannot specify both an Authorization header and an auth instance")
831
+ user_pass = "%s:%s" % [@auth.username, @auth.password]
832
+ encoded = Base64.encode64(user_pass).to_s.split("\n").map(&:strip).join
833
+ request.add_field("Authorization", "Basic %s" % encoded)
834
+ end
835
+
836
+ @headers.each { |key, value|
837
+ curl << "-H \"%s: %s\"" % [key, value]
838
+ request.add_field(key, value)
839
+ }
840
+
841
+ curl << "'%s%s'" % [@base_uri, path]
842
+ # DEBUG puts curl.join(" ")
843
+
844
+ raw_response = @http_handler.instance(@base_uri, request.path).execute(request)
845
+ response = raw_response.to_s == "" ? nil : JSON.parse(raw_response)
846
+
847
+ if block_given?
848
+ yield response
849
+ else
850
+ response
851
+ end
852
+ end
853
+
854
+ private
855
+ def to_query(params={})
856
+ parts = (params || {}).map { |k,v|
857
+ if v.is_a?(Enumerable)
858
+ v.map { |el| "%s=%s" % [k, CGI.escape(el.to_s)] }
859
+ else
860
+ "%s=%s" % [k, CGI.escape(v.to_s)]
861
+ end
862
+ }
863
+ parts.empty? ? nil : parts.join("&")
864
+ end
865
+
866
+ end
867
+
868
+ class ServerError < StandardError
869
+
870
+ attr_reader :code, :details, :body, :uri
871
+
872
+ def initialize(code, details, incoming={})
873
+ opts = HttpClient::Helper.symbolize_keys(incoming)
874
+ @code = HttpClient::Preconditions.assert_class('code', code, Integer)
875
+ @details = HttpClient::Preconditions.assert_class('details', details, String)
876
+ @body = HttpClient::Preconditions.assert_class_or_nil('body', opts.delete(:body), String)
877
+ @uri = HttpClient::Preconditions.assert_class_or_nil('uri', opts.delete(:uri), String)
878
+ HttpClient::Preconditions.assert_empty_opts(opts)
879
+ super(self.message)
880
+ end
881
+
882
+ def message
883
+ m = "%s %s" % [@code, @details]
884
+ if @body
885
+ m << ": %s" % @body
886
+ end
887
+ m
888
+ end
889
+
890
+ def body_json
891
+ @body ? JSON.parse(@body) : nil
892
+ end
893
+
894
+ end
895
+
896
+ class PreconditionException < Exception
897
+
898
+ attr_reader :message
899
+
900
+ def initialize(message)
901
+ super(message)
902
+ @message = message
903
+ end
904
+
905
+ end
906
+
907
+ module Preconditions
908
+
909
+ def Preconditions.check_argument(expression, error_message=nil)
910
+ if !expression
911
+ raise PreconditionException.new(error_message || "check_argument failed")
912
+ end
913
+ nil
914
+ end
915
+
916
+ def Preconditions.check_state(expression, error_message=nil)
917
+ if !expression
918
+ raise PreconditionException.new(error_message || "check_state failed")
919
+ end
920
+ nil
921
+ end
922
+
923
+ def Preconditions.check_not_nil(field_name, reference, error_message=nil)
924
+ if reference.nil?
925
+ raise PreconditionException.new(error_message || "argument for %s cannot be nil" % field_name)
926
+ end
927
+ reference
928
+ end
929
+
930
+ def Preconditions.check_not_blank(field_name, reference, error_message=nil)
931
+ if reference.to_s.strip == ""
932
+ raise PreconditionException.new(error_message || "argument for %s cannot be blank" % field_name)
933
+ end
934
+ reference
935
+ end
936
+
937
+ # Throws an error if opts is not empty. Useful when parsing
938
+ # arguments to a function
939
+ def Preconditions.assert_empty_opts(opts)
940
+ if !opts.empty?
941
+ raise PreconditionException.new("Invalid opts: #{opts.keys.inspect}\n#{opts.inspect}")
942
+ end
943
+ end
944
+
945
+ # Requires that the provided hash has the specified keys.
946
+ # @param fields A list of symbols
947
+ def Preconditions.require_keys(hash, fields, error_prefix=nil)
948
+ missing = fields.select { |f| !hash.has_key?(f) }
949
+ if !missing.empty?
950
+ msg = "Missing required fields: " + missing.join(", ")
951
+ raise PreconditionException.new(error_prefix.empty? ? msg : "#{error_prefix}: #{msg}")
952
+ end
953
+ end
954
+
955
+ # Asserts that value is not nill and is_?(klass). Returns
956
+ # value. Common use is
957
+ #
958
+ # amount = Preconditions.assert_class('amount', amount, BigDecimal)
959
+ def Preconditions.assert_class(field_name, value, klass)
960
+ Preconditions.check_not_nil('field_name', field_name)
961
+ Preconditions.check_not_nil('klass', klass)
962
+ Preconditions.check_not_nil('value', value, "Value for %s cannot be nil. Expected an instance of class %s" % [field_name, klass.name])
963
+ Preconditions.check_state(value.is_a?(klass),
964
+ "Value for #{field_name} is of type[#{value.class}] - class[#{klass}] is required. value[#{value.inspect.to_s}]")
965
+ value
966
+ end
967
+
968
+ def Preconditions.assert_class_or_nil(field_name, value, klass)
969
+ if !value.nil?
970
+ Preconditions.assert_class(field_name, value, klass)
971
+ end
972
+ end
973
+
974
+ def Preconditions.assert_boolean(field_name, value)
975
+ Preconditions.check_not_nil('field_name', field_name)
976
+ Preconditions.check_not_nil('value', value, "Value for %s cannot be nil. Expected an instance of TrueClass or FalseClass" % field_name)
977
+ Preconditions.check_state(value.is_a?(TrueClass) || value.is_a?(FalseClass),
978
+ "Value for #{field_name} is of type[#{value.class}] - class[TrueClass or FalseClass] is required. value[#{value.inspect.to_s}]")
979
+ value
980
+ end
981
+
982
+ def Preconditions.assert_boolean_or_nil(field_name, value)
983
+ if !value.nil?
984
+ Preconditions.assert_boolean(field_name, value)
985
+ end
986
+ end
987
+
988
+ def Preconditions.assert_collection_of_class(field_name, values, klass)
989
+ Preconditions.assert_class(field_name, values, Array)
990
+ values.each { |v| Preconditions.assert_class(field_name, v, klass) }
991
+ end
992
+
993
+ def Preconditions.assert_hash_of_class(field_name, hash, klass)
994
+ Preconditions.assert_class(field_name, hash, Hash)
995
+ values.each { |k, v| Preconditions.assert_class(field_name, v, klass) }
996
+ end
997
+
998
+ end
999
+
1000
+ class AuthScheme
1001
+
1002
+ attr_reader :name
1003
+
1004
+ def initialize(name)
1005
+ @name = HttpClient::Preconditions.check_not_blank('name', name)
1006
+ end
1007
+
1008
+ BASIC = AuthScheme.new("basic") unless defined?(BASIC)
1009
+
1010
+ end
1011
+
1012
+ class Authorization
1013
+
1014
+ attr_reader :scheme, :username, :password
1015
+
1016
+ def initialize(scheme, username, opts={})
1017
+ @scheme = HttpClient::Preconditions.assert_class('schema', scheme, AuthScheme)
1018
+ @username = HttpClient::Preconditions.check_not_blank('username', username, "username is required")
1019
+ @password = HttpClient::Preconditions.assert_class_or_nil('password', opts.delete(:password), String)
1020
+ HttpClient::Preconditions.assert_empty_opts(opts)
1021
+ end
1022
+
1023
+ def Authorization.basic(username, password=nil)
1024
+ Authorization.new(AuthScheme::BASIC, username, :password => password)
1025
+ end
1026
+
1027
+ end
1028
+
1029
+ module Helper
1030
+
1031
+ def Helper.symbolize_keys(hash)
1032
+ Preconditions.assert_class('hash', hash, Hash)
1033
+ new_hash = {}
1034
+ hash.each { |k, v|
1035
+ new_hash[k.to_sym] = v
1036
+ }
1037
+ new_hash
1038
+ end
1039
+
1040
+ def Helper.to_big_decimal(value)
1041
+ value ? BigDecimal.new(value.to_s) : nil
1042
+ end
1043
+
1044
+ def Helper.to_object(value)
1045
+ value ? (value.is_a?(Hash) ? value : JSON.parse(value)) : nil
1046
+ end
1047
+
1048
+ def Helper.to_uuid(value)
1049
+ Preconditions.check_state(value.nil? || value.match(/^\w\w\w\w\w\w\w\w\-\w\w\w\w\-\w\w\w\w\-\w\w\w\w\-\w\w\w\w\w\w\w\w\w\w\w\w$/),
1050
+ "Invalid guid[%s]" % value)
1051
+ value
1052
+ end
1053
+
1054
+ def Helper.to_date_iso8601(value)
1055
+ if value.is_a?(Date)
1056
+ value
1057
+ elsif value
1058
+ Date.parse(value.to_s)
1059
+ else
1060
+ nil
1061
+ end
1062
+ end
1063
+
1064
+ def Helper.to_date_time_iso8601(value)
1065
+ if value.is_a?(DateTime)
1066
+ value
1067
+ elsif value
1068
+ DateTime.parse(value.to_s)
1069
+ else
1070
+ nil
1071
+ end
1072
+ end
1073
+
1074
+ def Helper.date_iso8601_to_string(value)
1075
+ value.nil? ? nil : value.strftime('%Y-%m-%d')
1076
+ end
1077
+
1078
+ def Helper.date_time_iso8601_to_string(value)
1079
+ value.nil? ? nil : value.strftime('%Y-%m-%dT%H:%M:%S%z')
1080
+ end
1081
+
1082
+ TRUE_STRINGS = ['t', 'true', 'y', 'yes', 'on', '1', 'trueclass'] unless defined?(TRUE_STRINGS)
1083
+ FALSE_STRINGS = ['f', 'false', 'n', 'no', 'off', '0', 'falseclass'] unless defined?(FALSE_STRINGS)
1084
+
1085
+ def Helper.to_boolean(field_name, value)
1086
+ string = value.to_s.strip.downcase
1087
+ if TRUE_STRINGS.include?(string)
1088
+ true
1089
+ elsif FALSE_STRINGS.include?(string)
1090
+ false
1091
+ elsif string != ""
1092
+ raise PreconditionException.new("Unsupported boolean value[#{string}]. For true, must be one of: #{TRUE_STRINGS.inspect}. For false, must be one of: #{FALSE_STRINGS.inspect}")
1093
+ else
1094
+ nil
1095
+ end
1096
+ end
1097
+
1098
+ end
1099
+
1100
+ end
1101
+ end
1102
+ end
1103
+ end
1104
+ end