require 'json'
require 'stringio'
+require 'google/api_client/version'
require 'google/api_client/errors'
require 'google/api_client/environment'
require 'google/api_client/discovery'
require 'google/api_client/reference'
require 'google/api_client/result'
+
module Google
# TODO(bobaman): Document all this stuff.
# @option options [String] :host ("www.googleapis.com")
# The API hostname used by the client. This rarely needs to be changed.
# @option options [String] :application_name
- # The name and version of the application using the client. This should
- # be given in the form `"{name}/{version}"`.
+ # The name of the application using the client.
+ # @option options [String] :application_version
+ # The version number of the application using the client.
# @option options [String] :user_agent
# ("{app_name} google-api-ruby-client/{version} {os_name}/{os_version}")
# The user agent used by the client. Most developers will want to
self.host = options["host"] || 'www.googleapis.com'
# Most developers will want to leave this value alone and use the
# application_name option.
+ application_string = (
+ options["application_name"] ? (
+ "#{options["application_name"]}/" +
+ "#{options["application_version"] || '0.0.0'}"
+ ) : ""
+ )
self.user_agent = options["user_agent"] || (
- (options["application_name"] || '')
- 'google-api-ruby-client/' + VERSION::STRING +
- ' ' + ENV::OS_VERSION
+ "#{application_string} " +
+ "google-api-ruby-client/#{VERSION::STRING} " +
+ ENV::OS_VERSION
).strip
# The writer method understands a few Symbols and will generate useful
# default authentication mechanisms.
self.authorization = options["authorization"] || :oauth_2
+ self.key = options["key"]
+ self.user_ip = options["user_ip"]
# The HTTP adapter controls all of the HTTP traffic the client generates.
# By default, Net::HTTP is used, but adding support for other clients
# is trivial.
return @authorization
end
+ ##
+ # The application's API key issued by the API console.
+ #
+ # @return [String] The API key.
+ attr_accessor :key
+
+ ##
+ # The IP address of the user this request is being performed on behalf of.
+ #
+ # @return [String] The user's IP address.
+ attr_accessor :user_ip
+
##
# Returns the HTTP adapter used by the client.
#
# @return [Hash] The parsed JSON from the directory document.
def directory_document
return @directory_document ||= (begin
- request_uri = self.directory_uri
- request = ['GET', request_uri, [], []]
+ request = self.generate_request(
+ :http_method => 'GET',
+ :uri => self.directory_uri,
+ :authenticated => false
+ )
response = self.transmit(request)
status, headers, body = response
- if status == 200 # TODO(bobaman) Better status code handling?
+ if status >= 200 && status < 300
+ # TODO(bobaman) Better status code handling?
merged_body = body.inject(StringIO.new) do |accu, chunk|
accu.write(chunk)
accu
end
::JSON.parse(merged_body.string)
elsif status >= 400 && status < 500
+ _, request_uri, _, _ = request
raise ClientError,
"Could not retrieve discovery document at: #{request_uri}"
elsif status >= 500 && status < 600
+ _, request_uri, _, _ = request
raise ServerError,
"Could not retrieve discovery document at: #{request_uri}"
elsif status > 600
+ _, request_uri, _, _ = request
raise TransmissionError,
"Could not retrieve discovery document at: #{request_uri}"
end
api = api.to_s
version = version || 'v1'
return @discovery_documents["#{api}:#{version}"] ||= (begin
- request_uri = self.discovery_uri(api, version)
- request = ['GET', request_uri, [], []]
+ request = self.generate_request(
+ :http_method => 'GET',
+ :uri => self.discovery_uri(api, version),
+ :authenticated => false
+ )
response = self.transmit(request)
status, headers, body = response
- if status == 200 # TODO(bobaman) Better status code handling?
+ if status >= 200 && status < 300
+ # TODO(bobaman) Better status code handling?
merged_body = body.inject(StringIO.new) do |accu, chunk|
accu.write(chunk)
accu
end
::JSON.parse(merged_body.string)
elsif status >= 400 && status < 500
+ _, request_uri, _, _ = request
raise ClientError,
"Could not retrieve discovery document at: #{request_uri}"
elsif status >= 500 && status < 600
+ _, request_uri, _, _ = request
raise ServerError,
"Could not retrieve discovery document at: #{request_uri}"
elsif status > 600
+ _, request_uri, _, _ = request
raise TransmissionError,
"Could not retrieve discovery document at: #{request_uri}"
end
# object into a Hash and merge with the default options.
options={
:version => 'v1',
- :authorization => self.authorization
+ :authorization => self.authorization,
+ :key => self.key,
+ :user_ip => self.user_ip
}.merge(options)
# The Reference object is going to need this to do method ID lookups.
options[:client] = self
def execute!(*params)
result = self.execute(*params)
status, _, _ = result.response
- if result.data.respond_to?(:error)
+ if result.data.respond_to?(:error) &&
+ result.data.error.respond_to?(:message)
# You're going to get a terrible error message if the response isn't
# parsed successfully as an error.
- error_message = result.data.error
+ error_message = result.data.error.message
+ elsif result.data['error'] && result.data['error']['message']
+ error_message = result.data['error']['message']
end
if status >= 400 && status < 500
raise ClientError,