google-api-client 0.1.3 → 0.2.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.
@@ -12,81 +12,113 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+
15
16
  require 'json'
16
17
  require 'addressable/uri'
17
18
  require 'addressable/template'
18
- require 'extlib/inflection'
19
+
20
+ require 'google/inflection'
21
+ require 'google/api_client/errors'
19
22
 
20
23
  module Google
21
24
  class APIClient
22
- ##
23
- # An exception that is raised if a method is called with missing or
24
- # invalid parameter values.
25
- class ValidationError < StandardError
26
- end
27
-
28
25
  ##
29
26
  # A service that has been described by a discovery document.
30
- class Service
27
+ class API
31
28
 
32
29
  ##
33
30
  # Creates a description of a particular version of a service.
34
31
  #
35
- # @param [String] service_name
32
+ # @param [String] api
36
33
  # The identifier for the service. Note that while this frequently
37
34
  # matches the first segment of all of the service's RPC names, this
38
35
  # should not be assumed. There is no requirement that these match.
39
- # @param [String] service_version
36
+ # @param [String] version
40
37
  # The identifier for the service version.
41
- # @param [Hash] service_description
38
+ # @param [Hash] api_description
42
39
  # The section of the discovery document that applies to this service
43
40
  # version.
44
41
  #
45
- # @return [Google::APIClient::Service] The constructed service object.
46
- def initialize(service_name, service_version, service_description)
47
- @name = service_name
48
- @version = service_version
49
- @description = service_description
42
+ # @return [Google::APIClient::API] The constructed service object.
43
+ def initialize(document_base, discovery_document)
44
+ @document_base = Addressable::URI.parse(document_base)
45
+ @discovery_document = discovery_document
50
46
  metaclass = (class <<self; self; end)
51
47
  self.resources.each do |resource|
52
- method_name = Extlib::Inflection.underscore(resource.name).to_sym
48
+ method_name = Google::INFLECTOR.underscore(resource.name).to_sym
53
49
  if !self.respond_to?(method_name)
54
50
  metaclass.send(:define_method, method_name) { resource }
55
51
  end
56
52
  end
57
53
  self.methods.each do |method|
58
- method_name = Extlib::Inflection.underscore(method.name).to_sym
54
+ method_name = Google::INFLECTOR.underscore(method.name).to_sym
59
55
  if !self.respond_to?(method_name)
60
56
  metaclass.send(:define_method, method_name) { method }
61
57
  end
62
58
  end
63
59
  end
64
60
 
61
+ ##
62
+ # Returns the id of the service.
63
+ #
64
+ # @return [String] The service id.
65
+ def id
66
+ return @discovery_document['id']
67
+ end
68
+
65
69
  ##
66
70
  # Returns the identifier for the service.
67
71
  #
68
72
  # @return [String] The service identifier.
69
- attr_reader :name
73
+ def name
74
+ return @discovery_document['name']
75
+ end
70
76
 
71
77
  ##
72
78
  # Returns the version of the service.
73
79
  #
74
80
  # @return [String] The service version.
75
- attr_reader :version
81
+ def version
82
+ return @discovery_document['version']
83
+ end
76
84
 
77
85
  ##
78
86
  # Returns the parsed section of the discovery document that applies to
79
87
  # this version of the service.
80
88
  #
81
89
  # @return [Hash] The service description.
82
- attr_reader :description
90
+ def description
91
+ return @discovery_document['description']
92
+ end
93
+
94
+ ##
95
+ # Returns true if this is the preferred version of this API.
96
+ #
97
+ # @return [TrueClass, FalseClass]
98
+ # Whether or not this is the preferred version of this API.
99
+ def preferred
100
+ return @discovery_document['preferred']
101
+ end
102
+
103
+ ##
104
+ # Returns the base URI for the discovery document.
105
+ #
106
+ # @return [Addressable::URI] The base URI.
107
+ attr_reader :document_base
83
108
 
84
109
  ##
85
110
  # Returns the base URI for this version of the service.
86
111
  #
87
112
  # @return [Addressable::URI] The base URI that methods are joined to.
88
- def base
89
- return @base ||= Addressable::URI.parse(self.description['baseUrl'])
113
+ def method_base
114
+ if @discovery_document['basePath']
115
+ return @method_base ||= (
116
+ self.document_base +
117
+ Addressable::URI.parse(@discovery_document['basePath'])
118
+ ).normalize
119
+ else
120
+ return nil
121
+ end
90
122
  end
91
123
 
92
124
  ##
@@ -94,13 +126,13 @@ module Google
94
126
  #
95
127
  # @param [Addressable::URI, #to_str, String] new_base
96
128
  # The new base URI to use for the service.
97
- def base=(new_base)
98
- @base = Addressable::URI.parse(new_base)
129
+ def method_base=(new_method_base)
130
+ @method_base = Addressable::URI.parse(new_method_base)
99
131
  self.resources.each do |resource|
100
- resource.base = @base
132
+ resource.method_base = @method_base
101
133
  end
102
134
  self.methods.each do |method|
103
- method.base = @base
135
+ method.method_base = @method_base
104
136
  end
105
137
  end
106
138
 
@@ -111,8 +143,8 @@ module Google
111
143
  # @return [Array] A list of {Google::APIClient::Resource} objects.
112
144
  def resources
113
145
  return @resources ||= (
114
- (self.description['resources'] || []).inject([]) do |accu, (k, v)|
115
- accu << ::Google::APIClient::Resource.new(self.base, k, v)
146
+ (@discovery_document['resources'] || []).inject([]) do |accu, (k, v)|
147
+ accu << ::Google::APIClient::Resource.new(self.method_base, k, v)
116
148
  accu
117
149
  end
118
150
  )
@@ -125,8 +157,8 @@ module Google
125
157
  # @return [Array] A list of {Google::APIClient::Method} objects.
126
158
  def methods
127
159
  return @methods ||= (
128
- (self.description['methods'] || []).inject([]) do |accu, (k, v)|
129
- accu << ::Google::APIClient::Method.new(self.base, k, v)
160
+ (@discovery_document['methods'] || []).inject([]) do |accu, (k, v)|
161
+ accu << ::Google::APIClient::Method.new(self.method_base, k, v)
130
162
  accu
131
163
  end
132
164
  )
@@ -139,12 +171,12 @@ module Google
139
171
  #
140
172
  # @example
141
173
  # # Discover available methods
142
- # method_names = client.discovered_service('buzz').to_h.keys
174
+ # method_names = client.discovered_api('buzz').to_h.keys
143
175
  def to_h
144
176
  return @hash ||= (begin
145
177
  methods_hash = {}
146
178
  self.methods.each do |method|
147
- methods_hash[method.rpc_name] = method
179
+ methods_hash[method.id] = method
148
180
  end
149
181
  self.resources.each do |resource|
150
182
  methods_hash.merge!(resource.to_h)
@@ -153,55 +185,13 @@ module Google
153
185
  end)
154
186
  end
155
187
 
156
- ##
157
- # Compares two versions of a service.
158
- #
159
- # @param [Object] other The service to compare.
160
- #
161
- # @return [Integer]
162
- # <code>-1</code> if the service is older than <code>other</code>.
163
- # <code>0</code> if the service is the same as <code>other</code>.
164
- # <code>1</code> if the service is newer than <code>other</code>.
165
- # <code>nil</code> if the service cannot be compared to
166
- # <code>other</code>.
167
- def <=>(other)
168
- # We can only compare versions of the same service
169
- if other.kind_of?(self.class) && self.name == other.name
170
- split_version = lambda do |version|
171
- dotted_version = version[/^v?(\d+(.\d+)*)-?(.*?)?$/, 1]
172
- suffix = version[/^v?(\d+(.\d+)*)-?(.*?)?$/, 3]
173
- if dotted_version && suffix
174
- [dotted_version.split('.').map { |v| v.to_i }, suffix]
175
- else
176
- [[-1], version]
177
- end
178
- end
179
- self_sortable, self_suffix = split_version.call(self.version)
180
- other_sortable, other_suffix = split_version.call(other.version)
181
- result = self_sortable <=> other_sortable
182
- if result != 0
183
- return result
184
- # If the dotted versions are equal, check the suffix.
185
- # An omitted suffix should be sorted after an included suffix.
186
- elsif self_suffix == ''
187
- return 1
188
- elsif other_suffix == ''
189
- return -1
190
- else
191
- return self_suffix <=> other_suffix
192
- end
193
- else
194
- return nil
195
- end
196
- end
197
-
198
188
  ##
199
189
  # Returns a <code>String</code> representation of the service's state.
200
190
  #
201
191
  # @return [String] The service's state, as a <code>String</code>.
202
192
  def inspect
203
193
  sprintf(
204
- "#<%s:%#0x NAME:%s>", self.class.to_s, self.object_id, self.name
194
+ "#<%s:%#0x ID:%s>", self.class.to_s, self.object_id, self.id
205
195
  )
206
196
  end
