Skip to content

Instantly share code, notes, and snippets.

@yong
Created April 11, 2012 19:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yong/2361625 to your computer and use it in GitHub Desktop.
Save yong/2361625 to your computer and use it in GitHub Desktop.
Ruby script to delete multiple objects from Amazon S3 (via new Multi-Object Delete operation api)
require 'happening'
# Example:
# EM.run do
# items = Happening::S3::ItemCollection.new 'bucket', ['key1', 'key2', ...], :aws_access_key_id => 'Your-ID', :aws_secret_access_key => 'secret'
# items.delete
# end
module Happening
#Monkey patch
class AWS
protected
alias old_canonical_request_description canonical_request_description
def canonical_request_description(method, path, headers = {}, expires = nil)
description = old_canonical_request_description(method, path, headers, expires)
description << '?delete' if path[/[&?]delete($|&|=)/]
description
end
end
module S3
#Monkey patch
class Request
protected
def validate
end
end
class ItemCollection < Item
MULTIPLE_DELETE_LIMIT = 1000
def initialize(bucket, keys, options = {})
super bucket, "NO_USE", options
@keys = keys
end
def path(with_bucket=true)
with_bucket ? "/#{bucket}/?delete" : "/?delete"
end
def delete request_options = {}, &blk
i = 0
while i < @keys.size
keys = @keys.slice(i, MULTIPLE_DELETE_LIMIT)
data = "<Delete><Quiet>true</Quiet><Object><Key>" + keys.join("</Key></Object><Object><Key>") + "</Key></Object></Delete>"
md5 = Base64.encode64(Digest::MD5.digest(data)).strip
headers = aws.sign("POST", path, {"Content-MD5" => md5})
request_options[:on_success] = blk if blk
request_options.update(:headers => headers, :data => data)
Happening::S3::Request.new(:post, url, {:ssl => options[:ssl]}.update(request_options)).execute
i += MULTIPLE_DELETE_LIMIT
end
end
end
end
end
if $0 == __FILE__
if ARGV.length <= 3
puts "Usage:"
puts "s3_multi_object_delete.rb bucket s3id s3key key1 key2..."
exit
end
keys = ARGV
bucket = keys[0]
s3id = keys[1]
s3key = keys[2]
keys.shift(3)
EM.run do
on_error = Proc.new {|response| puts "An error occured: #{response.response}"; EM.stop }
items = Happening::S3::ItemCollection.new bucket, keys, :aws_access_key_id => s3id, :aws_secret_access_key => s3key, :protocol => 'http'
items.delete(:on_error => on_error) do |response|
puts "Deleted!"
EM.stop
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment