Module: Technoweenie::AttachmentFu::Backends::CloudFileBackend

Defined in:
lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb

Overview

CloudFiles Storage Backend

Enables use of Rackspace Cloud Files as a storage mechanism

Based heavily on the Amazon S3 backend.

Requirements

Requires the Cloud Files Gem by Rackspace

Configuration

Configuration is done via RAILS_ROOT/config/rackspace_cloudfiles.yml and is loaded according to the RAILS_ENV. The minimum connection options that you must specify are a container name, your Mosso login name and your Mosso API key. You can sign up for Cloud Files and get access keys by visiting www.mosso.com/buy.htm

Example configuration (RAILS_ROOT/config/rackspace_cloudfiles.yml)

development:
  container_name: appname_development
  username: <your key>
  api_key: <your key>

test:
  container_name: appname_test
  username: <your key>
  api_key: <your key>

production:
  container_name: appname
  username: <your key>
  apik_key: <your key>

You can change the location of the config path by passing a full path to the :cloudfiles_config_path option.

has_attachment :storage => :cloud_files, :cloudfiles_config_path => (RAILS_ROOT + '/config/mosso.yml')

Required configuration parameters

  • :username - The username for your Rackspace Cloud (Mosso) account. Provided by Rackspace.

  • :secret_access_key - The api key for your Rackspace Cloud account. Provided by Rackspace.

  • :container_name - The name of a container in your Cloud Files account.

If any of these required arguments is missing, a AuthenticationException will be raised from CloudFiles::Connection.

Usage

To specify Cloud Files as the storage mechanism for a model, set the acts_as_attachment :storage option to <tt>:cloud_files/tt>.

class Photo < ActiveRecord::Base
  has_attachment :storage => :cloud_files
end

Customizing the path

By default, files are prefixed using a pseudo hierarchy in the form of :table_name/:id, which results in Cloud Files object names (and urls) that look like: :server/:container_name/:table_name/:id/:filename with :table_name representing the customizable portion of the path. You can customize this prefix using the :path_prefix option:

class Photo < ActiveRecord::Base
  has_attachment :storage => :cloud_files, :path_prefix => 'my/custom/path'
end

Which would result in public URLs like http(s)://:server/:container_name/my/custom/path/:id/:filename.

Permissions

File permisisons are determined by the permissions of the container. At present, the options are public (and distributed by the Limelight CDN), and private (only available to your login)

Other options

Of course, all the usual configuration options apply, such as content_type and thumbnails:

class Photo < ActiveRecord::Base
  has_attachment :storage => :cloud_files, :content_type => ['application/pdf', :image], :resize_to => 'x50'
  has_attachment :storage => :cloud_files, :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }
end

Accessing Cloud Files URLs

You can get an object’s public URL using the cloudfiles_url accessor. For example, assuming that for your postcard app you had a container name like ‘postcard_world_development’, and an attachment model called Photo:

@postcard.cloudfiles_url # => http://cdn.cloudfiles.mosso.com/c45182/uploaded_files/20/london.jpg

The resulting url is in the form: :server/:container_name/:table_name/:id/:file. The optional thumbnail argument will output the thumbnail’s filename (if any).

Additionally, you can get an object’s base path relative to the container root using base_path:

@photo.file_base_path # => uploaded_files/20

And the full path (including the filename) using full_filename:

@photo.full_filename # => uploaded_files/20/london.jpg

Niether base_path or full_filename include the container name as part of the path. You can retrieve the container name using the container_name method.

Defined Under Namespace

Classes: ConfigFileNotFoundError, RequiredLibraryNotFoundError

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

:nodoc:



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb', line 109

def self.included(base) #:nodoc:
  mattr_reader :container_name, :cloudfiles_config

  begin
    require 'cloudfiles'
  rescue LoadError
    raise RequiredLibraryNotFoundError.new('CloudFiles could not be loaded')
  end

  begin
    @@cloudfiles_config_path = base.attachment_options[:cloudfiles_config_path] || (RAILS_ROOT + '/config/rackspace_cloudfiles.yml')
    @@cloudfiles_config = @@cloudfiles_config = YAML.load(ERB.new(File.read(@@cloudfiles_config_path)).result)[RAILS_ENV].symbolize_keys
  rescue
    #raise ConfigFileNotFoundError.new('File %s not found' % @@cloudfiles_config_path)
  end

  @@container_name = @@cloudfiles_config[:container_name]
  @@cf = CloudFiles::Connection.new(@@cloudfiles_config[:username], @@cloudfiles_config[:api_key])
  @@container = @@cf.container(@@container_name)
  
  base.before_update :rename_file
end

Instance Method Details

#attachment_path_idObject

The attachment ID used in the full path of a file



139
140
141
# File 'lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb', line 139

def attachment_path_id
  ((respond_to?(:parent_id) && parent_id) || id).to_s
end

#base_pathObject

The pseudo hierarchy containing the file relative to the container name Example: :table_name/:id



145
146
147
# File 'lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb', line 145

def base_path
  File.join(attachment_options[:path_prefix], attachment_path_id)
end

#cloudfiles_url(thumbnail = nil) ⇒ Object Also known as: public_filename

All public objects are accessible via a GET request to the Cloud Files servers. You can generate a url for an object using the cloudfiles_url method.

@photo.cloudfiles_url

The resulting url is in the CDN URL for the object

The optional thumbnail argument will output the thumbnail’s filename (if any).

If you are trying to get the URL for a nonpublic container, nil will be returned.



165
166
167
168
169
170
171
# File 'lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb', line 165

def cloudfiles_url(thumbnail = nil)
  if @@container.public?
    File.join(@@container.cdn_url, full_filename(thumbnail))
  else
    nil
  end
end

#create_temp_fileObject



174
175
176
# File 'lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb', line 174

def create_temp_file
  write_to_temp_file current_data
end

#current_dataObject



178
179
180
# File 'lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb', line 178

def current_data
  @@container.get_object(full_filename).data
end

#filename=(value) ⇒ Object

Overwrites the base filename writer in order to store the old filename



133
134
135
136
# File 'lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb', line 133

def filename=(value)
  @old_filename = filename unless filename.nil? || @old_filename
  write_attribute :filename, sanitize_filename(value)
end

#full_filename(thumbnail = nil) ⇒ Object

The full path to the file relative to the container name Example: :table_name/:id/:filename



151
152
153
# File 'lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb', line 151

def full_filename(thumbnail = nil)
  File.join(base_path, thumbnail_name_for(thumbnail))
end