cure-google-api-client 0.8.7.1

Sign up to get free protection for your applications and to get access to all the features.
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