google-api-client 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,13 @@
1
+ == 0.3.0
2
+
3
+ * updated to use v1 of the discovery API
4
+ * updated to use httpadapter 1.0.0
5
+ * added OAuth 2 support to the command line tool
6
+ * renamed some switches in the command line tool
7
+ * added additional configuration capabilities
8
+ * fixed a few deprecation warnings from dependencies
9
+ * added gemspec to source control
10
+
1
11
  == 0.2.0
2
12
 
3
13
  * updated to use v1 of the discovery API
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # APIClient
2
+
3
+ <dl>
4
+ <dt>Homepage</dt><dd><a href="http://code.google.com/p/google-api-ruby-client">http://code.google.com/p/google-api-ruby-client</a></dd>
5
+ <dt>Author</dt><dd><a href="mailto:bobaman@google.com">Bob Aman</a></dd>
6
+ <dt>Copyright</dt><dd>Copyright © 2011 Google, Inc.</dd>
7
+ <dt>License</dt><dd>Apache 2.0</dd>
8
+ </dl>
9
+
10
+ # Description
11
+
12
+ The Google API Ruby Client makes it trivial to discover and access supported
13
+ APIs.
14
+
15
+ # Example Usage
16
+
17
+ # Initialize the client
18
+ require 'google/api_client'
19
+ require 'signet/oauth_1/client'
20
+ client = Google::APIClient.new(
21
+ :service => 'buzz',
22
+ # Buzz has API-specific endpoints
23
+ :authorization => Signet::OAuth1::Client.new(
24
+ :temporary_credential_uri =>
25
+ 'https://www.google.com/accounts/OAuthGetRequestToken',
26
+ :authorization_uri =>
27
+ 'https://www.google.com/buzz/api/auth/OAuthAuthorizeToken',
28
+ :token_credential_uri =>
29
+ 'https://www.google.com/accounts/OAuthGetAccessToken',
30
+ :client_credential_key => 'anonymous',
31
+ :client_credential_secret => 'anonymous'
32
+ )
33
+ )
34
+ client.authorization.fetch_temporary_credential!(
35
+ :additional_parameters => {
36
+ 'scope' => 'https://www.googleapis.com/auth/buzz'
37
+ }
38
+ )
39
+ redirect_uri = client.authorization.authorization_uri(
40
+ :additional_parameters => {
41
+ 'domain' => client.authorization.client_credential_key,
42
+ 'scope' => 'https://www.googleapis.com/auth/buzz'
43
+ }
44
+ )
45
+ # Redirect user here
46
+ client.authorization.fetch_token_credential!(:verifier => '12345')
47
+
48
+ # Discover available methods
49
+ method_names = client.discovered_api('buzz').to_h.keys
50
+
51
+ # Make an API call
52
+ response = client.execute(
53
+ 'chili.activities.list',
54
+ {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'}
55
+ )
56
+ status, headers, body = response
57
+
58
+ # Install
59
+
60
+ Be sure `http://rubygems.org/` is in your gem sources.
61
+
62
+ For normal client usage, this is sufficient:
63
+
64
+ $ sudo gem install google-api-client
65
+
66
+ The command line interface, the example applications, and the test suite
67
+ require additional dependencies. These may be obtained with:
68
+
69
+ $ sudo gem install google-api-client --development --force --no-rdoc --no-ri
data/Rakefile CHANGED
@@ -4,11 +4,8 @@ $LOAD_PATH.uniq!
4
4
 
5
5
  require 'rubygems'
6
6
  require 'rake'
7
- require 'rake/testtask'
8
- require 'rake/rdoctask'
9
- require 'rake/packagetask'
10
- require 'rake/gempackagetask'
11
7
 
8
+ gem 'rspec', '~> 1.2.9'
12
9
  begin
13
10
  require 'spec/rake/spectask'
14
11
  rescue LoadError
@@ -27,6 +24,8 @@ PKG_HOMEPAGE = 'http://code.google.com/p/google-api-ruby-client/'
27
24
 
28
25
  RELEASE_NAME = "REL #{PKG_VERSION}"
29
26
 
27
+ PKG_AUTHOR = "Bob Aman"
28
+ PKG_AUTHOR_EMAIL = "bobaman@google.com"
30
29
  PKG_SUMMARY = 'Package Summary'
31
30
  PKG_DESCRIPTION = <<-TEXT
32
31
  The Google API Ruby Client makes it trivial to discover and access supported
data/bin/google-api CHANGED
@@ -108,8 +108,8 @@ HTML
108
108
  options[:api] = s
109
109
  end
110
110
  opts.on(
111
- "--service-version <id>", String,
112
- "Select service version") do |id|
111
+ "--api-version <id>", String,
112
+ "Select api version") do |id|
113
113
  options[:version] = id
114
114
  end
115
115
  opts.on(
@@ -165,7 +165,7 @@ HTML
165
165
  "\nAvailable commands:\n" +
166
166
  " oauth-1-login Log a user into an API with OAuth 1.0a\n" +
167
167
  " oauth-2-login Log a user into an API with OAuth 2.0 d10\n" +
168
- " list List the methods available for a service\n" +
168
+ " list List the methods available for an API\n" +
169
169
  " execute Execute a method on the API\n" +
170
170
  " irb Start an interactive client session"
171
171
  )
@@ -238,17 +238,27 @@ HTML
238
238
  end
239
239
 
240
240
  if options[:discovery_uri]
241
- client.discovery_uri = options[:discovery_uri]
241
+ if options[:api] && options[:version]
242
+ client.register_discovery_uri(
243
+ options[:api], options[:version], options[:discovery_uri]
244
+ )
245
+ else
246
+ STDERR.puts(
247
+ 'Cannot register a discovery URI without ' +
248
+ 'specifying an API and version.'
249
+ )
250
+ exit(1)
251
+ end
242
252
  end
243
253
 
244
254
  return client
245
255
  end
246
256
 
247
- def api_version(api, version)
257
+ def api_version(api_name, version)
248
258
  v = version
249
259
  if !version
250
- if client.preferred_version(api)
251
- v = client.preferred_version(api).version
260
+ if client.preferred_version(api_name)
261
+ v = client.preferred_version(api_name).version
252
262
  else
253
263
  v = 'v1'
254
264
  end
@@ -284,13 +294,12 @@ HTML
284
294
  exit(0)
285
295
  else
286
296
  $verifier = nil
287
- # TODO(bobaman): Cross-platform?
288
- logger = WEBrick::Log.new('/dev/null')
289
297
  server = WEBrick::HTTPServer.new(
290
298
  :Port => OAUTH_SERVER_PORT,
291
- :Logger => logger,
292
- :AccessLog => logger
299
+ :Logger => WEBrick::Log.new,
300
+ :AccessLog => WEBrick::Log.new
293
301
  )
302
+ server.logger.level = 0
294
303
  trap("INT") { server.shutdown }
295
304
 
296
305
  server.mount("/", OAuthVerifierServlet)
@@ -379,7 +388,7 @@ HTML
379
388
  )
380
389
 
381
390
  # Launch browser
382
- Launchy::Browser.run(oauth_client.authorization_uri.to_s)
391
+ Launchy.open(oauth_client.authorization_uri.to_s)
383
392
 
384
393
  server.start
385
394
  oauth_client.code = $verifier
@@ -399,18 +408,28 @@ HTML
399
408
  end
400
409
 
401
410
  def list
402
- api = options[:api]
403
- unless api
411
+ api_name = options[:api]
412
+ unless api_name
404
413
  STDERR.puts('No API name supplied.')
405
414
  exit(1)
406
415
  end
407
416
  client = Google::APIClient.new(:authorization => nil)
408
417
  if options[:discovery_uri]
409
- client.discovery_uri = options[:discovery_uri]
418
+ if options[:api] && options[:version]
419
+ client.register_discovery_uri(
420
+ options[:api], options[:version], options[:discovery_uri]
421
+ )
422
+ else
423
+ STDERR.puts(
424
+ 'Cannot register a discovery URI without ' +
425
+ 'specifying an API and version.'
426
+ )
427
+ exit(1)
428
+ end
410
429
  end
411
- version = api_version(api, options[:version])
412
- service = client.discovered_api(api, version)
413
- rpcnames = service.to_h.keys
430
+ version = api_version(api_name, options[:version])
431
+ api = client.discovered_api(api_name, version)
432
+ rpcnames = api.to_h.keys
414
433
  puts rpcnames.sort.join("\n")
415
434
  exit(0)
416
435
  end
@@ -447,7 +466,7 @@ HTML
447
466
  method.upcase!
448
467
  request = [method, uri.to_str, headers, [request_body]]
449
468
  request = client.generate_authenticated_request(:request => request)
450
- response = client.transmit_request(request)
469
+ response = client.transmit(request)
451
470
  status, headers, body = response
452
471
  puts body
453
472
  exit(0)
@@ -457,14 +476,14 @@ HTML
457
476
  STDERR.puts('No rpcname supplied.')
458
477
  exit(1)
459
478
  end
460
- api = options[:api] || self.rpcname[/^([^\.]+)\./, 1]
461
- version = api_version(api, options[:version])
462
- service = client.discovered_api(api, version)
463
- method = service.to_h[self.rpcname]
479
+ api_name = options[:api] || self.rpcname[/^([^\.]+)\./, 1]
480
+ version = api_version(api_name, options[:version])
481
+ api = client.discovered_api(api_name, version)
482
+ method = api.to_h[self.rpcname]
464
483
  if !method
465
484
  STDERR.puts(
466
485
  "Method #{self.rpcname} does not exist for " +
467
- "#{api}-#{version}."
486
+ "#{api_name}-#{version}."
468
487
  )
469
488
  exit(1)
470
489
  end
@@ -477,10 +496,13 @@ HTML
477
496
  parameters['xoauth_requestor_id'] = options[:requestor_id]
478
497
  end
479
498
  begin
480
- response = client.execute(
481
- method, parameters, request_body, headers
499
+ result = client.execute(
500
+ :api_method => method,
501
+ :parameters => parameters,
502
+ :merged_body => request_body,
503
+ :headers => headers
482
504
  )
483
- status, headers, body = response
505
+ status, headers, body = result.response
484
506
  puts body
485
507
  exit(0)
486
508
  rescue ArgumentError => e
@@ -17,9 +17,12 @@ require 'httpadapter'
17
17
  require 'json'
18
18
  require 'stringio'
19
19
 
20
+ require 'google/api_client/version'
20
21
  require 'google/api_client/errors'
21
22
  require 'google/api_client/environment'
22
23
  require 'google/api_client/discovery'
24
+ require 'google/api_client/reference'
25
+ require 'google/api_client/result'
23
26
 
24
27
  module Google
25
28
  # TODO(bobaman): Document all this stuff.
@@ -65,19 +68,11 @@ module Google
65
68
  'google-api-ruby-client/' + VERSION::STRING +
66
69
  ' ' + ENV::OS_VERSION
67
70
  ).strip
68
- # This is mostly a default for the sake of convenience.
69
- # Unlike most other options, this one may be nil, so we check for
70
- # the presence of the key rather than checking the value.
71
- if options.has_key?("parser")
72
- self.parser = options["parser"]
73
- else
74
- require 'google/api_client/parsers/json_parser'
75
- # NOTE: Do not rely on this default value, as it may change
76
- self.parser = Google::APIClient::JSONParser
77
- end
78
71
  # The writer method understands a few Symbols and will generate useful
79
72
  # default authentication mechanisms.
80
73
  self.authorization = options["authorization"] || :oauth_2
74
+ self.key = options["key"]
75
+ self.user_ip = options["user_ip"]
81
76
  # The HTTP adapter controls all of the HTTP traffic the client generates.
