Skip to content

Instantly share code, notes, and snippets.

@merlinvn
Created April 24, 2012 03:41
Show Gist options
  • Save merlinvn/2476222 to your computer and use it in GitHub Desktop.
Save merlinvn/2476222 to your computer and use it in GitHub Desktop.
Cloudfiles Storage for Paperclip
module Paperclip
module Storage
module Cloudfilesstorage
extend self
def self.extended base
#check to see whether the Cloudfiles gem exists??
begin
require 'cloudfiles'
rescue LoadError => e
e.message << " (You may need to install the cloudfiles gem)"
raise e
end unless defined?(CloudFiles)
@@container ||= {}
base.instance_eval do
@options[:cloudfiles_credentials] ||= "#{Rails.root}/config/rackspace_cloudfiles.yml"
@cloudfiles_credentials = parse_credentials(@options[:cloudfiles_credentials])
@container_name = @options[:container] || options[:container_name] || @cloudfiles_credentials[:container] || @cloudfiles_credentials[:container_name]
@container_name = @container_name.call(self) if @container_name.is_a?(Proc)
@cloudfiles_options = @options[:cloudfiles_options] || {}
@@cdn_url = @cloudfiles_credentials[:cname] || cloudfiles_container.cdn_url
@@ssl_url = @cloudfiles_credentials[:cname] || cloudfiles_container.cdn_ssl_url
@use_ssl = @options[:ssl] || false
@path_filename = ":cf_path_filename" unless @url.to_s.match(/^:cf.*filename$/)
@url = (@use_ssl == true ? @@ssl_url : @@cdn_url) + "/#{URI.encode(@path_filename).gsub(/&/, '%26')}"
@options[:url] = @url
@path = (Paperclip::Attachment.default_options[:path] == @options[:path]) ? ":attachment/:id/:style/:basename.:extension" : @options[:path]
end
Paperclip.interpolates(:cf_path_filename) do |attachment, style|
URI.encode(attachment.path(style))
end
end
def cloudfiles
@@cf ||= CloudFiles::Connection.new(:username => @cloudfiles_credentials[:username],
:api_key => @cloudfiles_credentials[:api_key],
:snet => @cloudfiles_credentials[:servicenet],
:auth_url => (@cloudfiles_credentials[:auth_url] || "https://auth.api.rackspacecloud.com/v1.0"))
end
def create_container
container = cloudfiles.create_container(@container_name)
container.make_public
container
end
def cloudfiles_container
@@container[@container_name] ||= create_container
end
def container_name
@container_name
end
def parse_credentials creds
creds = find_credentials(creds).stringify_keys
(creds[Rails.env] || creds).symbolize_keys
end
def exists?(style = default_style)
cloudfiles_container.object_exists?(path(style))
end
def to_file(style=default_style)
@queued_for_write[style] || "#{@@cdn_url}/#{style}"
end
def flush_writes #:nodoc:
@queued_for_write.each do |style, file|
object = cloudfiles_container.create_object(path(style), false)
object.load_from_filename(file.path)
end
@queued_for_write = {}
end
def flush_deletes #:nodoc:
@queued_for_delete.each do |path|
cloudfiles_container.delete_object(path)
end
@queued_for_delete = []
end
def find_credentials creds
case creds
when File
YAML.load_file(creds.path)
when String
YAML.load_file(creds)
when Hash
creds
else
raise ArgumentError, "Credentials are not a path, file, or hash."
end
end
private :find_credentials
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment