# bucket.rb module S3Lib class Bucket attr_reader :name, :xml, :prefix, :marker, :max_keys include S3Lib::AclAccess def self.create(name, params = {}) params['x-amz-acl'] = params.delete(:access) if params[:access] # translate from :access to 'x-amz-acl' response = self.bucket_request(:put, name, params) response.status[0] == "200" ? true : false end # passing :force => true will cause the bucket to be deleted even if it is not empty. def self.delete(name, params = {}) if params.delete(:force) self.delete_all(name, params) end response = self.bucket_request(:delete, name, params) end def delete(params = {}) self.class.delete(@name, @params.merge(params)) end def self.delete_all(name, params = {}) bucket = Bucket.find(name, params) bucket.delete_all end def delete_all objects.each do |object| object.delete end end def self.find(name, params = {}) response = self.bucket_request(:get, name, params) doc = REXML::Document.new(response) Bucket.new(doc, params) end def initialize(doc, params = {}) @xml = doc.root @params = params @name = @xml.elements['Name'].text @max_keys = @xml.elements['MaxKeys'].text.to_i @prefix = @xml.elements['Prefix'].text @marker = @xml.elements['Marker'].text end def is_truncated? @xml.elements['IsTruncated'].text == 'true' end def objects(params = {}) refresh if params[:refresh] @objects || get_objects end def refresh refreshed_bucket = Bucket.find(@name, @params) @xml = refreshed_bucket.xml @objects = nil end def url @name end # access an object in the bucket by key name def [](key) objects.detect{|object| object.key == key} end private def self.bucket_request(verb, name, params = {}) begin response = S3Lib.request(verb, name, params) rescue S3Lib::S3ResponseError => error case error.amazon_error_type when "NoSuchBucket": raise S3Lib::BucketNotFoundError.new("The bucket '#{name}' does not exist.", error.io, error.s3requester) when "NotSignedUp": raise S3Lib::NotYourBucketError.new("The bucket '#{name}' is owned by someone else.", error.io, error.s3requester) when "BucketNotEmpty": raise S3Lib::BucketNotEmptyError.new("The bucket '#{name}' is not empty, so you can't delete it.\nTry using Bucket.delete_all('#{name}') first, or Bucket.delete('#{name}', :force => true).", error.io, error.s3requester) else # Re-raise the error if it's not one of the above raise end end end def get_objects @objects = REXML::XPath.match(@xml, '//Contents').collect do |object| key = object.elements['Key'].text S3Lib::S3Object.new(self, key, :lazy_load => true) end end end end