Class: Google::APIClient::Reference

Inherits:
Object
  • Object
show all
Defined in:
lib/google/api_client/reference.rb

Constant Summary collapse

MULTIPART_BOUNDARY =
"-----------RubyApiMultipartPost".freeze

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Reference

Returns a new instance of Reference.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/google/api_client/reference.rb', line 32

def initialize(options={})
  # We only need this to do lookups on method ID String values
  # It's optional, but method ID lookups will fail if the client is
  # omitted.
  @client = options[:client]
  @version = options[:version] || 'v1'

  self.connection = options[:connection] || Faraday.default_connection
  self.authorization = options[:authorization]
  self.api_method = options[:api_method]
  self.parameters = options[:parameters] || {}
  # These parameters are handled differently because they're not
  # parameters to the API method, but rather to the API system.
  if self.parameters.kind_of?(Array)
    if options[:key]
      self.parameters.reject! { |k, _| k == 'key' }
      self.parameters << ['key', options[:key]]
    end
    if options[:user_ip]
      self.parameters.reject! { |k, _| k == 'userIp' }
      self.parameters << ['userIp', options[:user_ip]]
    end
  elsif self.parameters.kind_of?(Hash)
    self.parameters['key'] ||= options[:key] if options[:key]
    self.parameters['userIp'] ||= options[:user_ip] if options[:user_ip]
    # Convert to Array, because they're easier to work with when
    # repeated parameters are an issue.
    self.parameters = self.parameters.to_a
  else
    raise TypeError,
      "Expected Array or Hash, got #{self.parameters.class}."
  end
  self.headers = options[:headers] || {}
  if options[:media]
    self.media = options[:media]
    upload_type = self.parameters.find { |(k, _)| ['uploadType', 'upload_type'].include?(k) }.last
    case upload_type
    when "media"
      if options[:body] || options[:body_object]
        raise ArgumentError,
          "Can not specify body & body object for simple uploads."
      end
      self.headers['Content-Type'] ||= self.media.content_type
      self.body = self.media
    when "multipart"
      unless options[:body_object]
        raise ArgumentError, "Multipart requested but no body object."
      end
      # This is all a bit of a hack due to Signet requiring body to be a
      # string. Ideally, update Signet to delay serialization so we can
      # just pass streams all the way down through to the HTTP library.
       = StringIO.new(serialize_body(options[:body_object]))
      env = {
        :request_headers => {
          'Content-Type' =>
            "multipart/related;boundary=#{MULTIPART_BOUNDARY}"
        },
        :request => {:boundary => MULTIPART_BOUNDARY}
      }
      multipart = Faraday::Request::Multipart.new
      self.body = multipart.create_multipart(env, [
        [nil, Faraday::UploadIO.new(
          , 'application/json', 'file.json'
        )],
        [nil, self.media]])
      self.headers.update(env[:request_headers])
    when "resumable"
      file_length = self.media.length
      self.headers['X-Upload-Content-Type'] = self.media.content_type
      self.headers['X-Upload-Content-Length'] = file_length.to_s
      if options[:body_object]
        self.headers['Content-Type'] ||= 'application/json'
        self.body = serialize_body(options[:body_object])
      else
        self.body = ''
      end
    else
      raise ArgumentError, "Invalid uploadType for media."
    end
  elsif options[:body]
    self.body = options[:body]
  elsif options[:body_object]
    self.headers['Content-Type'] ||= 'application/json'
    self.body = serialize_body(options[:body_object])
  else
    self.body = ''
  end
  unless self.api_method
    self.http_method = options[:http_method] || 'GET'
    self.uri = options[:uri]
    unless self.parameters.empty?
      query_values = (self.uri.query_values(Array) || [])
      self.uri.query = Addressable::URI.form_encode(
        (query_values + self.parameters).sort
      )
      self.uri.query = nil if self.uri.query == ""
    end
  end
end

Instance Method Details

#api_methodObject



168
169
170
# File 'lib/google/api_client/reference.rb', line 168

def api_method
  return @api_method
end

#api_method=(new_api_method) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/google/api_client/reference.rb', line 172

def api_method=(new_api_method)
  if new_api_method.kind_of?(Google::APIClient::Method) ||
      new_api_method == nil
    @api_method = new_api_method
  elsif new_api_method.respond_to?(:to_str) ||
      new_api_method.kind_of?(Symbol)
    unless @client
      raise ArgumentError,
        "API method lookup impossible without client instance."
    end
    new_api_method = new_api_method.to_s
    # This method of guessing the API is unreliable. This will fail for
    # APIs where the first segment of the RPC name does not match the
    # service name. However, this is a fallback mechanism anyway.
    # Developers should be passing in a reference to the method, rather
    # than passing in a string or symbol. This should raise an error
    # in the case of a mismatch.
    api = new_api_method[/^([^.]+)\./, 1]
    @api_method = @client.discovered_method(
      new_api_method, api, @version
    )
    if @api_method
      # Ditch the client reference, we won't need it again.
      @client = nil
    else
      raise ArgumentError, "API method could not be found."
    end
  else
    raise TypeError,
      "Expected Google::APIClient::Method, got #{new_api_method.class}."
  end
