cure-google-api-client 0.8.7.1

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 (62) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +178 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE +202 -0
  5. data/README.md +218 -0
  6. data/Rakefile +41 -0
  7. data/google-api-client.gemspec +43 -0
  8. data/lib/cacerts.pem +2183 -0
  9. data/lib/compat/multi_json.rb +19 -0
  10. data/lib/google/api_client.rb +750 -0
  11. data/lib/google/api_client/auth/compute_service_account.rb +28 -0
  12. data/lib/google/api_client/auth/file_storage.rb +59 -0
  13. data/lib/google/api_client/auth/installed_app.rb +126 -0
  14. data/lib/google/api_client/auth/jwt_asserter.rb +126 -0
  15. data/lib/google/api_client/auth/key_utils.rb +93 -0
  16. data/lib/google/api_client/auth/pkcs12.rb +41 -0
  17. data/lib/google/api_client/auth/storage.rb +102 -0
  18. data/lib/google/api_client/auth/storages/file_store.rb +58 -0
  19. data/lib/google/api_client/auth/storages/redis_store.rb +54 -0
  20. data/lib/google/api_client/batch.rb +326 -0
  21. data/lib/google/api_client/charset.rb +33 -0
  22. data/lib/google/api_client/client_secrets.rb +179 -0
  23. data/lib/google/api_client/discovery.rb +19 -0
  24. data/lib/google/api_client/discovery/api.rb +310 -0
  25. data/lib/google/api_client/discovery/media.rb +77 -0
  26. data/lib/google/api_client/discovery/method.rb +363 -0
  27. data/lib/google/api_client/discovery/resource.rb +156 -0
  28. data/lib/google/api_client/discovery/schema.rb +117 -0
  29. data/lib/google/api_client/environment.rb +42 -0
  30. data/lib/google/api_client/errors.rb +65 -0
  31. data/lib/google/api_client/gzip.rb +28 -0
  32. data/lib/google/api_client/logging.rb +32 -0
  33. data/lib/google/api_client/media.rb +259 -0
  34. data/lib/google/api_client/railtie.rb +18 -0
  35. data/lib/google/api_client/reference.rb +27 -0
  36. data/lib/google/api_client/request.rb +350 -0
  37. data/lib/google/api_client/result.rb +255 -0
  38. data/lib/google/api_client/service.rb +233 -0
  39. data/lib/google/api_client/service/batch.rb +110 -0
  40. data/lib/google/api_client/service/request.rb +144 -0
  41. data/lib/google/api_client/service/resource.rb +40 -0
  42. data/lib/google/api_client/service/result.rb +162 -0
  43. data/lib/google/api_client/service/simple_file_store.rb +151 -0
  44. data/lib/google/api_client/service/stub_generator.rb +61 -0
  45. data/lib/google/api_client/service_account.rb +21 -0
  46. data/lib/google/api_client/version.rb +26 -0
  47. data/spec/google/api_client/auth/storage_spec.rb +122 -0
  48. data/spec/google/api_client/auth/storages/file_store_spec.rb +40 -0
  49. data/spec/google/api_client/auth/storages/redis_store_spec.rb +70 -0
  50. data/spec/google/api_client/batch_spec.rb +248 -0
  51. data/spec/google/api_client/client_secrets_spec.rb +53 -0
  52. data/spec/google/api_client/discovery_spec.rb +708 -0
  53. data/spec/google/api_client/gzip_spec.rb +98 -0
  54. data/spec/google/api_client/media_spec.rb +178 -0
  55. data/spec/google/api_client/request_spec.rb +29 -0
  56. data/spec/google/api_client/result_spec.rb +207 -0
  57. data/spec/google/api_client/service_account_spec.rb +169 -0
  58. data/spec/google/api_client/service_spec.rb +618 -0
  59. data/spec/google/api_client/simple_file_store_spec.rb +133 -0
  60. data/spec/google/api_client_spec.rb +352 -0
  61. data/spec/spec_helper.rb +66 -0
  62. metadata +339 -0
