Skip to content

Instantly share code, notes, and snippets.

@cblunt
Created February 14, 2014 07:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cblunt/8997077 to your computer and use it in GitHub Desktop.
Save cblunt/8997077 to your computer and use it in GitHub Desktop.
Quick script to recursively copy files from 1 folder to another on Rackspace Cloudfiles
require 'rubygems'
require 'fog'
# Configuration
CONTAINER_NAME = "your_container_name"
IGNORE_TYPES = ["application/directory"]
MAX_TRIES = 3
CF_USERNAME = "your_rackspace_username"
CF_API_KEY = "your_rackspace_api_key"
SRC_PATH = "staging" # Currently supports only the 1st-level folder, e.g. "[staging]/uploads/photos/1/image.jpg"
DEST_PATH = "production" # Copy from "staging/uploads/photos/1/image.jpg TO production/uploads/photos/1/image.jpg"
# Helper class for virtual path hierarchy
class FilePath
@@delimiter = "/"
def initialize(file)
@path = file.key
@segments = @path.split("/")
end
def path(start_depth = 0)
@segments[start_depth..@segments.length-1].join(@@delimiter)
end
def segments(start_depth = 0)
@segments[start_depth..@segments.length-1]
end
end
# Configured for UK authentication
service = Fog::Storage.new({
provider: 'Rackspace',
rackspace_username: CF_USERNAME,
rackspace_api_key: CF_API_KEY,
rackspace_auth_url: Fog::Rackspace::UK_AUTH_ENDPOINT,
rackspace_region: :lon,
rackspace_servicenet: true
})
directory = service.directories.get CONTAINER_NAME
files = directory.files.all
files.each do |file|
fp = FilePath.new(file)
if fp.segments.first == SRC_PATH
# check if a corresponding file exists in DEST_PATH
check_path = "#{DEST_PATH}/#{fp.path(1)}"
check_file = directory.files.head(check_path)
if check_file
puts "\t EXISTS #{fp.path} : #{check_file.key}"
elsif IGNORE_TYPES.include?(file.content_type)
puts "\t IGNORE #{fp.path} (#{file.content_type})"
else
print "\t COPY #{fp.path} => #{check_path} (#{file.content_type})... "
try = 0
begin
service.copy_object(CONTAINER_NAME, fp.path, CONTAINER_NAME, check_path)
puts "DONE"
rescue Excon::Errors::NotFound, Excon::Errors::Timeout, Fog::Storage::Rackspace::NotFound => e
if try == MAX_TRIES
$stderr.puts e.message
else
try += 1
puts "RETRY \##{try} of #{MAX_TRIES}"
retry
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment