lib/fire_cloud_client.rb
# retrieve single file in a GCP bucket of a workspace and download locally to portal.  will perform a chunked download
# on files larger that 100 MB
#
# * *params*
#   - +workspace_namespace+ (String) => namespace of workspace
#   - +workspace_name+ (String) => name of workspace
#   - +filename+ (String) => name of file
#   - +destination+ (String) => destination path for downloaded file
#   - +opts+ (Hash) => extra options for signed_url, see
#     https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-storage/v0.23.2/google/cloud/storage/file?method=signed_url-instance
#
# * *return*
#   - +File+ object
retrieve single file in a GCP bucket of a workspace and download locally to portal.  will perform a chunked download
on files larger that 100 MB



*return
+File+ object
retrieve single file in a GCP bucket of a workspace and download locally to portal . will perform a chunked download on files larger that 100 MB * return + File + object
def download_workspace_file(workspace_namespace, workspace_name, filename, destination, opts={})
    file = self.get_workspace_file(workspace_namespace, workspace_name, filename)
    end_path = [destination, filename].join('/').gsub(/\/\//, '/')
    if filename.include?('/')
      path_parts = filename.split('/')
      path_parts.pop
      directory = File.join(destination, path_parts)
      FileUtils.mkdir_p directory
    end
    if file.size > 50.megabytes
      Rails.logger.info "Performing chunked download for #{filename} from #{workspace_namespace}/#{workspace_name}"
      if file.content_encoding == 'gzip'
        new_file = file.copy file.name + '.tmp'
        new_file.content_encoding = nil
        remote = new_file
      else
        remote = file
      end
      size_range = 0..remote.size
      local = File.new(end_path, 'wb')
      size_range.each_slice(50.megabytes) do |range|
        range_req = range.first..range.last
        merged_opts = opts.merge(range: range_req)
        buffer = remote.download merged_opts
        buffer.rewind
        local.write buffer.read
      end
      if file.content_encoding == 'gzip'
        remote.delete
      end
      Rails.logger.info "Chunked download for #{filename} from #{workspace_namespace}/#{workspace_name} complete"
      local
    else
      file.download end_path, opts
    end
  end
def download_workspace_file ( workspace_namespace , workspace_name , filename , destination , opts = { } ) file = self . get_workspace_file ( workspace_namespace , workspace_name , filename ) end_path = [ destination , filename ] . join ( '/' ) . gsub ( / \/ \/ / , '/' ) if filename . include? ( '/' ) path_parts = filename . split ( '/' ) path_parts . pop directory = File . join ( destination , path_parts ) FileUtils . mkdir_p directory end if file . size > 50 . megabytes Rails . logger . info "Performing chunked download for #{filename} from #{workspace_namespace}/#{workspace_name}" if file . content_encoding == 'gzip' new_file = file . copy file . name + '.tmp' new_file . content_encoding = nil remote = new_file else remote = file end size_range = 0 .. remote . size local = File . new ( end_path , 'wb' ) size_range . each_slice ( 50 . megabytes ) do | range | range_req = range . first .. range . last merged_opts = opts . merge ( range : range_req ) buffer = remote . download merged_opts buffer . rewind local . write buffer . read end if file . content_encoding == 'gzip' remote . delete end Rails . logger . info "Chunked download for #{filename} from #{workspace_namespace}/#{workspace_name} complete" local else file . download end_path , opts end end
retrieve single file in a GCP bucket of a workspace and download locally to portal.
retrieve single file in a GCP bucket of a workspace and download locally to portal .
# create a valid path by combining destination directory and filename, making sure no double / exist # gotcha in case file is in a subdirectory # determine if a chunked download is needed # we need to determine whether or not this file has been gzipped - if so, we have to make a copy and unset the # gzip content-encoding as we cannot do range requests on gzipped data # clean up the temp copy # return newly-opened file (will need to check content type before attempting to parse)
workspace_namespace
<not_specific>
workspace_name
<not_specific>
filename
<not_specific>
destination
<not_specific>
opts
<not_specific>