@@ -0,0 +1,77 @@
1
+ # Copyright 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require 'addressable/uri'
17
+ require 'addressable/template'
18
+
19
+ require 'google/api_client/errors'
20
+
21
+
22
+ module Google
23
+ class APIClient
24
+ ##
25
+ # Media upload elements for discovered methods
26
+ class MediaUpload
27
+
28
+ ##
29
+ # Creates a description of a particular method.
30
+ #
31
+ # @param [Google::APIClient::API] api
32
+ # Base discovery document for the API
33
+ # @param [Addressable::URI] method_base
34
+ # The base URI for the service.
35
+ # @param [Hash] discovery_document
36
+ # The media upload section of the discovery document.
37
+ #
38
+ # @return [Google::APIClient::Method] The constructed method object.
39
+ def initialize(api, method_base, discovery_document)
40
+ @api = api
41
+ @method_base = method_base
42
+ @discovery_document = discovery_document
43
+ end
44
+
45
+ ##
46
+ # List of acceptable mime types
47
+ #
48
+ # @return [Array]
49
+ # List of acceptable mime types for uploaded content
50
+ def accepted_types
51
+ @discovery_document['accept']
52
+ end
53
+
54
+ ##
55
+ # Maximum size of an uplad
56
+ # TODO: Parse & convert to numeric value
57
+ #
58
+ # @return [String]
59
+ def max_size
60
+ @discovery_document['maxSize']
61
+ end
62
+
63
+ ##
64
+ # Returns the URI template for the method. A parameter list can be
65
+ # used to expand this into a URI.
66
+ #
67
+ # @return [Addressable::Template] The URI template.
68
+ def uri_template
69
+ return @uri_template ||= Addressable::Template.new(
70
+ @api.method_base.join(Addressable::URI.parse(@discovery_document['protocols']['simple']['path']))
71
+ )
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,363 @@
1
+ # Copyright 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require 'addressable/uri'
17
+ require 'addressable/template'
18
+
19
+ require 'google/api_client/errors'
20
+
21
+
22
+ module Google
23
+ class APIClient
24
+ ##
25
+ # A method that has been described by a discovery document.
26
+ class Method
27
+
28
+ ##
29
+ # Creates a description of a particular method.
30
+ #
31
+ # @param [Google::APIClient::API] api
32
+ # The API this method belongs to.
33
+ # @param [Addressable::URI] method_base
34
+ # The base URI for the service.
35
+ # @param [String] method_name
36
+ # The identifier for the method.
37
+ # @param [Hash] discovery_document
38
+ # The section of the discovery document that applies to this method.
39
+ #
40
+ # @return [Google::APIClient::Method] The constructed method object.
41
+ def initialize(api, method_base, method_name, discovery_document)
42
+ @api = api
43
+ @method_base = method_base
44
+ @name = method_name
45
+ @discovery_document = discovery_document
46
+ end
47
+
48
+ # @return [String] unparsed discovery document for the method
49
+ attr_reader :discovery_document
50
+
51
+ ##
52
+ # Returns the API this method belongs to.
53
+ #
54
+ # @return [Google::APIClient::API] The API this method belongs to.
55
+ attr_reader :api
56
+
57
+ ##
58
+ # Returns the identifier for the method.
59
+ #
60
+ # @return [String] The method identifier.
61
+ attr_reader :name
62
+
63
+ ##
64
+ # Returns the base URI for the method.
65
+ #
66
+ # @return [Addressable::URI]
67
+ # The base URI that this method will be joined to.
68
+ attr_reader :method_base
69
+
70
+ ##
71
+ # Updates the method with the new base.
72
+ #
73
+ # @param [Addressable::URI, #to_str, String] new_method_base
74
+ # The new base URI to use for the method.
75
+ def method_base=(new_method_base)
76
+ @method_base = Addressable::URI.parse(new_method_base)
77
+ @uri_template = nil
78
+ end
79
+
80
+ ##
81
+ # Returns a human-readable description of the method.
82
+ #
83
+ # @return [Hash] The API description.
84
+ def description
85
+ return @discovery_document['description']
86
+ end
87
+
88
+ ##
89
+ # Returns the method ID.
90
+ #
91
+ # @return [String] The method identifier.
92
+ def id
93
+ return @discovery_document['id']
94
+ end
95
+
96
+ ##
97
+ # Returns the HTTP method or 'GET' if none is specified.
98
+ #
99
+ # @return [String] The HTTP method that will be used in the request.
100
+ def http_method
101
+ return @discovery_document['httpMethod'] || 'GET'
102
+ end
103
+
104
+ ##
105
+ # Returns the URI template for the method. A parameter list can be
106
+ # used to expand this into a URI.
107
+ #
108
+ # @return [Addressable::Template] The URI template.
109
+ def uri_template
110
+ return @uri_template ||= Addressable::Template.new(
111
+ self.method_base.join(Addressable::URI.parse("./" + @discovery_document['path']))
112
+ )
113
+ end
114
+
115
+ ##
116
+ # Returns media upload information for this method, if supported
117
+ #
118
+ # @return [Google::APIClient::MediaUpload] Description of upload endpoints
119
+ def media_upload
120
+ if @discovery_document['mediaUpload']
121
+ return @media_upload ||= Google::APIClient::MediaUpload.new(self, self.method_base, @discovery_document['mediaUpload'])
122
+ else
123
+ return nil
124
+ end
125
+ end
126
+
127
+ ##
128
+ # Returns the Schema object for the method's request, if any.
129
+ #
130
+ # @return [Google::APIClient::Schema] The request schema.
131
+ def request_schema
132
+ if @discovery_document['request']
133
+ schema_name = @discovery_document['request']['$ref']
134
+ return @api.schemas[schema_name]
135
+ else
136
+ return nil
137
+ end
138
+ end
139
+
140
+ ##
141
+ # Returns the Schema object for the method's response, if any.
142
+ #
143
+ # @return [Google::APIClient::Schema] The response schema.
144
+ def response_schema
145
+ if @discovery_document['response']
146
+ schema_name = @discovery_document['response']['$ref']
147
+ return @api.schemas[schema_name]
148
+ else
149
+ return nil
150
+ end
151
+ end
152
+
153
+ ##
154
+ # Normalizes parameters, converting to the appropriate types.
155
+ #
156
+ # @param [Hash, Array] parameters
157
+ # The parameters to normalize.
158
+ #
159
+ # @return [Hash] The normalized parameters.
160
+ def normalize_parameters(parameters={})
161
+ # Convert keys to Strings when appropriate
162
+ if parameters.kind_of?(Hash) || parameters.kind_of?(Array)
163
+ # Returning an array since parameters can be repeated (ie, Adsense Management API)
164
+ parameters = parameters.inject([]) do |accu, (k, v)|
165
+ k = k.to_s if k.kind_of?(Symbol)
166
+ k = k.to_str if k.respond_to?(:to_str)
167
+ unless k.kind_of?(String)
168
+ raise TypeError, "Expected String, got #{k.class}."
169
+ end
170
+ accu << [k, v]
171
+ accu
172
+ end
173
+ else
174
+ raise TypeError,
175
+ "Expected Hash or Array, got #{parameters.class}."
176
+ end
177
+ return parameters
178
+ end
179
+
180
+ ##
181
+ # Expands the method's URI template using a parameter list.
182
+ #
183
+ # @api private
184
+ # @param [Hash, Array] parameters
185
+ # The parameter list to use.
186
+ #
187
+ # @return [Addressable::URI] The URI after expansion.
188
+ def generate_uri(parameters={})
189
+ parameters = self.normalize_parameters(parameters)
190
+
191
+ self.validate_parameters(parameters)
192
+ template_variables = self.uri_template.variables
193
+ upload_type = parameters.assoc('uploadType') || parameters.assoc('upload_type')
194
+ if upload_type
195
+ unless self.media_upload
196
+ raise ArgumentException, "Media upload not supported for this method"
197
+ end
198
+ case upload_type.last
199
+ when 'media', 'multipart', 'resumable'
200
+ uri = self.media_upload.uri_template.expand(parameters)
201
+ else
202
+ raise ArgumentException, "Invalid uploadType '#{upload_type}'"
203
+ end
204
+ else
205
+ uri = self.uri_template.expand(parameters)
206
+ end
207
+ query_parameters = parameters.reject do |k, v|
208
+ template_variables.include?(k)
209
+ end
210
+ # encode all non-template parameters
211
+ params = ""
212
+ unless query_parameters.empty?
213
+ params = "?" + Addressable::URI.form_encode(query_parameters.sort)
214
+ end
215
+ # Normalization is necessary because of undesirable percent-escaping
216
+ # during URI template expansion
217
+ return uri.normalize + params
218
+ end
219
+
220
+ ##
221
+ # Generates an HTTP request for this method.
222
+ #
223
+ # @api private
224
+ # @param [Hash, Array] parameters
225
+ # The parameters to send.
226
+ # @param [String, StringIO] body The body for the HTTP request.
227
+ # @param [Hash, Array] headers The HTTP headers for the request.
228
+ # @option options [Faraday::Connection] :connection
229
+ # The HTTP connection to use.
230
+ #
231
+ # @return [Array] The generated HTTP request.
232
+ def generate_request(parameters={}, body='', headers={}, options={})
233
+ if !headers.kind_of?(Array) && !headers.kind_of?(Hash)
234
+ raise TypeError, "Expected Hash or Array, got #{headers.class}."
235
+ end
236
+ method = self.http_method.to_s.downcase.to_sym
237
+ uri = self.generate_uri(parameters)
238
+ headers = Faraday::Utils::Headers.new(headers)
239
+ return [method, uri, headers, body]
240
+ end
241
+
242
+
243
+ ##
244
+ # Returns a <code>Hash</code> of the parameter descriptions for
245
+ # this method.
246
+ #
247
+ # @return [Hash] The parameter descriptions.
248
+ def parameter_descriptions
249
+ @parameter_descriptions ||= (
250
+ @discovery_document['parameters'] || {}
251
+ ).inject({}) { |h,(k,v)| h[k]=v; h }
252
+ end
253
+
254
+ ##
255
+ # Returns an <code>Array</code> of the parameters for this method.
256
+ #
257
+ # @return [Array] The parameters.
258
+ def parameters
259
+ @parameters ||= ((
260
+ @discovery_document['parameters'] || {}
261
+ ).inject({}) { |h,(k,v)| h[k]=v; h }).keys
262
+ end
263
+
264
+ ##
265
+ # Returns an <code>Array</code> of the required parameters for this
266
+ # method.
267
+ #
268
+ # @return [Array] The required parameters.
269
+ #
270
+ # @example
271
+ # # A list of all required parameters.
272
+ # method.required_parameters
273
+ def required_parameters
274
+ @required_parameters ||= ((self.parameter_descriptions.select do |k, v|
275
+ v['required']
276
+ end).inject({}) { |h,(k,v)| h[k]=v; h }).keys
277
+ end
278
+
279
+ ##
280
+ # Returns an <code>Array</code> of the optional parameters for this
281
+ # method.
282
+ #
283
+ # @return [Array] The optional parameters.
284
+ #
285
+ # @example
286
+ # # A list of all optional parameters.
287
+ # method.optional_parameters
288
+ def optional_parameters
289
+ @optional_parameters ||= ((self.parameter_descriptions.reject do |k, v|
290
+ v['required']
291
+ end).inject({}) { |h,(k,v)| h[k]=v; h }).keys
292
+ end
293
+
294
+ ##
295
+ # Verifies that the parameters are valid for this method. Raises an
296
+ # exception if validation fails.
297
+ #
298
+ # @api private
299
+ # @param [Hash, Array] parameters
300
+ # The parameters to verify.
301
+ #
302
+ # @return [NilClass] <code>nil</code> if validation passes.
303
+ def validate_parameters(parameters={})
304
+ parameters = self.normalize_parameters(parameters)
305
+ required_variables = ((self.parameter_descriptions.select do |k, v|
306
+ v['required']
307
+ end).inject({}) { |h,(k,v)| h[k]=v; h }).keys
308
+ missing_variables = required_variables - parameters.map { |(k, _)| k }
309
+ if missing_variables.size > 0
310
+ raise ArgumentError,
311
+ "Missing required parameters: #{missing_variables.join(', ')}."
312
+ end
313
+ parameters.each do |k, v|
314
+ # Handle repeated parameters.
315
+ if self.parameter_descriptions[k] &&
316
+ self.parameter_descriptions[k]['repeated'] &&
317
+ v.kind_of?(Array)
318
+ # If this is a repeated parameter and we've got an array as a
319
+ # value, just provide the whole array to the loop below.
320
+ items = v
321
+ else
322
+ # If this is not a repeated parameter, or if it is but we're
323
+ # being given a single value, wrap the value in an array, so that
324
+ # the loop below still works for the single element.
325
+ items = [v]
326
+ end
327
+
328
+ items.each do |item|
329
+ if self.parameter_descriptions[k]
330
+ enum = self.parameter_descriptions[k]['enum']
331
+ if enum && !enum.include?(item)
332
+ raise ArgumentError,
333
+ "Parameter '#{k}' has an invalid value: #{item}. " +
334
+ "Must be one of #{enum.inspect}."
335
+ end
336
+ pattern = self.parameter_descriptions[k]['pattern']
337
+ if pattern
338
+ regexp = Regexp.new("^#{pattern}$")
339
+ if item !~ regexp
340
+ raise ArgumentError,
341
+ "Parameter '#{k}' has an invalid value: #{item}. " +
342
+ "Must match: /^#{pattern}$/."
343
+ end
344
+ end
345
+ end
346
+ end
347
+ end
348
+ return nil
349
+ end
350
+
351
+ ##
352
+ # Returns a <code>String</code> representation of the method's state.
353
+ #
354
+ # @return [String] The method's state, as a <code>String</code>.
355
+ def inspect
356
+ sprintf(
357
+ "#<%s:%#0x ID:%s>",
358
+ self.class.to_s, self.object_id, self.id
359
+ )
360
+ end
361
+ end
362
+ end
363
+ end
@@ -0,0 +1,156 @@
1
+ # Copyright 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require 'addressable/uri'
17
+
18
+ require 'active_support/inflector'
19
+ require 'google/api_client/discovery/method'
20
+
21
+
22
+ module Google
23
+ class APIClient
24
+ ##
25
+ # A resource that has been described by a discovery document.
26
+ class Resource
27
+
28
+ ##
29
+ # Creates a description of a particular version of a resource.
30
+ #
31
+ # @param [Google::APIClient::API] api
32
+ # The API this resource belongs to.
33
+ # @param [Addressable::URI] method_base
34
+ # The base URI for the service.
35
+ # @param [String] resource_name
36
+ # The identifier for the resource.
37
+ # @param [Hash] discovery_document
38
+ # The section of the discovery document that applies to this resource.
39
+ #
40
+ # @return [Google::APIClient::Resource] The constructed resource object.
41
+ def initialize(api, method_base, resource_name, discovery_document)
42
+ @api = api
43
+ @method_base = method_base
44
+ @name = resource_name
45
+ @discovery_document = discovery_document
46
+ metaclass = (class <<self; self; end)
47
+ self.discovered_resources.each do |resource|
48
+ method_name = ActiveSupport::Inflector.underscore(resource.name).to_sym
49
+ if !self.respond_to?(method_name)
50
+ metaclass.send(:define_method, method_name) { resource }
51
+ end
52
+ end
53
+ self.discovered_methods.each do |method|
54
+ method_name = ActiveSupport::Inflector.underscore(method.name).to_sym
55
+ if !self.respond_to?(method_name)
56
+ metaclass.send(:define_method, method_name) { method }
57
+ end
58
+ end
59
+ end
60
+
61
+ # @return [String] unparsed discovery document for the resource
62
+ attr_reader :discovery_document
63
+
64
+ ##
65
+ # Returns the identifier for the resource.
66
+ #
67
+ # @return [String] The resource identifier.
68
+ attr_reader :name
69
+
70
+ ##
71
+ # Returns the base URI for this resource.
72
+ #
73
+ # @return [Addressable::URI] The base URI that methods are joined to.
74
+ attr_reader :method_base
75
+
76
+ ##
77
+ # Returns a human-readable description of the resource.
78
+ #
79
+ # @return [Hash] The API description.
80
+ def description
81
+ return @discovery_document['description']
82
+ end
83
+
84
+ ##
85
+ # Updates the hierarchy of resources and methods with the new base.
86
+ #
87
+ # @param [Addressable::URI, #to_str, String] new_method_base
88
+ # The new base URI to use for the resource.
89
+ def method_base=(new_method_base)
90
+ @method_base = Addressable::URI.parse(new_method_base)
91
+ self.discovered_resources.each do |resource|
92
+ resource.method_base = @method_base
93
+ end
94
+ self.discovered_methods.each do |method|
95
+ method.method_base = @method_base
96
+ end
97
+ end
98
+
99
+ ##
100
+ # A list of sub-resources available on this resource.
101
+ #
102
+ # @return [Array] A list of {Google::APIClient::Resource} objects.
103
+ def discovered_resources
104
+ return @discovered_resources ||= (
105
+ (@discovery_document['resources'] || []).inject([]) do |accu, (k, v)|
106
+ accu << Google::APIClient::Resource.new(
107
+ @api, self.method_base, k, v
108
+ )
109
+ accu
110
+ end
111
+ )
112
+ end
113
+
114
+ ##
115
+ # A list of methods available on this resource.
116
+ #
117
+ # @return [Array] A list of {Google::APIClient::Method} objects.
118
+ def discovered_methods
119
+ return @discovered_methods ||= (
120
+ (@discovery_document['methods'] || []).inject([]) do |accu, (k, v)|
121
+ accu << Google::APIClient::Method.new(@api, self.method_base, k, v)
122
+ accu
123
+ end
124
+ )
125
+ end
126
+
127
+ ##
128
+ # Converts the resource to a flat mapping of RPC names and method
129
+ # objects.
130
+ #
131
+ # @return [Hash] All methods available on the resource.
132
+ def to_h
133
+ return @hash ||= (begin
134
+ methods_hash = {}
135
+ self.discovered_methods.each do |method|
136
+ methods_hash[method.id] = method
137
+ end
138
+ self.discovered_resources.each do |resource|
139
+ methods_hash.merge!(resource.to_h)
140
+ end
141
+ methods_hash
142
+ end)
143
+ end
144
+
145
+ ##
146
+ # Returns a <code>String</code> representation of the resource's state.
147
+ #
148
+ # @return [String] The resource's state, as a <code>String</code>.
149
+ def inspect
150
+ sprintf(
151
+ "#<%s:%#0x NAME:%s>", self.class.to_s, self.object_id, self.name
152
+ )
153
+ end
154
+ end
155
+ end
156
+ end