Class: DropboxClient::ChunkedUploader

Inherits:
Object
  • Object
show all
Defined in:
lib/dropbox_sdk.rb

Overview

ChunkedUploader is responsible for uploading a large file to Dropbox in smaller chunks. This allows large files to be uploaded and makes allows recovery during failure.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, file_obj, total_size) ⇒ ChunkedUploader

Returns a new instance of ChunkedUploader.



843
844
845
846
847
848
849
# File 'lib/dropbox_sdk.rb', line 843

def initialize(client, file_obj, total_size)
  @client = client
  @file_obj = file_obj
  @total_size = total_size
  @upload_id = nil
  @offset = 0
end

Instance Attribute Details

#clientObject

Returns the value of attribute client.



841
842
843
# File 'lib/dropbox_sdk.rb', line 841

def client
  @client
end

#file_objObject

Returns the value of attribute file_obj.



841
842
843
# File 'lib/dropbox_sdk.rb', line 841

def file_obj
  @file_obj
end

#offsetObject

Returns the value of attribute offset.



841
842
843
# File 'lib/dropbox_sdk.rb', line 841

def offset
  @offset
end

#total_sizeObject

Returns the value of attribute total_size.



841
842
843
# File 'lib/dropbox_sdk.rb', line 841

def total_size
  @total_size
end

#upload_idObject

Returns the value of attribute upload_id.



841
842
843
# File 'lib/dropbox_sdk.rb', line 841

def upload_id
  @upload_id
end

Instance Method Details

#finish(to_path, overwrite = false, parent_rev = nil) ⇒ Object

Completes a file upload

Args:

  • to_path: The directory path to upload the file to. If the destination directory does not yet exist, it will be created.

  • overwrite: Whether to overwrite an existing file at the given path. [default is False] If overwrite is False and a file already exists there, Dropbox will rename the upload to make sure it doesn’t overwrite anything. You must check the returned metadata to know what this new name is. This field should only be True if your intent is to potentially clobber changes to a file that you don’t know about.

  • parent_rev: The rev field from the ‘parent’ of this upload. If your intent is to update the file at the given path, you should pass the parent_rev parameter set to the rev value from the most recent metadata you have of the existing file at that path. If the server has a more recent version of the file at the specified path, it will automatically rename your uploaded file, spinning off a conflict. Using this parameter effectively causes the overwrite parameter to be ignored. The file will always be overwritten if you send the most-recent parent_rev, and it will never be overwritten you send a less-recent one.

Returns:



916
917
918
919
# File 'lib/dropbox_sdk.rb', line 916

def finish(to_path, overwrite=false, parent_rev=nil)
  response = @client.commit_chunked_upload(to_path, @upload_id, overwrite, parent_rev)
  Dropbox::parse_response(response)
end

#upload(chunk_size = 4*1024*1024) ⇒ Object

Uploads data from this ChunkedUploader’s file_obj in chunks, until an error occurs. Throws an exception when an error occurs, and can be called again to resume the upload.

Args:

  • chunk_size: The chunk size for each individual upload. Defaults to 4MB.



857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
# File 'lib/dropbox_sdk.rb', line 857

def upload(chunk_size=4*1024*1024)
  last_chunk = nil

  while @offset < @total_size
    if not last_chunk
      last_chunk = @file_obj.read(chunk_size)
    end

    resp = {}
    begin
      resp = Dropbox::parse_response(@client.partial_chunked_upload(last_chunk, @upload_id, @offset))
      last_chunk = nil
    rescue SocketError => e
      raise e
    rescue SystemCallError => e
      raise e
    rescue DropboxError => e
      raise e if e.http_response.nil? or e.http_response.code[0] == '5'
      begin
        resp = JSON.parse(e.http_response.body)
        raise DropboxError.new('server response does not have offset key') unless resp.has_key? 'offset'
      rescue JSON::ParserError
        raise DropboxError.new("Unable to parse JSON response: #{e.http_response.body}")
      end
    end

    if resp.has_key? 'offset' and resp['offset'] > @offset
      @offset += (resp['offset'] - @offset) if resp['offset']
      last_chunk = nil
    end
    @upload_id = resp['upload_id'] if resp['upload_id']
  end
end