A Rails plugin and AngularJS application that makes direct uploads to multiple cloud storage providers easy.
Only supports XMLHttpRequest Level 2 capable browsers and cloud providers that have a RESTful API with CORS support.
Why compromise?
Get started now: gem install condo
or checkout the example application
Also see our github pages site
GNU Lesser General Public License v3 (LGPL version 3)
Condominios was created to provide direct to cloud uploads using standards based browser technology. However it is not limited to that use case.
The API is RESTful, providing an abstraction layer and signed URLs that can be utilised in native (mobile) applications.
The main advantages are:
- Off-loads processing to client machines
- Better guarantees against upload corruption
- file hashing on the client side
- Upload results are guaranteed
- user is always aware of any failures in the process
- Detailed progress and control over the upload
This has numerous advantages over traditional Form Data style post uploads too.
- Progress bars
- Resumability when uploading large files
- Optional parallel uploads (multiple parts of the file simultaneously)
Support for all major browsers
- Chrome
- Firefox
- Safari
- Opera
- IE10+
- Residence == the current storage provider
- Resident == the current user
See the example application which implements the steps below on an otherwise blank rails app.
- Add the following to your rails application gemfile:
gem 'condo'
- Add a datastore
gem 'condo_active_record'
(for traditional databases)- condo_mongoid by axomi for MongoDB
gem 'condo_interface'
(optional – an example interface)
- Run migrations if using active record
rake railties:install:migrations FROM=condo_active_record
rake db:migrate
- Create an initialiser for any default residencies. (details further down)
- Create controllers that will be used as Condo endpoints
- Typically
rails g controller Uploads
- Add the resource to your routes
- Typically
- At the top of the new controller add the following line to the class:
include Condo
- This creates the following public methods at run time: new, create, edit, update, destroy implementing the API
- The following protected methods are also generated: set_residence, current_residence, current_resident, current_upload
- You are encouraged to use standard filters to authenticate users and set the residence (if this is dynamic) + implement index / show if desired
- You must implement the following call-backs:
- resident_id – this should provide a unique identifier for the current user, used for authorisation
- upload_complete – provides the upload information for storage in the greater application logic. Return true if successful.
- destroy_upload – provides the upload information so that a scheduled task can be created to clean up the upload. Return true if successfully scheduled.
- This should be done in the background using something like Fog Can’t trust the client
If you are using Condo Interface then you may want to do the following:
- Create an index for your controller
def index; end
- Create an index.html.erb in your view with:
- Make sure your AngularJS app includes:
angular.module('YourApp', ['Condo', 'CondoInterface']);
<div data-ng-app="YourApp"><%= render "condo_interface/upload" %></div>
Alternative you could load an AngularJS template linking to <%= asset_path(‘templates/_upload.html’) %>
If you are creating an application that only communicates with one or two storage providers or accounts then this is the simplest way to get started.
In an initialiser do the following:
Condo::Configuration.add_residence(:AmazonS3, {
:access_id => ENV['S3_KEY'],
:secret_key => ENV['S3_SECRET']
# :location => 'us-west-1' # or 'ap-southeast-1' etc (see http://docs.amazonwebservices.com/general/latest/gr/rande.html#s3_region)
# Defaults to 'us-east-1' or US Standard - not required for Google
# :namespace => :admin_resident # Allows you to assign different defaults to different controllers or users etc
})
The first residence to be defined in a namespace will be the default. To change the residence for the current request use set_residence(:name, :location)
– location is optional
Currently available residencies:
- :AmazonS3
- :GoogleCloudStorage
- :RackspaceCloudFiles (Works with Swift left as rackspace for backwards compatibility)
Note:: There is also a callback to dynamically set storage provider. Which is useful if your users use:
- Their own bucket
- Different cloud providers etc
These are pretty well defined here