207
197
  end
@@ -221,19 +211,19 @@ module Google
221
211
  # The section of the discovery document that applies to this resource.
222
212
  #
223
213
  # @return [Google::APIClient::Resource] The constructed resource object.
224
- def initialize(base, resource_name, resource_description)
225
- @base = base
214
+ def initialize(method_base, resource_name, discovery_document)
215
+ @method_base = method_base
226
216
  @name = resource_name
227
- @description = resource_description
217
+ @discovery_document = discovery_document
228
218
  metaclass = (class <<self; self; end)
229
219
  self.resources.each do |resource|
230
- method_name = Extlib::Inflection.underscore(resource.name).to_sym
220
+ method_name = Google::INFLECTOR.underscore(resource.name).to_sym
231
221
  if !self.respond_to?(method_name)
232
222
  metaclass.send(:define_method, method_name) { resource }
233
223
  end
234
224
  end
235
225
  self.methods.each do |method|
236
- method_name = Extlib::Inflection.underscore(method.name).to_sym
226
+ method_name = Google::INFLECTOR.underscore(method.name).to_sym
237
227
  if !self.respond_to?(method_name)
238
228
  metaclass.send(:define_method, method_name) { method }
239
229
  end
@@ -257,20 +247,20 @@ module Google
257
247
  # Returns the base URI for this resource.
258
248
  #
259
249
  # @return [Addressable::URI] The base URI that methods are joined to.
260
- attr_reader :base
250
+ attr_reader :method_base
261
251
 
262
252
  ##
263
253
  # Updates the hierarchy of resources and methods with the new base.
264
254
  #
265
255
  # @param [Addressable::URI, #to_str, String] new_base
266
256
  # The new base URI to use for the resource.
267
- def base=(new_base)
268
- @base = Addressable::URI.parse(new_base)
257
+ def method_base=(new_method_base)
258
+ @method_base = Addressable::URI.parse(new_method_base)
269
259
  self.resources.each do |resource|
270
- resource.base = @base
260
+ resource.method_base = @method_base
271
261
  end
272
262
  self.methods.each do |method|
273
- method.base = @base
263
+ method.method_base = @method_base
274
264
  end
275
265
  end
276
266
 
@@ -280,8 +270,8 @@ module Google
280
270
  # @return [Array] A list of {Google::APIClient::Resource} objects.
281
271
  def resources
282
272
  return @resources ||= (
283
- (self.description['resources'] || []).inject([]) do |accu, (k, v)|
284
- accu << ::Google::APIClient::Resource.new(self.base, k, v)
273
+ (@discovery_document['resources'] || []).inject([]) do |accu, (k, v)|
274
+ accu << ::Google::APIClient::Resource.new(self.method_base, k, v)
285
275
  accu
286
276
  end
287
277
  )
@@ -293,8 +283,8 @@ module Google
293
283
  # @return [Array] A list of {Google::APIClient::Method} objects.
294
284
  def methods
295
285
  return @methods ||= (
296
- (self.description['methods'] || []).inject([]) do |accu, (k, v)|
297
- accu << ::Google::APIClient::Method.new(self.base, k, v)
286
+ (@discovery_document['methods'] || []).inject([]) do |accu, (k, v)|
287
+ accu << ::Google::APIClient::Method.new(self.method_base, k, v)
298
288
  accu
299
289
  end
300
290
  )
