1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00
fog--fog/lib/fog/rackspace/examples/storage/upload_large_files.rb

99 lines
No EOL
3.1 KiB
Ruby

#!/usr/bin/env ruby
# This example demonstrates uploading large files in segments
require 'rubygems' #required for Ruby 1.8.x
require 'fog'
# Size of segment. The Rackspace cloud currently requires files larger than 5GB to be segmented so we will choose 5GB -1 for a size
# http://docs.rackspace.com/files/api/v1/cf-devguide/content/Large_Object_Creation-d1e2019.html
SEGMENT_LIMIT = 5368709119.0
# Size of buffer to use for transfers. Use Excon's default chunk size and if that's not avaliable we will default to 1 MB
BUFFER_SIZE = Excon.defaults[:chunk_size] || 1024 * 1024
def get_user_input(prompt)
print "\n#{prompt}: "
gets.chomp
end
def select_directory(directories)
abort "\nThere are not any directories in the Chicago region. Try running create_private_directory.rb\n\n" if directories.empty?
puts "\nSelect Directory:\n\n"
directories.each_with_index do |dir, i|
puts "\t #{i}. #{dir.key} [#{dir.count} objects]"
end
select_str = get_user_input "Enter Directory Number"
directories[select_str.to_i]
end
# Use username defined in ~/.fog file, if absent prompt for username.
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_username
Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username")
end
# Use api key defined in ~/.fog file, if absent prompt for api key
# For more details on ~/.fog refer to http://fog.io/about/getting_started.html
def rackspace_api_key
Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key")
end
# create Cloud Files service
service = Fog::Storage.new({
:provider => 'Rackspace',
:rackspace_username => rackspace_username,
:rackspace_api_key => rackspace_api_key,
:rackspace_region => :ord
})
# retrieve directories with files
directories = service.directories
# prompt for directory
directory = select_directory(directories)
# prompt for file name
file_name = get_user_input "Enter full path of file to upload"
segment_name = File.basename(file_name)
File.open(file_name) do |f|
num_segments = (f.size / SEGMENT_LIMIT).round + 1
puts "\nThis upload of '#{file_name}' will require #{num_segments} segment(s) and 1 manifest file\n"
1.upto(num_segments) do |segment|
print "\n\tUploading segment #{segment} "
offset = 0
read = 0
service.put_object(directory.key, "#{segment_name}/#{segment}", nil, options = {}) do
if (offset < SEGMENT_LIMIT) && (read.zero? || read == BUFFER_SIZE)
print "."
buf = f.sysread(BUFFER_SIZE)
read = buf.size
offset += read
buf
else
""
end
end
end
end
puts "\n\n\tWriting manifest #{segment_name}\n\n"
service.put_object_manifest(directory.key, segment_name)
puts <<-NOTE
You should now be able to download #{segment_name} from the cloud control panel or using the following code:
directory = service.directories.get('#{directory.key}')
File.open('downloaded_#{segment_name}', 'w') do | f |
directory.files.get(#{segment_name}) do | data, remaining, content_length |
print "."
f.syswrite data
end
end
NOTE