Class: Raca::Container
- Inherits:
-
Object
- Object
- Raca::Container
- Defined in:
- lib/raca/container.rb
Overview
Represents a single cloud files container. Contains methods for uploading, downloading, collecting stats, listing files, etc.
You probably don’t want to instantiate this directly, see Raca::Account#containers
Constant Summary collapse
- MAX_ITEMS_PER_LIST =
10_000
- LARGE_FILE_THRESHOLD =
5 Gb
5_368_709_120
- LARGE_FILE_SEGMENT_SIZE =
4 Gb
4_295_000_000
Instance Attribute Summary collapse
-
#container_name ⇒ Object
readonly
Returns the value of attribute container_name.
Instance Method Summary collapse
-
#cdn_enable(ttl = 259200) ⇒ Object
use this with caution, it will make EVERY object in the container publicly available via the CDN.
-
#cdn_metadata ⇒ Object
Return the key details for CDN access to this container.
-
#delete(key) ⇒ Object
Delete
key
from the container. -
#download(key, filepath) ⇒ Object
Download the object at key into a local file at filepath.
-
#expiring_url(object_key, temp_url_key, expires_at = Time.now.to_i + 60) ⇒ Object
DEPRECATED: use temp_url instead, this will be removed in version 1.0.
-
#initialize(account, region, container_name, opts = {}) ⇒ Container
constructor
A new instance of Container.
- #inspect ⇒ Object
-
#list(options = {}) ⇒ Object
Return an array of files in the container.
-
#metadata ⇒ Object
Return some basic stats on the current container.
-
#object_metadata(key) ⇒ Object
Returns some metadata about a single object in this container.
-
#purge_from_akamai(key, email_address) ⇒ Object
Remove
key
from the CDN edge nodes on which it is currently cached. -
#search(prefix) ⇒ Object
Returns an array of object keys that start with prefix.
-
#set_metadata(headers) ⇒ Object
Set metadata headers on the container.
-
#temp_upload_url(object_key, temp_url_key, expires_at = Time.now.to_i + 60) ⇒ Object
Generate a temporary URL for uploading a file to a private container.
-
#temp_url(object_key, temp_url_key, expires_at = Time.now.to_i + 60) ⇒ Object
Generate an expiring URL for downloading a file that is otherwise private.
-
#upload(key, data_or_path, headers = {}) ⇒ Object
Upload data_or_path (which may be a filename or an IO) to the container, as key.
Constructor Details
#initialize(account, region, container_name, opts = {}) ⇒ Container
Returns a new instance of Container.
21 22 23 24 25 26 27 28 |
# File 'lib/raca/container.rb', line 21 def initialize(account, region, container_name, opts = {}) raise ArgumentError, "The container name must not contain '/'." if container_name['/'] @account, @region, @container_name = account, region, container_name @storage_url = @account.public_endpoint("cloudFiles", region) @cdn_url = @account.public_endpoint("cloudFilesCDN", region) @logger = opts[:logger] @logger ||= Rails.logger if defined?(Rails) end |
Instance Attribute Details
#container_name ⇒ Object (readonly)
Returns the value of attribute container_name.
19 20 21 |
# File 'lib/raca/container.rb', line 19 def container_name @container_name end |
Instance Method Details
#cdn_enable(ttl = 259200) ⇒ Object
use this with caution, it will make EVERY object in the container publicly available via the CDN. CDN enabling can be done via the web UI but only with a TTL of 72 hours. Using the API it’s possible to set a TTL of 50 years.
TTL is defined in seconds, default is 72 hours.
204 205 206 207 208 209 |
# File 'lib/raca/container.rb', line 204 def cdn_enable(ttl = 259200) log "enabling CDN access to #{container_path} with a cache expiry of #{ttl / 60} minutes" response = cdn_client.put(container_path, "X-TTL" => ttl.to_i.to_s) (200..299).cover?(response.code.to_i) end |
#cdn_metadata ⇒ Object
Return the key details for CDN access to this container. Can be called on non CDN enabled containers, but the details won’t make much sense.
185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/raca/container.rb', line 185 def log "retrieving container CDN metadata from #{container_path}" response = cdn_client.head(container_path) { :cdn_enabled => response["X-CDN-Enabled"] == "True", :host => response["X-CDN-URI"], :ssl_host => response["X-CDN-SSL-URI"], :streaming_host => response["X-CDN-STREAMING-URI"], :ttl => response["X-TTL"].to_i, :log_retention => response["X-Log-Retention"] == "True" } end |
#delete(key) ⇒ Object
Delete key
from the container. If the container is on the CDN, the object will still be served from the CDN until the TTL expires.
50 51 52 53 54 55 |
# File 'lib/raca/container.rb', line 50 def delete(key) log "deleting #{key} from #{container_path}" object_path = File.join(container_path, Raca::Util.url_encode(key)) response = storage_client.delete(object_path) (200..299).cover?(response.code.to_i) end |
#download(key, filepath) ⇒ Object
Download the object at key into a local file at filepath.
Returns the number of downloaded bytes.
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/raca/container.rb', line 90 def download(key, filepath) log "downloading #{key} from #{container_path}" object_path = File.join(container_path, Raca::Util.url_encode(key)) outer_response = storage_client.get(object_path) do |response| File.open(filepath, 'wb') do |io| response.read_body do |chunk| io.write(chunk) end end end outer_response["Content-Length"].to_i end |
#expiring_url(object_key, temp_url_key, expires_at = Time.now.to_i + 60) ⇒ Object
DEPRECATED: use temp_url instead, this will be removed in version 1.0
220 221 222 |
# File 'lib/raca/container.rb', line 220 def expiring_url(object_key, temp_url_key, expires_at = Time.now.to_i + 60) temp_url(object_key, temp_url_key, expires_at) end |
#inspect ⇒ Object
232 233 234 |
# File 'lib/raca/container.rb', line 232 def inspect "#<Raca::Container:#{__id__} region=#{@region} container_name=#{@container_name}>" end |
#list(options = {}) ⇒ Object
Return an array of files in the container.
Supported options
max - the maximum number of items to return marker - return items alphabetically after this key. Useful for pagination prefix - only return items that start with this string details - return extra details for each file - size, md5, etc
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/raca/container.rb', line 112 def list( = {}) max = .fetch(:max, 100_000_000) marker = .fetch(:marker, nil) prefix = .fetch(:prefix, nil) details = .fetch(:details, nil) limit = [max, MAX_ITEMS_PER_LIST].min log "retrieving up to #{max} items from #{container_path}" request_path = list_request_path(marker, prefix, details, limit) result = storage_client.get(request_path).body || "" if details result = JSON.parse(result) else result = result.split("\n") end result.tap {|items| if max <= limit log "Got #{items.length} items; we don't need any more." elsif items.length < limit log "Got #{items.length} items; there can't be any more." else log "Got #{items.length} items; requesting #{limit} more." details ? marker = items.last["name"] : marker = items.last items.concat list(max: max-items.length, marker: marker, prefix: prefix, details: details) end } end |
#metadata ⇒ Object
Return some basic stats on the current container.
151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/raca/container.rb', line 151 def log "retrieving container metadata from #{container_path}" response = storage_client.head(container_path) custom = {} response.each_capitalized_name { |name| custom[name] = response[name] if name[/\AX-Container-Meta-/] } { :objects => response["X-Container-Object-Count"].to_i, :bytes => response["X-Container-Bytes-Used"].to_i, :custom => custom, } end |
#object_metadata(key) ⇒ Object
Returns some metadata about a single object in this container.
75 76 77 78 79 80 81 82 83 84 |
# File 'lib/raca/container.rb', line 75 def (key) object_path = File.join(container_path, Raca::Util.url_encode(key)) log "Requesting metadata from #{object_path}" response = storage_client.head(object_path) { :content_type => response["Content-Type"], :bytes => response["Content-Length"].to_i } end |
#purge_from_akamai(key, email_address) ⇒ Object
Remove key
from the CDN edge nodes on which it is currently cached. The object is not deleted from the container: as the URL is re-requested, the edge cache will be re-filled with the object currently in the container.
This shouldn’t be used except when it’s really required (e.g. when a piece has to be taken down) because it’s expensive: it lodges a support ticket at Akamai. (!)
64 65 66 67 68 69 70 71 |
# File 'lib/raca/container.rb', line 64 def purge_from_akamai(key, email_address) log "Requesting #{File.join(container_path, key)} to be purged from the CDN" response = cdn_client.delete( File.join(container_path, Raca::Util.url_encode(key)), 'X-Purge-Email' => email_address ) (200..299).cover?(response.code.to_i) end |
#search(prefix) ⇒ Object
Returns an array of object keys that start with prefix. This is a convenience method that is equivilant to:
container.list(prefix: "foo/bar/")
144 145 146 147 |
# File 'lib/raca/container.rb', line 144 def search(prefix) log "retrieving container listing from #{container_path} items starting with #{prefix}" list(prefix: prefix) end |
#set_metadata(headers) ⇒ Object
Set metadata headers on the container
headers = { "X-Container-Meta-Access-Control-Allow-Origin" => "*" }
container.(headers)
Note: Rackspace requires some headers to begin with ‘X-Container-Meta-’ or other prefixes, e.g. when setting
'Access-Control-Allow-Origin', it needs to be set as 'X-Container-Meta-Access-Control-Allow-Origin'.
See: docs.rackspace.com/files/api/v1/cf-devguide/content/CORS_Container_Header-d1e1300.html
http://docs.rackspace.com/files/api/v1/cf-devguide/content/
POST_updateacontainermeta_v1__account___container__containerServicesOperations_d1e000.html
176 177 178 179 180 |
# File 'lib/raca/container.rb', line 176 def (headers) log "setting headers for container #{container_path}" response = storage_client.post(container_path, '', headers) (200..299).cover?(response.code.to_i) end |
#temp_upload_url(object_key, temp_url_key, expires_at = Time.now.to_i + 60) ⇒ Object
Generate a temporary URL for uploading a file to a private container. Anyone can perform a PUT request to the URL returned from this method and an object will be created in the container.
228 229 230 |
# File 'lib/raca/container.rb', line 228 def temp_upload_url(object_key, temp_url_key, expires_at = Time.now.to_i + 60) private_url("PUT", object_key, temp_url_key, expires_at) end |
#temp_url(object_key, temp_url_key, expires_at = Time.now.to_i + 60) ⇒ Object
Generate an expiring URL for downloading a file that is otherwise private. Useful for providing temporary access to files.
214 215 216 |
# File 'lib/raca/container.rb', line 214 def temp_url(object_key, temp_url_key, expires_at = Time.now.to_i + 60) private_url("GET", object_key, temp_url_key, expires_at) end |
#upload(key, data_or_path, headers = {}) ⇒ Object
Upload data_or_path (which may be a filename or an IO) to the container, as key.
If headers are provided they will be added to to upload request. Use this to manually specify content type, content disposition, CORS headers, etc.
35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/raca/container.rb', line 35 def upload(key, data_or_path, headers = {}) if data_or_path.respond_to?(:read) && data_or_path.respond_to?(:size) upload_io(key, data_or_path, data_or_path.size, headers) elsif !File.file?(data_or_path.to_s) raise ArgumentError, "data_or_path must be an IO with data or filename string" else File.open(data_or_path.to_s, "rb") do |io| upload_io(key, io, io.stat.size, headers) end end end |