Class: CloudFiles::Container

Inherits:
Object
  • Object
show all
Defined in:
lib/cloudfiles/container.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, name) ⇒ Container

Retrieves an existing CloudFiles::Container object tied to the current CloudFiles::Connection. If the requested container does not exist, it will raise a CloudFiles::Exception::NoSuchContainer Exception.

Will likely not be called directly, instead use connection.container(‘container_name’) to retrieve the object.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/cloudfiles/container.rb', line 16

def initialize(connection, name)
  @connection = connection
  @name = name
  @storagehost = self.connection.storagehost
  @storagepath = self.connection.storagepath + "/" + CloudFiles.escape(@name)
  @storageport = self.connection.storageport
  @storagescheme = self.connection.storagescheme
  @cdnmgmthost = self.connection.cdnmgmthost
  @cdnmgmtpath = self.connection.cdnmgmtpath + "/" + CloudFiles.escape(@name) if self.connection.cdnmgmtpath
  @cdnmgmtport = self.connection.cdnmgmtport
  @cdnmgmtscheme = self.connection.cdnmgmtscheme
  # Load the metadata now, so we'll get a CloudFiles::Exception::NoSuchContainer exception should the container
  # not exist.
  self.
end

Instance Attribute Details

#connectionObject (readonly)

The parent CloudFiles::Connection object for this container



10
11
12
# File 'lib/cloudfiles/container.rb', line 10

def connection
  @connection
end

#nameObject (readonly)

Name of the container which corresponds to the instantiated container class



7
8
9
# File 'lib/cloudfiles/container.rb', line 7

def name
  @name
end

Instance Method Details

#bytesObject

Size of the container (in bytes)



75
76
77
# File 'lib/cloudfiles/container.rb', line 75

def bytes
  self.[:bytes]
end

#cdn_enabledObject Also known as: cdn_enabled?, public?

Returns true if the container is public and CDN-enabled. Returns false otherwise.

Aliased as container.public?

public_container.cdn_enabled?
=> true

private_container.public?
=> false


93
94
95
# File 'lib/cloudfiles/container.rb', line 93

def cdn_enabled
  self.[:cdn_enabled]
end

#cdn_logObject Also known as: log_retention?, cdn_log?

Returns true if log retention is enabled on this container, false otherwise



120
121
122
# File 'lib/cloudfiles/container.rb', line 120

def cdn_log
  self.[:cdn_log]
end

#cdn_metadataObject

Retrieves CDN-Enabled Meta Data



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/cloudfiles/container.rb', line 59

def 
  @cdn_metadata ||= (
    response = self.connection.cfreq("HEAD", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme)
    cdn_enabled = ((response["x-cdn-enabled"] || "").downcase == "true") ? true : false
    {
      :cdn_enabled => cdn_enabled,
      :cdn_ttl => cdn_enabled ? response["x-ttl"].to_i : nil,
      :cdn_url => cdn_enabled ? response["x-cdn-uri"] : nil,
      :user_agent_acl => response["x-user-agent-acl"],
      :referrer_acl => response["x-referrer-acl"],
      :cdn_log => (cdn_enabled and response["x-log-retention"] == "True") ? true : false
    }
  )
end

#cdn_ttlObject

CDN container TTL (if container is public)



100
101
102
# File 'lib/cloudfiles/container.rb', line 100

def cdn_ttl
  self.[:cdn_ttl]
end

#cdn_urlObject

CDN container URL (if container if public)



105
106
107
# File 'lib/cloudfiles/container.rb', line 105

def cdn_url
  self.[:cdn_url]
end

#countObject

Number of objects in the container



80
81
82
# File 'lib/cloudfiles/container.rb', line 80

def count
  self.[:count]
end

#create_object(objectname, make_path = false) ⇒ Object

Creates a new CloudFiles::StorageObject in the current container.

If an object with the specified name exists in the current container, that object will be returned. Otherwise, an empty new object will be returned.

Passing in the optional make_path argument as true will create zero-byte objects to simulate a filesystem path to the object, if an objectname with path separators (“/path/to/myfile.mp3”) is supplied. These path objects can be used in the Container.objects method.



253
254
255
# File 'lib/cloudfiles/container.rb', line 253

def create_object(objectname, make_path = false)
  CloudFiles::StorageObject.new(self, objectname, false, make_path)
end

#delete_object(objectname) ⇒ Object

Removes an CloudFiles::StorageObject from a container. True is returned if the removal is successful. Throws NoSuchObjectException if the object doesn’t exist. Throws InvalidResponseException if the request fails.

container.delete_object('new.txt')
=> true

container.delete_object('nonexistent_file.txt')
=> NoSuchObjectException: Object nonexistent_file.txt does not exist


265
266
267
268
269
270
# File 'lib/cloudfiles/container.rb', line 265

def delete_object(objectname)
  response = self.connection.cfreq("DELETE", @storagehost, "#{@storagepath}/#{CloudFiles.escape objectname}", @storageport, @storagescheme)
  raise CloudFiles::Exception::NoSuchObject, "Object #{objectname} does not exist" if (response.code == "404")
  raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code =~ /^20/)
  true
end

#empty?Boolean

Returns true if a container is empty and returns false otherwise.

new_container.empty?
=> true

full_container.empty?
=> false

Returns:

  • (Boolean)


229
230
231
# File 'lib/cloudfiles/container.rb', line 229

def empty?
  return ([:count].to_i == 0)? true : false
end

#log_retention=(value) ⇒ Object

Change the log retention status for this container. Values are true or false.

These logs will be periodically (at unpredictable intervals) compressed and uploaded to a “.CDN_ACCESS_LOGS” container in the form of “container_name.YYYYMMDDHH-XXXX.gz”.



130
131
132
133
134
# File 'lib/cloudfiles/container.rb', line 130

def log_retention=(value)
  response = self.connection.cfreq("POST", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme, {"x-log-retention" => value.to_s.capitalize})
  raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "201" or response.code == "202")
  return true
end

#make_privateObject

Makes a container private and returns true upon success. Throws NoSuchContainerException if the container doesn’t exist or if the request fails.

Note that if the container was previously public, it will continue to exist out on the CDN until it expires.

container.make_private
=> true


311
312
313
314
315
316
317
# File 'lib/cloudfiles/container.rb', line 311

def make_private
  headers = { "X-CDN-Enabled" => "False" }
  response = self.connection.cfreq("POST", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme, headers)
  raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202")
  refresh
  true
end

#make_public(options = {:ttl => 86400}) ⇒ Object

Makes a container publicly available via the Cloud Files CDN and returns true upon success. Throws NoSuchContainerException if the container doesn’t exist or if the request fails.

Takes an optional hash of options, including:

:ttl, which is the CDN cache TTL in seconds (default 86400 seconds or 1 day, minimum 3600 or 1 hour, maximum 259200 or 3 days)

:user_agent_acl, a Perl-compatible regular expression limiting access to this container to user agents matching the given regular expression

:referrer_acl, a Perl-compatible regular expression limiting access to this container to HTTP referral URLs matching the given regular expression

container.make_public(:ttl => 8900, :user_agent_acl => "/Mozilla/", :referrer_acl => "/^http://rackspace.com")
=> true


285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/cloudfiles/container.rb', line 285

def make_public(options = {:ttl => 86400})
  if options.is_a?(Fixnum)
    print "DEPRECATED: make_public takes a hash of options now, instead of a TTL number"
    ttl = options
    options = {:ttl => ttl}
  end

  response = self.connection.cfreq("PUT", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme)
  raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202")

  headers = { "X-TTL" => options[:ttl].to_s , "X-CDN-Enabled" => "True" }
  headers["X-User-Agent-ACL"] = options[:user_agent_acl] if options[:user_agent_acl]
  headers["X-Referrer-ACL"] = options[:referrer_acl] if options[:referrer_acl]
  response = self.connection.cfreq("POST", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme, headers)
  raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code == "201" || response.code == "202")
  refresh
  true
end

#metadataObject

Retrieves Metadata for the container



50
51
52
53
54
55
56
# File 'lib/cloudfiles/container.rb', line 50

def 
  @metadata ||= (
    response = self.connection.cfreq("HEAD", @storagehost, @storagepath + "/", @storageport, @storagescheme)
    raise CloudFiles::Exception::NoSuchContainer, "Container #{@name} does not exist" unless (response.code =~ /^20/)
    {:bytes => response["x-container-bytes-used"].to_i, :count => response["x-container-object-count"].to_i}
  )
end

#object(objectname) ⇒ Object Also known as: get_object

Returns the CloudFiles::StorageObject for the named object. Refer to the CloudFiles::StorageObject class for available methods. If the object exists, it will be returned. If the object does not exist, a NoSuchObjectException will be thrown.

object = container.object('test.txt')
object.data
=> "This is test data"

object = container.object('newfile.txt')
=> NoSuchObjectException: Object newfile.txt does not exist


146
147
148
149
# File 'lib/cloudfiles/container.rb', line 146

def object(objectname)
  o = CloudFiles::StorageObject.new(self, objectname, true)
  return o
end

#object_exists?(objectname) ⇒ Boolean

Returns true if object exists and returns false otherwise.

container.object_exists?('goodfile.txt')
=> true

container.object_exists?('badfile.txt')
=> false

Returns:

  • (Boolean)


240
241
242
243
# File 'lib/cloudfiles/container.rb', line 240

def object_exists?(objectname)
  response = self.connection.cfreq("HEAD", @storagehost, "#{@storagepath}/#{CloudFiles.escape objectname}", @storageport, @storagescheme)
  return (response.code =~ /^20/)? true : false
end

#objects(params = {}) ⇒ Object Also known as: list_objects

Gathers a list of all available objects in the current container and returns an array of object names.

container = cf.container("My Container")
container.objects                     #=> [ "cat", "dog", "donkey", "monkeydir", "monkeydir/capuchin"]

Pass a limit argument to limit the list to a number of objects:

container.objects(:limit => 1)                  #=> [ "cat" ]

Pass an marker with or without a limit to start the list at a certain object:

container.objects(:limit => 1, :marker => 'dog')                #=> [ "donkey" ]

Pass a prefix to search for objects that start with a certain string:

container.objects(:prefix => "do")       #=> [ "dog", "donkey" ]

Only search within a certain pseudo-filesystem path:

container.objects(:path => 'monkeydir')     #=> ["monkeydir/capuchin"]

Only grab “virtual directories”, based on a single-character delimiter (no “directory” objects required):

container.objects(:delimiter => '/')      #=> ["monkeydir"]

All arguments to this method are optional.

Returns an empty array if no object exist in the container. Throws an InvalidResponseException if the request fails.



170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/cloudfiles/container.rb', line 170

def objects(params = {})
  params[:marker] ||= params[:offset] unless params[:offset].nil?
  query = []
  params.each do |param, value|
    if [:limit, :marker, :prefix, :path, :delimiter].include? param
      query << "#{param}=#{CloudFiles.escape(value.to_s)}"
    end
  end
  response = self.connection.cfreq("GET", @storagehost, "#{@storagepath}?#{query.join '&'}", @storageport, @storagescheme)
  return [] if (response.code == "204")
  raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "200")
  return CloudFiles.lines(response.body)
end

#objects_detail(params = {}) ⇒ Object Also known as: list_objects_info

Retrieves a list of all objects in the current container along with their size in bytes, hash, and content_type. If no objects exist, an empty hash is returned. Throws an InvalidResponseException if the request fails. Takes a parameter hash as an argument, in the same form as the objects method.

Returns a hash in the same format as the containers_detail from the CloudFiles class.

container.objects_detail
=> {"test.txt"=>{:content_type=>"application/octet-stream",
                 :hash=>"e2a6fcb4771aa3509f6b27b6a97da55b",
                 :last_modified=>Mon Jan 19 10:43:36 -0600 2009,
                 :bytes=>"16"},
    "new.txt"=>{:content_type=>"application/octet-stream",
                :hash=>"0aa820d91aed05d2ef291d324e47bc96",
                :last_modified=>Wed Jan 28 10:16:26 -0600 2009,
                :bytes=>"22"}
   }


201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/cloudfiles/container.rb', line 201

def objects_detail(params = {})
  params[:marker] ||= params[:offset] unless params[:offset].nil?
  query = ["format=xml"]
  params.each do |param, value|
    if [:limit, :marker, :prefix, :path, :delimiter].include? param
      query << "#{param}=#{CloudFiles.escape(value.to_s)}"
    end
  end
  response = self.connection.cfreq("GET", @storagehost, "#{@storagepath}?#{query.join '&'}", @storageport, @storagescheme)
  return {} if (response.code == "204")
  raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code == "200")
  doc = REXML::Document.new(response.body)
  detailhash = {}
  doc.elements.each("container/object") { |o|
    detailhash[o.elements["name"].text] = { :bytes => o.elements["bytes"].text, :hash => o.elements["hash"].text, :content_type => o.elements["content_type"].text, :last_modified => DateTime.parse(o.elements["last_modified"].text) }
  }
  doc = nil
  return detailhash
end

#purge_from_cdn(email = nil) ⇒ Object

Purges CDN Edge Cache for all objects inside of this container

:email, An valid email address or comma seperated

list of emails to be notified once purge is complete .

 container.purge_from_cdn
 => true

or 

 container.purge_from_cdn("[email protected]")
 => true

or

 container.purge_from_cdn("[email protected], [email protected]")
 => true


336
337
338
339
340
341
342
343
344
345
346
# File 'lib/cloudfiles/container.rb', line 336

def purge_from_cdn(email=nil)
    if email
        headers = {"X-Purge-Email" => email}
        response = self.connection.cfreq("DELETE", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme, headers)
        raise CloudFiles::Exception::Connection, "Error Unable to Purge Container: #{@name}" unless (response.code > "200" && response.code < "299")
    else
        response = self.connection.cfreq("DELETE", @cdnmgmthost, @cdnmgmtpath, @cdnmgmtport, @cdnmgmtscheme)
        raise CloudFiles::Exception::Connection, "Error Unable to Purge Container: #{@name}" unless (response.code > "200" && response.code < "299")
    true
    end
end

#referrer_aclObject

The container ACL on the site Referrer



115
116
117
# File 'lib/cloudfiles/container.rb', line 115

def referrer_acl
  self.[:referrer_acl]
end

#refreshObject Also known as: populate

Refreshes data about the container and populates class variables. Items are otherwise loaded in a lazy loaded fashion.

container.count
=> 2
[Upload new file to the container]
container.count
=> 2
container.populate
container.count
=> 3


43
44
45
46
# File 'lib/cloudfiles/container.rb', line 43

def refresh
  @metadata = @cdn_metadata = nil
  true
end

#to_sObject

:nodoc:



348
349
350
# File 'lib/cloudfiles/container.rb', line 348

def to_s # :nodoc:
  @name
end

#user_agent_aclObject

The container ACL on the User Agent



110
111
112
# File 'lib/cloudfiles/container.rb', line 110

def user_agent_acl
  self.[:user_agent_acl]
end