end

#authorizationObject



147
148
149
# File 'lib/google/api_client/reference.rb', line 147

def authorization
  return @authorization
end

#authorization=(new_authorization) ⇒ Object



151
152
153
# File 'lib/google/api_client/reference.rb', line 151

def authorization=(new_authorization)
  @authorization = new_authorization
end

#bodyObject



214
215
216
# File 'lib/google/api_client/reference.rb', line 214

def body
  return @body
end

#body=(new_body) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/google/api_client/reference.rb', line 218

def body=(new_body)
  if new_body.respond_to?(:to_str)
    @body = new_body.to_str
  elsif new_body.respond_to?(:read)
    @body = new_body.read()
  elsif new_body.respond_to?(:inject)
    @body = (new_body.inject(StringIO.new) do |accu, chunk|
      accu.write(chunk)
      accu
    end).string
  else
    raise TypeError,
      "Expected body to be String, IO, or Enumerable chunks."
  end
end

#connectionObject



155
156
157
# File 'lib/google/api_client/reference.rb', line 155

def connection
  return @connection
end

#connection=(new_connection) ⇒ Object



159
160
161
162
163
164
165
166
# File 'lib/google/api_client/reference.rb', line 159

def connection=(new_connection)
  if new_connection.kind_of?(Faraday::Connection)
    @connection = new_connection
  else
    raise TypeError,
      "Expected Faraday::Connection, got #{new_connection.class}."
  end
end

#headersObject



234
235
236
# File 'lib/google/api_client/reference.rb', line 234

def headers
  return @headers ||= {}
end

#headers=(new_headers) ⇒ Object



238
239
240
241
242
243
244
# File 'lib/google/api_client/reference.rb', line 238

def headers=(new_headers)
  if new_headers.kind_of?(Array) || new_headers.kind_of?(Hash)
    @headers = new_headers
  else
    raise TypeError, "Expected Hash or Array, got #{new_headers.class}."
  end
end

#http_methodObject



246
247
248
# File 'lib/google/api_client/reference.rb', line 246

def http_method
  return @http_method ||= self.api_method.http_method
end

#http_method=(new_http_method) ⇒ Object



250
251
252
253
254
255
256
257
258
259
# File 'lib/google/api_client/reference.rb', line 250

def http_method=(new_http_method)
  if new_http_method.kind_of?(Symbol)
    @http_method = new_http_method.to_s.upcase
  elsif new_http_method.respond_to?(:to_str)
    @http_method = new_http_method.to_str.upcase
  else
    raise TypeError,
      "Expected String or Symbol, got #{new_http_method.class}."
  end
end

#mediaObject



139
140
141
# File 'lib/google/api_client/reference.rb', line 139

def media
  return @media
end

#media=(media) ⇒ Object



143
144
145
# File 'lib/google/api_client/reference.rb', line 143

def media=(media)
  @media = (media)
end

#parametersObject



205
206
207
# File 'lib/google/api_client/reference.rb', line 205

def parameters
  return @parameters
end

#parameters=(new_parameters) ⇒ Object



209
210
211
212
# File 'lib/google/api_client/reference.rb', line 209

def parameters=(new_parameters)
  # No type-checking needed, the Method class handles this.
  @parameters = new_parameters
end

#serialize_body(body) ⇒ Object

Raises:

  • (TypeError)


132
133
134
135
136
137
# File 'lib/google/api_client/reference.rb', line 132

def serialize_body(body)
  return body.to_json if body.respond_to?(:to_json)
  return MultiJson.dump(options[:body_object].to_hash) if body.respond_to?(:to_hash)
  raise TypeError, 'Could not convert body object to JSON.' +
                   'Must respond to :to_json or :to_hash.'
end

#to_hashObject



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/google/api_client/reference.rb', line 286

def to_hash
  options = {}
  if self.api_method
    options[:api_method] = self.api_method
    options[:parameters] = self.parameters
  else
    options[:http_method] = self.http_method
    options[:uri] = self.uri
  end
  options[:headers] = self.headers
  options[:body] = self.body
  options[:connection] = self.connection
  unless self.authorization.nil?
    options[:authorization] = self.authorization
  end
  return options
end

#to_requestObject



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/google/api_client/reference.rb', line 269

def to_request
  if self.api_method
    return self.api_method.generate_request(
      self.parameters, self.body, self.headers,
      :connection => self.connection
    )
  else
    return self.connection.build_request(
      self.http_method.to_s.downcase.to_sym
    ) do |req|
      req.url(Addressable::URI.parse(self.uri).normalize.to_s)
      req.headers = Faraday::Utils::Headers.new(self.headers)
      req.body = self.body
    end
  end
end

#uriObject



261
262
263
# File 'lib/google/api_client/reference.rb', line 261

def uri
  return @uri ||= self.api_method.generate_uri(self.parameters)
end

#uri=(new_uri) ⇒ Object



265
266
267
# File 'lib/google/api_client/reference.rb', line 265

def uri=(new_uri)
  @uri = Addressable::URI.parse(new_uri)
end