Class: Google::APIClient::ResumableUpload

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

Overview

Resumable uploader.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(result, media, location) ⇒ ResumableUpload

Creates a new uploader.

Parameters:



52
53
54
55
56
57
58
59
60
61
# File 'lib/google/api_client/media.rb', line 52

def initialize(result, media, location)
  self.media = media
  self.location = location
  self.chunk_size = 256 * 1024
  
  @api_method = result.reference.api_method
  @result = result
  @offset = 0
  @complete = false
end

Instance Attribute Details

#chunk_sizeObject

Returns the value of attribute chunk_size.



39
40
41
# File 'lib/google/api_client/media.rb', line 39

def chunk_size
  @chunk_size
end

#clientObject

Returns the value of attribute client.



38
39
40
# File 'lib/google/api_client/media.rb', line 38

def client
  @client
end

#locationObject

Returns the value of attribute location.



41
42
43
# File 'lib/google/api_client/media.rb', line 41

def location
  @location
end

#mediaObject

Returns the value of attribute media.



40
41
42
# File 'lib/google/api_client/media.rb', line 40

def media
  @media
end

#resultObject (readonly)

Returns the value of attribute result.



37
38
39
# File 'lib/google/api_client/media.rb', line 37

def result
  @result
end

Instance Method Details

#complete?TrueClass, FalseClass

Check if upload is complete

Returns:

  • (TrueClass, FalseClass)

    Whether or not the upload complete successfully



109
110
111
# File 'lib/google/api_client/media.rb', line 109

def complete?
  return @complete
end

#expired?TrueClass, FalseClass

Check if the upload URL expired (upload not completed in alotted time.) Expired uploads must be restarted from the beginning

Returns:

  • (TrueClass, FalseClass)

    Whether or not the upload has expired and can not be resumed



119
120
121
# File 'lib/google/api_client/media.rb', line 119

def expired?
  return @result.status == 404 || @result.status == 410
end

#process_result(result) ⇒ Object

Check the result from the server, updating the offset and/or location if available.

Parameters:



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/google/api_client/media.rb', line 145

def process_result(result)
  case result.status
  when 200...299
    @complete = true
    if @api_method
      # Inject the original API method so data is parsed correctly
      result.reference.api_method = @api_method
    end
    return result
  when 308
    range = result.headers['range']
    if range
      @offset = range.scan(/\d+/).collect{|x| Integer(x)}.last + 1
    end
    if result.headers['location']
      self.location = result.headers['location']
    end
  when 500...599
    # Invalidate the offset to mark it needs to be queried on the
    # next request
    @offset = nil
  end
  return nil
end

#resync_range(api_client) ⇒ Object

Get the last saved range from the server in case an error occurred and the offset is not known.

Parameters:



129
130
131
132
133
134
135
136
137
# File 'lib/google/api_client/media.rb', line 129

def resync_range(api_client)
  r = api_client.execute(
    :uri => self.location,
    :http_method => :put,
    :headers => { 
      'Content-Length' => "0", 
      'Content-Range' => "bytes */#{media.length}" })
  return process_result(r)
end

#send_all(api_client) ⇒ Object

Sends all remaining chunks to the server

Parameters:



68
69
70
71
72
73
74
# File 'lib/google/api_client/media.rb', line 68

def send_all(api_client)
  until complete?
    send_chunk(api_client)
    break unless result.status == 308
  end
  return result
end

#send_chunk(api_client) ⇒ Object

Sends the next chunk to the server

Parameters:



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/google/api_client/media.rb', line 82

def send_chunk(api_client)
  if @offset.nil?
    return resync_range(api_client)
  end

  start_offset = @offset
  self.media.io.pos = start_offset
  chunk = self.media.io.read(chunk_size)
  content_length = chunk.bytesize

  end_offset = start_offset + content_length - 1
  @result = api_client.execute(
    :uri => self.location,
    :http_method => :put,
    :headers => {
      'Content-Length' => "#{content_length}",
      'Content-Type' => self.media.content_type, 
      'Content-Range' => "bytes #{start_offset}-#{end_offset}/#{media.length}" },
    :body => chunk)
  return process_result(@result)
end