Class: CloudFiles::StorageObject
- Inherits:
-
Object
- Object
- CloudFiles::StorageObject
- Defined in:
- lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb
Instance Attribute Summary collapse
-
#bytes ⇒ Object
readonly
Size of the object (in bytes).
-
#container ⇒ Object
readonly
The parent CloudFiles::Container object.
-
#content_type ⇒ Object
readonly
Content type of the object data.
-
#etag ⇒ Object
readonly
ETag of the object data.
-
#last_modified ⇒ Object
readonly
Date of the object’s last modification.
-
#name ⇒ Object
readonly
Name of the object corresponding to the instantiated object.
Instance Method Summary collapse
-
#data(size = -1,, offset = 0, headers = {}) ⇒ Object
Retrieves the data from an object and stores the data in memory.
-
#data_stream(size = -1,, offset = 0, headers = {}, &block) ⇒ Object
Retrieves the data from an object and returns a stream that must be passed to a block.
-
#initialize(container, objectname, force_exists = false, make_path = false) ⇒ StorageObject
constructor
Builds a new CloudFiles::StorageObject in the current container.
-
#load_from_filename(filename) ⇒ Object
A convenience method to stream data into an object from a local file (or anything that can be loaded by Ruby’s open method).
-
#metadata ⇒ Object
Returns the object’s metadata as a nicely formatted hash, stripping off the X-Meta-Object- prefix that the system prepends to the key name.
-
#populate ⇒ Object
(also: #refresh)
Caches data about the CloudFiles::StorageObject for fast retrieval.
-
#public_url ⇒ Object
If the parent container is public (CDN-enabled), returns the CDN URL to this object.
-
#save_to_filename(filename) ⇒ Object
A convenience method to stream data from an object into a local file.
-
#set_metadata(metadatahash) ⇒ Object
Sets the metadata for an object.
-
#to_s ⇒ Object
:nodoc:.
-
#write(data = nil, headers = {}) ⇒ Object
Takes supplied data and writes it to the object, saving it.
Constructor Details
#initialize(container, objectname, force_exists = false, make_path = false) ⇒ StorageObject
Builds a new CloudFiles::StorageObject in the current container. If force_exist is set, the object must exist or a NoSuchObjectException will be raised. If not, an “empty” CloudFiles::StorageObject will be returned, ready for data via CloudFiles::StorageObject.write
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 35 def initialize(container,objectname,force_exists=false,make_path=false) if objectname.match(/\?/) raise SyntaxException, "Object #{objectname} contains an invalid character in the name (? not allowed)" end @container = container @containername = container.name @name = objectname @make_path = make_path @storagehost = self.container.connection.storagehost @storagepath = self.container.connection.storagepath+"/#{@containername}/#{@name}" if container.object_exists?(objectname) populate else raise NoSuchObjectException, "Object #{@name} does not exist" if force_exists end end |
Instance Attribute Details
#bytes ⇒ Object (readonly)
Size of the object (in bytes)
18 19 20 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 18 def bytes @bytes end |
#container ⇒ Object (readonly)
The parent CloudFiles::Container object
21 22 23 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 21 def container @container end |
#content_type ⇒ Object (readonly)
Content type of the object data
30 31 32 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 30 def content_type @content_type end |
#etag ⇒ Object (readonly)
ETag of the object data
27 28 29 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 27 def etag @etag end |
#last_modified ⇒ Object (readonly)
Date of the object’s last modification
24 25 26 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 24 def last_modified @last_modified end |
#name ⇒ Object (readonly)
Name of the object corresponding to the instantiated object
15 16 17 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 15 def name @name end |
Instance Method Details
#data(size = -1,, offset = 0, headers = {}) ⇒ Object
Retrieves the data from an object and stores the data in memory. The data is returned as a string. Throws a NoSuchObjectException if the object doesn’t exist.
If the optional size and range arguments are provided, the call will return the number of bytes provided by size, starting from the offset provided in offset.
object.data
=> "This is the text stored in the file"
76 77 78 79 80 81 82 83 84 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 76 def data(size=-1,offset=0,headers = {}) if size.to_i > 0 range = sprintf("bytes=%d-%d", offset.to_i, (offset.to_i + size.to_i) - 1) headers['Range'] = range end response = self.container.connection.cfreq("GET",@storagehost,@storagepath,headers) raise NoSuchObjectException, "Object #{@name} does not exist" unless (response.code =~ /^20/) response.body.chomp end |
#data_stream(size = -1,, offset = 0, headers = {}, &block) ⇒ Object
Retrieves the data from an object and returns a stream that must be passed to a block. Throws a NoSuchObjectException if the object doesn’t exist.
If the optional size and range arguments are provided, the call will return the number of bytes provided by size, starting from the offset provided in offset.
data = ""
object.data_stream do |chunk|
data += chunk
end
data
=> "This is the text stored in the file"
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 99 def data_stream(size=-1,offset=0,headers = {},&block) if size.to_i > 0 range = sprintf("bytes=%d-%d", offset.to_i, (offset.to_i + size.to_i) - 1) headers['Range'] = range end self.container.connection.cfreq("GET",@storagehost,@storagepath,headers,nil) do |response| raise NoSuchObjectException, "Object #{@name} does not exist" unless (response.code == "200") response.read_body(&block) end end |
#load_from_filename(filename) ⇒ Object
A convenience method to stream data into an object from a local file (or anything that can be loaded by Ruby’s open method)
Throws an Errno::ENOENT if the file cannot be read.
object.data
=> "This is my data"
object.load_from_filename("/tmp/file.txt")
=> true
object.data
=> "This data was in the file /tmp/file.txt"
object.load_from_filename("/tmp/nonexistent.txt")
=> Errno::ENOENT: No such file or directory - /tmp/nonexistent.txt
190 191 192 193 194 195 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 190 def load_from_filename(filename) f = open(filename) self.write(f) f.close true end |
#metadata ⇒ Object
Returns the object’s metadata as a nicely formatted hash, stripping off the X-Meta-Object- prefix that the system prepends to the key name.
object.
=> {"ruby"=>"cool", "foo"=>"bar"}
115 116 117 118 119 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 115 def = {} .each{|key, value| [key.gsub(/x-object-meta-/,'').gsub(/\+\-/, ' ')] = URI.decode(value).gsub(/\+\-/, ' ')} end |
#populate ⇒ Object Also known as: refresh
Caches data about the CloudFiles::StorageObject for fast retrieval. This method is automatically called when the class is initialized, but it can be called again if the data needs to be updated.
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 54 def populate response = self.container.connection.cfreq("HEAD",@storagehost,@storagepath) raise NoSuchObjectException, "Object #{@name} does not exist" if (response.code != "204") @bytes = response["content-length"] @last_modified = Time.parse(response["last-modified"]) @etag = response["etag"] @content_type = response["content-type"] resphash = {} response.to_hash.select { |k,v| k.match(/^x-object-meta/) }.each { |x| resphash[x[0]] = x[1][0].to_s } = resphash true end |
#public_url ⇒ Object
If the parent container is public (CDN-enabled), returns the CDN URL to this object. Otherwise, return nil
public_object.public_url
=> "http://cdn.cloudfiles.mosso.com/c10181/rampage.jpg"
private_object.public_url
=> nil
229 230 231 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 229 def public_url self.container.public? ? self.container.cdn_url + "/#{URI.encode(@name)}" : nil end |
#save_to_filename(filename) ⇒ Object
A convenience method to stream data from an object into a local file
Throws an Errno::ENOENT if the file cannot be opened for writing due to a path error, and Errno::EACCES if the file cannot be opened for writing due to permissions.
object.data
=> "This is my data"
object.save_to_filename("/tmp/file.txt")
=> true
$ cat /tmp/file.txt
"This is my data"
object.save_to_filename("/tmp/owned_by_root.txt")
=> Errno::EACCES: Permission denied - /tmp/owned_by_root.txt
213 214 215 216 217 218 219 220 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 213 def save_to_filename(filename) ::File.open(filename, 'w+') do |f| self.data_stream do |chunk| f.write chunk end end true end |
#set_metadata(metadatahash) ⇒ Object
Sets the metadata for an object. By passing a hash as an argument, you can set the metadata for an object. However, setting metadata will overwrite any existing metadata for the object.
Throws NoSuchObjectException if the object doesn’t exist. Throws InvalidResponseException if the request fails.
126 127 128 129 130 131 132 133 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 126 def () headers = {} .each{|key, value| headers['X-Object-Meta-' + key.to_s.capitalize] = value.to_s} response = self.container.connection.cfreq("POST",@storagehost,@storagepath,headers) raise NoSuchObjectException, "Object #{@name} does not exist" if (response.code == "404") raise InvalidResponseException, "Invalid response code #{response.code}" unless (response.code == "202") true end |
#to_s ⇒ Object
:nodoc:
233 234 235 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 233 def to_s # :nodoc: @name end |
#write(data = nil, headers = {}) ⇒ Object
Takes supplied data and writes it to the object, saving it. You can supply an optional hash of headers, including Content-Type and ETag, that will be applied to the object.
If you would rather stream the data in chunks, instead of reading it all into memory at once, you can pass an IO object for the data, such as: object.write(open(‘/path/to/file.mp3’))
You can compute your own MD5 sum and send it in the “ETag” header. If you provide yours, it will be compared to the MD5 sum on the server side. If they do not match, the server will return a 422 status code and a MisMatchedChecksumException will be raised. If you do not provide an MD5 sum as the ETag, one will be computed on the server side.
Updates the container cache and returns true on success, raises exceptions if stuff breaks.
object = container.create_object("newfile.txt")
object.write("This is new data")
=> true
object.data
=> "This is new data"
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/vendor/cloudfiles-1.3.0/cloudfiles/storage_object.rb', line 154 def write(data=nil,headers={}) #raise SyntaxException, "No data was provided for object '#{@name}'" if (data.nil?) # Try to get the content type raise SyntaxException, "No data or header updates supplied" if (data.nil? and headers.empty?) if headers['Content-Type'].nil? type = MIME::Types.type_for(self.name).first.to_s if type.empty? headers['Content-Type'] = "application/octet-stream" else headers['Content-Type'] = type end end response = self.container.connection.cfreq("PUT",@storagehost,"#{@storagepath}",headers,data) raise InvalidResponseException, "Invalid content-length header sent" if (response.code == "412") raise MisMatchedChecksumException, "Mismatched etag" if (response.code == "422") raise InvalidResponseException, "Invalid response code #{response.code}" unless (response.code == "201") make_path(File.dirname(self.name)) if @make_path == true self.populate true end |