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
31
32
# 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
  if self.connection.cdn_available?
    @cdnmgmthost = self.connection.cdnmgmthost
    @cdnmgmtpath = self.connection.cdnmgmtpath + "/" + CloudFiles.escape(@name) if self.connection.cdnmgmtpath
    @cdnmgmtport = self.connection.cdnmgmtport
    @cdnmgmtscheme = self.connection.cdnmgmtscheme
  end
  # 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)



83
84
85
# File 'lib/cloudfiles/container.rb', line 83

def bytes
  self.[:bytes]
end

#cdn_available?Boolean

Returns:

  • (Boolean)


369
370
371
# File 'lib/cloudfiles/container.rb', line 369

def cdn_available?
  self.connection.cdn_available?
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


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

def cdn_enabled
  cdn_available? && 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



133
134
135
# File 'lib/cloudfiles/container.rb', line 133

def cdn_log
  self.[:cdn_log]
end

#cdn_metadataObject

Retrieves CDN-Enabled Meta Data



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/cloudfiles/container.rb', line 61

def 
  return @cdn_metadata if @cdn_metadata
  if cdn_available?
    @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,
        :cdn_ssl_url => cdn_enabled ? response["x-cdn-ssl-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
      }
    )
  else
    @cdn_metadata = {}
  end
end

#cdn_ssl_urlObject

CDN SSL container URL (if container is public)



118
119
120
# File 'lib/cloudfiles/container.rb', line 118

def cdn_ssl_url
  self.[:cdn_ssl_url]
end

#cdn_ttlObject

CDN container TTL (if container is public)



108
109
110
# File 'lib/cloudfiles/container.rb', line 108

def cdn_ttl
  self.[:cdn_ttl]
end

#cdn_urlObject

CDN container URL (if container is public)



113
114
115
# File 'lib/cloudfiles/container.rb', line 113

def cdn_url
  self.[:cdn_url]
end

#countObject

Number of objects in the container



88
89
90
# File 'lib/cloudfiles/container.rb', line 88

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.



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

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


279
280
281
282
283
284
# File 'lib/cloudfiles/container.rb', line 279

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)


243
244
245
# File 'lib/cloudfiles/container.rb', line 243

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”.



143
144
145
146
147
148
# File 'lib/cloudfiles/container.rb', line 143

def log_retention=(value)
  raise Exception::CDNNotAvailable unless cdn_available?
  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


326
327
328
329
330
331
332
333
# File 'lib/cloudfiles/container.rb', line 326

def make_private
  raise Exception::CDNNotAvailable unless cdn_available?
  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


299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/cloudfiles/container.rb', line 299

def make_public(options = {:ttl => 86400})
  raise Exception::CDNNotAvailable unless cdn_available?
  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



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

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


160
161
162
163
# File 'lib/cloudfiles/container.rb', line 160

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)


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

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.



184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/cloudfiles/container.rb', line 184

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"}
   }


215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/cloudfiles/container.rb', line 215

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


352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/cloudfiles/container.rb', line 352

def purge_from_cdn(email=nil)
  raise Exception::CDNNotAvailable unless cdn_available?
  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



128
129
130
# File 'lib/cloudfiles/container.rb', line 128

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


45
46
47
48
# File 'lib/cloudfiles/container.rb', line 45

def refresh
  @metadata = @cdn_metadata = nil
  true
end

#to_sObject

:nodoc:



365
366
367
# File 'lib/cloudfiles/container.rb', line 365

def to_s # :nodoc:
  @name
end

#user_agent_aclObject

The container ACL on the User Agent



123
124
125
# File 'lib/cloudfiles/container.rb', line 123

def user_agent_acl
  self.[:user_agent_acl]
end