class Dragonfly::S3DataStore
Constants
- SUBDOMAIN_PATTERN
- VERSION
Attributes
access_key_id[RW]
bucket_name[RW]
fog_storage_options[RW]
region[RW]
root_path[RW]
secret_access_key[RW]
storage_headers[RW]
url_host[RW]
url_scheme[RW]
use_iam_profile[RW]
Public Class Methods
new(opts={})
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 16 def initialize(opts={}) @bucket_name = opts[:bucket_name] @access_key_id = opts[:access_key_id] @secret_access_key = opts[:secret_access_key] @region = opts[:region] @storage_headers = opts[:storage_headers] || {'x-amz-acl' => 'public-read'} @url_scheme = opts[:url_scheme] || 'http' @url_host = opts[:url_host] @use_iam_profile = opts[:use_iam_profile] @root_path = opts[:root_path] @fog_storage_options = opts[:fog_storage_options] || {} end
Public Instance Methods
bucket_exists?()
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 97 def bucket_exists? rescuing_socket_errors{ storage.get_bucket_location(bucket_name) } true rescue Excon::Errors::NotFound => e false end
destroy(uid)
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 56 def destroy(uid) rescuing_socket_errors{ storage.delete_object(bucket_name, full_path(uid)) } rescue Excon::Errors::NotFound, Excon::Errors::Conflict => e Dragonfly.warn("#{self.class.name} destroy error: #{e}") end
domain()
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 74 def domain case region when 'us-east-1', nil 's3.amazonaws.com' else "s3-#{region}.amazonaws.com" end end
read(uid)
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 48 def read(uid) ensure_configured response = rescuing_socket_errors{ storage.get_object(bucket_name, full_path(uid)) } [response.body, headers_to_meta(response.headers)] rescue Excon::Errors::NotFound => e nil end
storage()
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 83 def storage @storage ||= begin storage = Fog::Storage.new(fog_storage_options.merge({ :provider => 'AWS', :aws_access_key_id => access_key_id, :aws_secret_access_key => secret_access_key, :region => region, :use_iam_profile => use_iam_profile }).reject {|name, option| option.nil?}) storage.sync_clock storage end end
url_for(uid, opts={})
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 62 def url_for(uid, opts={}) if expires = opts[:expires] storage.get_object_https_url(bucket_name, full_path(uid), expires, {:query => opts[:query]}) else scheme = opts[:scheme] || url_scheme host = opts[:host] || url_host || ( bucket_name =~ SUBDOMAIN_PATTERN ? "#{bucket_name}.s3.amazonaws.com" : "s3.amazonaws.com/#{bucket_name}" ) "#{scheme}://#{host}/#{full_path(uid)}" end end
write(content, opts={})
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 31 def write(content, opts={}) ensure_configured ensure_bucket_initialized headers = {'Content-Type' => content.mime_type} headers.merge!(opts[:headers]) if opts[:headers] uid = opts[:path] || generate_uid(content.name || 'file') rescuing_socket_errors do content.file do |f| storage.put_object(bucket_name, full_path(uid), f, full_storage_headers(headers, content.meta)) end end uid end
Private Instance Methods
ensure_bucket_initialized()
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 119 def ensure_bucket_initialized unless @bucket_initialized rescuing_socket_errors{ storage.put_bucket(bucket_name, 'LocationConstraint' => region) } unless bucket_exists? @bucket_initialized = true end end
ensure_configured()
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 106 def ensure_configured unless @configured if use_iam_profile raise NotConfigured, "You need to configure #{self.class.name} with bucket_name" if bucket_name.nil? else [:bucket_name, :access_key_id, :secret_access_key].each do |attr| raise NotConfigured, "You need to configure #{self.class.name} with #{attr}" if send(attr).nil? end end @configured = true end end
escape_meta_values(meta)
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 159 def escape_meta_values(meta) meta.inject({}) {|hash, (key, value)| hash[key] = value.is_a?(String) ? CGI.escape(value) : value hash } end
full_path(uid)
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 130 def full_path(uid) File.join *[root_path, uid].compact end
full_storage_headers(headers, meta)
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 134 def full_storage_headers(headers, meta) storage_headers.merge(meta_to_headers(meta)).merge(headers) end
generate_uid(name)
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 126 def generate_uid(name) "#{Time.now.strftime '%Y/%m/%d/%H/%M/%S'}/#{SecureRandom.uuid}/#{name}" end
headers_to_meta(headers)
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 138 def headers_to_meta(headers) json = headers['x-amz-meta-json'] if json && !json.empty? unescape_meta_values(Serializer.json_decode(json)) elsif marshal_data = headers['x-amz-meta-extra'] Utils.stringify_keys(Serializer.marshal_b64_decode(marshal_data)) end end
meta_to_headers(meta)
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 147 def meta_to_headers(meta) meta = escape_meta_values(meta) {'x-amz-meta-json' => Serializer.json_encode(meta)} end
rescuing_socket_errors() { || ... }
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 152 def rescuing_socket_errors(&block) yield rescue Excon::Errors::SocketError => e storage.reload yield end
unescape_meta_values(meta)
click to toggle source
# File lib/dragonfly/s3_data_store.rb, line 166 def unescape_meta_values(meta) meta.inject({}) {|hash, (key, value)| hash[key] = value.is_a?(String) ? CGI.unescape(value) : value hash } end