require "hash_keyword_args"
require "tmpdir"
require "pathname"
module Defog
class Proxy
attr_reader :proxy_root #
attr_reader :fog_wrapper # :nodoc:
# Opens a Fog
cloud storage connection to map to a corresponding proxy
# directory. Use via, e.g.,
#
# Defog::Proxy.new(:provider => :AWS, :aws_access_key_id => access_key, ...)
#
# The :provider
and its corresponding options must be
# specified as per Fog::Storage.new
. Currently, only
# :local
and :AWS
are supported. When using
# :AWS
, an additional option :bucket
must be
# specified; all files proxied by this instance must be in a single
# bucket.
#
# By default, each proxy's root directory is placed in a reasonable
# safe place, under Rails.root/tmp
if Rails is defined
# otherwise under Dir.tmpdir
. (More details: within that
# directory, the root directory is disambiguated by #provider and
# #location, so that multiple Defog::Proxy instances can be
# created without collision.)
#
# The upshot is that if you have no special constraints you don't need
# to worry about it. But if you do care, you can specify the option:
# :proxy_root => "/root/for/this/proxy/files"
#
def initialize(opts={})
opts = opts.keyword_args(:provider => :required, :proxy_root => :optional, :OTHERS => :optional)
@proxy_root = Pathname.new(opts.delete(:proxy_root)) if opts.proxy_root
@fog_wrapper = FogWrapper.connect(opts)
@proxy_root ||= case
when defined?(Rails) then Rails.root
else Pathname.new(Dir.tmpdir)
end + "defog" + provider.to_s + location
end
# Returns the provider for this proxy. I.e., :local
or
# :AWS
def provider
@fog_wrapper.provider
end
# Returns a 'location' handle to use in the default proxy root path,
# to disambiguate it from other proxies with the same provider. For
# :AWS it's the bucket name, for :Local it's derived from the local
# root path.
def location
@fog_wrapper.location
end
# Proxy a remote cloud file. Returns a Defog::File object, which is a
# specialization of ::File.
#
# key
is the cloud storage key for the file.
#
# mode
can be "r", "r+", "w", "w+", "a", or "a+" with the
# usual semantics.
#
# Like ::File.open, if called with a block yields the file object to
# the block and ensures the file will be closed when leaving the block.
#
# Normally the proxy file is synchronized and then deleted upon close.
# Pass
# :persist => true
# to maintain the file after closing. See File#close for more
# details.
#
def file(key, mode, opts={}, &block)
opts = opts.keyword_args(:persist)
File.get(opts.merge(:proxy => self, :key => key, :mode => mode), &block)
end
end
end