82
77
  # By default, Net::HTTP is used, but adding support for other clients
83
78
  # is trivial.
@@ -94,33 +89,6 @@ module Google
94
89
  return self
95
90
  end
96
91
 
97
-
98
- ##
99
- # Returns the parser used by the client.
100
- #
101
- # @return [#serialize, #parse]
102
- # The parser used by the client. Any object that implements both a
103
- # <code>#serialize</code> and a <code>#parse</code> method may be used.
104
- # If <code>nil</code>, no parsing will be done.
105
- attr_reader :parser
106
-
107
- ##
108
- # Sets the parser used by the client.
109
- #
110
- # @param [#serialize, #parse] new_parser
111
- # The parser used by the client. Any object that implements both a
112
- # <code>#serialize</code> and a <code>#parse</code> method may be used.
113
- # If <code>nil</code>, no parsing will be done.
114
- def parser=(new_parser)
115
- if new_parser &&
116
- !new_parser.respond_to?(:serialize) &&
117
- !new_parser.respond_to?(:parse)
118
- raise TypeError,
119
- 'Expected parser object to respond to #serialize and #parse.'
120
- end
121
- @parser = new_parser
122
- end
123
-
124
92
  ##
125
93
  # Returns the authorization mechanism used by the client.
126
94
  #
@@ -177,6 +145,18 @@ module Google
177
145
  return @authorization
178
146
  end
179
147
 
148
+ ##
149
+ # The application's API key issued by the API console.
150
+ #
151
+ # @return [String] The API key..
152
+ attr_accessor :key
153
+
154
+ ##
155
+ # The IP address of the user this request is being performed on behalf of.
156
+ #
157
+ # @return [String] The user's IP address.
158
+ attr_accessor :user_ip
159
+
180
160
  ##
181
161
  # Returns the HTTP adapter used by the client.
182
162
  #
@@ -280,7 +260,7 @@ module Google
280
260
  "Expected String or StringIO, got #{discovery_document.class}."
281
261
  end
282
262
  @discovery_documents["#{api}:#{version}"] =
283
- JSON.parse(discovery_document)
263
+ ::JSON.parse(discovery_document)
284
264
  end
285
265
 
286
266
  ##
@@ -289,18 +269,30 @@ module Google
289
269
  # @return [Hash] The parsed JSON from the directory document.
290
270
  def directory_document
291
271
  return @directory_document ||= (begin
292
- request_uri = self.directory_uri
293
- request = ['GET', request_uri, [], []]
294
- response = self.transmit_request(request)
272
+ request = self.generate_request(
273
+ :http_method => 'GET',
274
+ :uri => self.directory_uri,
275
+ :authenticated => false
276
+ )
277
+ response = self.transmit(request)
295
278
  status, headers, body = response
296
- if status == 200 # TODO(bobaman) Better status code handling?
297
- merged_body = StringIO.new
298
- body.each do |chunk|
299
- merged_body.write(chunk)
279
+ if status >= 200 && status < 300
280
+ # TODO(bobaman) Better status code handling?
281
+ merged_body = body.inject(StringIO.new) do |accu, chunk|
282
+ accu.write(chunk)
283
+ accu
300
284
  end
301
- merged_body.rewind
302
- JSON.parse(merged_body.string)
303
- else
285
+ ::JSON.parse(merged_body.string)
286
+ elsif status >= 400 && status < 500
287
+ _, request_uri, _, _ = request
288
+ raise ClientError,
289
+ "Could not retrieve discovery document at: #{request_uri}"
290
+ elsif status >= 500 && status < 600
291
+ _, request_uri, _, _ = request
292
+ raise ServerError,
293
+ "Could not retrieve discovery document at: #{request_uri}"
294
+ elsif status > 600
295
+ _, request_uri, _, _ = request
304
296
  raise TransmissionError,
305
297
  "Could not retrieve discovery document at: #{request_uri}"
306
298
  end
@@ -317,18 +309,30 @@ module Google
317
309
  api = api.to_s
318
310
  version = version || 'v1'
319
311
  return @discovery_documents["#{api}:#{version}"] ||= (begin
320
- request_uri = self.discovery_uri(api, version)
321
- request = ['GET', request_uri, [], []]
322
- response = self.transmit_request(request)
312
+ request = self.generate_request(
313
+ :http_method => 'GET',
314
+ :uri => self.discovery_uri(api, version),
315
+ :authenticated => false
316
+ )
317
+ response = self.transmit(request)
323
318
  status, headers, body = response
324
- if status == 200 # TODO(bobaman) Better status code handling?
325
- merged_body = StringIO.new
326
- body.each do |chunk|
327
- merged_body.write(chunk)
319
+ if status >= 200 && status < 300
320
+ # TODO(bobaman) Better status code handling?
321
+ merged_body = body.inject(StringIO.new) do |accu, chunk|
322
+ accu.write(chunk)
323
+ accu
328
324
  end
329
- merged_body.rewind
330
- JSON.parse(merged_body.string)
331
- else
325
+ ::JSON.parse(merged_body.string)
326
+ elsif status >= 400 && status < 500
327
+ _, request_uri, _, _ = request
328
+ raise ClientError,
329
+ "Could not retrieve discovery document at: #{request_uri}"
330
+ elsif status >= 500 && status < 600
331
+ _, request_uri, _, _ = request
332
+ raise ServerError,
333
+ "Could not retrieve discovery document at: #{request_uri}"
334
+ elsif status > 600
335
+ _, request_uri, _, _ = request
332
336
  raise TransmissionError,
333
337
  "Could not retrieve discovery document at: #{request_uri}"
334
338
  end
@@ -344,7 +348,7 @@ module Google
344
348
  document_base = self.directory_uri
345
349
  if self.directory_document && self.directory_document['items']
346
350
  self.directory_document['items'].map do |discovery_document|
347
- ::Google::APIClient::API.new(
351
+ Google::APIClient::API.new(
348
352
  document_base,
349
353
  discovery_document
350
354
  )
@@ -373,7 +377,7 @@ module Google
373
377
  document_base = self.discovery_uri(api, version)
374
378
  discovery_document = self.discovery_document(api, version)
375
379
  if document_base && discovery_document
376
- ::Google::APIClient::API.new(
380
+ Google::APIClient::API.new(
377
381
  document_base,
378
382
  discovery_document
379
383
  )
@@ -442,8 +446,6 @@ module Google
442
446
  # - <code>:version</code> —
443
447
  # The service version. Only used if <code>api_method</code> is a
444
448
  # <code>String</code>. Defaults to <code>'v1'</code>.
445
- # - <code>:parser</code> —
446
- # The parser for the response.
447
449
  # - <code>:authorization</code> —
448
450
  # The authorization mechanism for the response. Used only if
449
451
  # <code>:authenticated</code> is <code>true</code>.
@@ -457,17 +459,22 @@ module Google
457
459
  #
458
460
  # @example
459
461
  # request = client.generate_request(
460
- # 'chili.activities.list',
461
- # {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'}
462
+ # :api_method => 'chili.activities.list',
463
+ # :parameters =>
464
+ # {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'}
462
465
  # )
463
466
  # method, uri, headers, body = request
464
- def generate_request(
465
- api_method, parameters={}, body='', headers=[], options={})
467
+ def generate_request(options={})
468
+ # Note: The merge method on a Hash object will coerce an API Reference
469
+ # object into a Hash and merge with the default options.
466
470
  options={
467
- :parser => self.parser,
468
471
  :version => 'v1',
469
- :authorization => self.authorization
472
+ :authorization => self.authorization,
473
+ :key => self.key,
474
+ :user_ip => self.user_ip
470
475
  }.merge(options)
476
+ # The Reference object is going to need this to do method ID lookups.
477
+ options[:client] = self
471
478
  # The default value for the :authenticated option depends on whether an
472
479
  # authorization mechanism has been set.
473
480
  if options[:authorization]
@@ -475,27 +482,8 @@ module Google
475
482
  else
476
483
  options = {:authenticated => false}.merge(options)
477
484
  end
478
- if api_method.kind_of?(String) || api_method.kind_of?(Symbol)
479
- api_method = api_method.to_s
480
- # This method of guessing the API is unreliable. This will fail for
481
- # APIs where the first segment of the RPC name does not match the
482
- # service name. However, this is a fallback mechanism anyway.
483
- # Developers should be passing in a reference to the method, rather
484
- # than passing in a string or symbol. This should raise an error
485
- # in the case of a mismatch.
486
- api = api_method[/^([^.]+)\./, 1]
487
- api_method = self.discovered_method(
488
- api_method, api, options[:version]
489
- )
490
- elsif !api_method.kind_of?(::Google::APIClient::Method)
491
- raise TypeError,
492
- "Expected String, Symbol, or Google::APIClient::Method, " +
493
- "got #{api_method.class}."
494
- end
495
- unless api_method
496
- raise ArgumentError, "API method could not be found."
497
- end
498
- request = api_method.generate_request(parameters, body, headers)
485
+ reference = Google::APIClient::Reference.new(options)
486
+ request = reference.to_request
499
487
  if options[:authenticated]
500
488
  request = self.generate_authenticated_request(:request => request)
501
489
  end
@@ -503,47 +491,13 @@ module Google
503
491
  end
504
492
 
505
493
  ##
506
- # Generates a request and transmits it.
507
- #
508
- # @param [Google::APIClient::Method, String] api_method
509
- # The method object or the RPC name of the method being executed.
510
- # @param [Hash, Array] parameters
511
- # The parameters to send to the method.
512
- # @param [String] body The body of the request.
513
- # @param [Hash, Array] headers The HTTP headers for the request.
514
- # @param [Hash] options
515
- # The configuration parameters for the request.
516
- # - <code>:version</code> —
517
- # The service version. Only used if <code>api_method</code> is a
518
- # <code>String</code>. Defaults to <code>'v1'</code>.
519
- # - <code>:adapter</code> —
520
- # The HTTP adapter.
521
- # - <code>:parser</code> —
522
- # The parser for the response.
523
- # - <code>:authorization</code> —
524
- # The authorization mechanism for the response. Used only if
525
- # <code>:authenticated</code> is <code>true</code>.
526
- # - <code>:authenticated</code> —
527
- # <code>true</code> if the request must be signed or otherwise
528
- # authenticated, <code>false</code>
529
- # otherwise. Defaults to <code>true</code>.
494
+ # Signs a request using the current authorization mechanism.
530
495
  #
531
- # @return [Array] The response from the API.
496
+ # @param [Hash] options The options to pass through.
532
497
  #
533
- # @example
534
- # response = client.execute(
535
- # 'chili.activities.list',
536
- # {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'}
537
- # )
538
- # status, headers, body = response
539
- def execute(api_method, parameters={}, body='', headers=[], options={})
540
- request = self.generate_request(
541
- api_method, parameters, body, headers, options
542
- )
543
- return self.transmit_request(
544
- request,
545
- options[:adapter] || self.http_adapter
546
- )
498
+ # @return [Array] The signed or otherwise authenticated request.
499
+ def generate_authenticated_request(options={})
500
+ return authorization.generate_authenticated_request(options)
547
501
  end
548
502
 
549
503
  ##
@@ -553,7 +507,7 @@ module Google
553
507
  # @param [#transmit] adapter The HTTP adapter.
554
508
  #
555
509
  # @return [Array] The response from the server.
556
- def transmit_request(request, adapter=self.http_adapter)
510
+ def transmit(request, adapter=self.http_adapter)
557
511
  if self.user_agent != nil
558
512
  # If there's no User-Agent header, set one.
559
513
  method, uri, headers, body = request
@@ -577,13 +531,89 @@ module Google
577
531
  end
578
532
 
579
533
  ##
580
- # Signs a request using the current authorization mechanism.
534
+ # Executes a request, wrapping it in a Result object.
581
535
  #
582
- # @param [Hash] options The options to pass through.
536
+ # @param [Google::APIClient::Method, String] api_method
537
+ # The method object or the RPC name of the method being executed.
538
+ # @param [Hash, Array] parameters
539
+ # The parameters to send to the method.
540
+ # @param [String] body The body of the request.
541
+ # @param [Hash, Array] headers The HTTP headers for the request.
542
+ # @param [Hash] options
543
+ # The configuration parameters for the request.
544
+ # - <code>:version</code> —
545
+ # The service version. Only used if <code>api_method</code> is a
546
+ # <code>String</code>. Defaults to <code>'v1'</code>.
547
+ # - <code>:adapter</code> —
548
+ # The HTTP adapter.
549
+ # - <code>:authorization</code> —
550
+ # The authorization mechanism for the response. Used only if
551
+ # <code>:authenticated</code> is <code>true</code>.
552
+ # - <code>:authenticated</code> —
553
+ # <code>true</code> if the request must be signed or otherwise
554
+ # authenticated, <code>false</code>
555
+ # otherwise. Defaults to <code>true</code>.
583
556
  #
584
- # @return [Array] The signed or otherwise authenticated request.
585
- def generate_authenticated_request(options={})
586
- return authorization.generate_authenticated_request(options)
557
+ # @return [Array] The response from the API.
558
+ #
559
+ # @example
560
+ # request = client.generate_request(
561
+ # :api_method => 'chili.activities.list',
562
+ # :parameters =>
563
+ # {'scope' => '@self', 'userId' => '@me', 'alt' => 'json'}
564
+ # )
565
+ def execute(*params)
566
+ # This block of code allows us to accept multiple parameter passing
567
+ # styles, and maintaining some backwards compatibility.
568
+ #
569
+ # Note: I'm extremely tempted to deprecate this style of execute call.
570
+ if params.last.respond_to?(:to_hash) && params.size == 1
571
+ options = params.pop
572
+ else
573
+ options = {}
574
+ end
575
+ options[:api_method] = params.shift if params.size > 0
576
+ options[:parameters] = params.shift if params.size > 0
577
+ options[:merged_body] = params.shift if params.size > 0
578
+ options[:headers] = params.shift if params.size > 0
579
+ options[:client] = self
580
+
581
+ reference = Google::APIClient::Reference.new(options)
582
+ request = self.generate_request(reference)
583
+ response = self.transmit(
584
+ request,
585
+ options[:adapter] || self.http_adapter
586
+ )
587
+ return Google::APIClient::Result.new(reference, request, response)
588
+ end
589
+
590
+ ##
591
+ # Same as Google::APIClient#execute, but raises an exception if there was
592
+ # an error.
593
+ #
594
+ # @see Google::APIClient#execute
595
+ def execute!(*params)
596
+ result = self.execute(*params)
597
+ status, _, _ = result.response
598
+ if result.data.respond_to?(:error) &&
599
+ result.data.error.respond_to?(:message)
600
+ # You're going to get a terrible error message if the response isn't
601
+ # parsed successfully as an error.
602
+ error_message = result.data.error.message
603
+ elsif result.data['error'] && result.data['error']['message']
604
+ error_message = result.data['error']['message']
605
+ end
606
+ if status >= 400 && status < 500
607
+ raise ClientError,
608
+ error_message || "A client error has occurred."
609
+ elsif status >= 500 && status < 600
610
+ raise ServerError,
611
+ error_message || "A server error has occurred."
612
+ elsif status > 600
613
+ raise TransmissionError,
614
+ error_message || "A transmission error has occurred."
615
+ end
616
+ return result
587
617
  end
588
618
  end
589
619
  end