@@ -309,7 +299,7 @@ module Google
309
299
  return @hash ||= (begin
310
300
  methods_hash = {}
311
301
  self.methods.each do |method|
312
- methods_hash[method.rpc_name] = method
302
+ methods_hash[method.id] = method
313
303
  end
314
304
  self.resources.each do |resource|
315
305
  methods_hash.merge!(resource.to_h)
@@ -336,7 +326,7 @@ module Google
336
326
  ##
337
327
  # Creates a description of a particular method.
338
328
  #
339
- # @param [Addressable::URI] base
329
+ # @param [Addressable::URI] method_base
340
330
  # The base URI for the service.
341
331
  # @param [String] method_name
342
332
  # The identifier for the method.
@@ -344,10 +334,10 @@ module Google
344
334
  # The section of the discovery document that applies to this method.
345
335
  #
346
336
  # @return [Google::APIClient::Method] The constructed method object.
347
- def initialize(base, method_name, method_description)
348
- @base = base
337
+ def initialize(method_base, method_name, discovery_document)
338
+ @method_base = method_base
349
339
  @name = method_name
350
- @description = method_description
340
+ @discovery_document = discovery_document
351
341
  end
352
342
 
353
343
  ##
@@ -368,24 +358,24 @@ module Google
368
358
  #
369
359
  # @return [Addressable::URI]
370
360
  # The base URI that this method will be joined to.
371
- attr_reader :base
361
+ attr_reader :method_base
372
362
 
373
363
  ##
374
364
  # Updates the method with the new base.
375
365
  #
376
366
  # @param [Addressable::URI, #to_str, String] new_base
377
367
  # The new base URI to use for the method.
378
- def base=(new_base)
379
- @base = Addressable::URI.parse(new_base)
368
+ def method_base=(new_method_base)
369
+ @method_base = Addressable::URI.parse(new_method_base)
380
370
  @uri_template = nil
381
371
  end
382
372
 
383
373
  ##
384
- # Returns the RPC name for the method.
374
+ # Returns the method ID.
385
375
  #
386
- # @return [String] The RPC name.
387
- def rpc_name
388
- return self.description['rpcName']
376
+ # @return [String] The method identifier.
377
+ def id
378
+ return @discovery_document['id']
389
379
  end
390
380
 
391
381
  ##
@@ -398,8 +388,9 @@ module Google
398
388
  # a join operation on a URI, but we have to treat these as Strings
399
389
  # because of the way the discovery document provides the URIs.
400
390
  # This should be fixed soon.
401
- return @uri_template ||=
402
- Addressable::Template.new(base.to_s + self.description['pathUrl'])
391
+ return @uri_template ||= Addressable::Template.new(
392
+ self.method_base + @discovery_document['path']
393
+ )
403
394
  end
404
395
 
405
396
  ##
@@ -474,7 +465,7 @@ module Google
474
465
  if !headers.kind_of?(Array) && !headers.kind_of?(Hash)
475
466
  raise TypeError, "Expected Hash or Array, got #{headers.class}."
476
467
  end
477
- method = self.description['httpMethod'] || 'GET'
468
+ method = @discovery_document['httpMethod'] || 'GET'
478
469
  uri = self.generate_uri(parameters)
479
470
  headers = headers.to_a if headers.kind_of?(Hash)
480
471
  return [method, uri.to_str, headers, [body]]
@@ -487,7 +478,7 @@ module Google
487
478
  # @return [Hash] The parameter descriptions.
488
479
  def parameter_descriptions
489
480
  @parameter_descriptions ||= (
490
- self.description['parameters'] || {}
481
+ @discovery_document['parameters'] || {}
491
482
  ).inject({}) { |h,(k,v)| h[k]=v; h }
492
483
  end
493
484
 
@@ -497,7 +488,7 @@ module Google
497
488
  # @return [Array] The parameters.
498
489
  def parameters
499
490
  @parameters ||= ((
500
- self.description['parameters'] || {}
491
+ @discovery_document['parameters'] || {}
501
492
  ).inject({}) { |h,(k,v)| h[k]=v; h }).keys
502
493
  end
503
494
 
@@ -551,6 +542,12 @@ module Google
551
542
  end
552
543
  parameters.each do |k, v|
553
544
  if self.parameter_descriptions[k]
545
+ enum = self.parameter_descriptions[k]['enum']
546
+ if enum && !enum.include?(v)
547
+ raise ArgumentError,
548
+ "Parameter '#{k}' has an invalid value: #{v}. " +
549
+ "Must be one of #{enum.inspect}."
550
+ end
554
551
  pattern = self.parameter_descriptions[k]['pattern']
555
552
  if pattern
556
553
  regexp = Regexp.new("^#{pattern}$")
@@ -571,7 +568,8 @@ module Google
571
568
  # @return [String] The method's state, as a <code>String</code>.
572
569
  def inspect
573
570
  sprintf(
574
- "#<%s:%#0x NAME:%s>", self.class.to_s, self.object_id, self.rpc_name
571
+ "#<%s:%#0x ID:%s>",
572
+ self.class.to_s, self.object_id, self.id
575
573
  )
576
574
  end
577
575
  end
@@ -0,0 +1,13 @@
1
+ module Google
2
+ class APIClient
3
+ module ENV
4
+ OS_VERSION = if RUBY_PLATFORM =~ /win32/
5
+ `ver`.sub(/\s*\[Version\s*/, '/').sub(']', '')
6
+ elsif RUBY_PLATFORM =~ /darwin/i
7
+ "Mac OS X/#{`sw_vers -productVersion`}"
8
+ else
9
+ `uname -sr`.sub(' ', '/')
10
+ end
11
+ end
12
+ end
13
+ end