-
Notifications
You must be signed in to change notification settings - Fork 2
Examples
Copy the example from config/ungulate.rb. This could go in e.g. config/initializers/ungulate.rb
You only need to set queue_name if you want to use thumbnailing with an SQS queue. If you're using your own queuing system, you don't need to set queue_name.
You should read http://doc.s3.amazonaws.com/proposals/post.html first to understand the conditions section.
class UploadsController < ApplicationController
def new
@boring_image = BoringImage.find(params[:boring_image_id])
config = YAML.load_file(Rails.root.join('config', 's3.yml'))[Rails.env]
expiration = 10.hours.from_now
# use a predefined key - here we use a timestamp so we don't have to wait for CloudFront to update
key = "boring_images/#{Time.now.strftime('%Y%m%d%H%M%S')}/#{@boring_image.to_param}"
@upload = Ungulate::FileUpload.new(
:bucket_url => "http://#{config['bucket']}.s3.amazonaws.com/",
:key => key,
:policy => {
'expiration' => expiration,
'conditions' => [
{'bucket' => config['bucket']},
{'key' => key},
{'acl' => 'private'},
{'success_action_redirect' => new_item_url}
]
}
)
end
end
class ItemsController < ApplicationController
def new
@some_item = Item.new
@some_item.key = params[:key]
@some_item.save!
redirect_to some_other_url
end
end
If you want to include the uploaded filename in the key that is stored on S3, you should use ${filename} in the key. However, to restrict the form to only permit uploading to a particular prefix before this filename, you must use starts-with, like so:
key = "some/prefix/to/${filename}"
@upload = Ungulate::FileUpload.new(
:bucket_url => "http://#{config['bucket']}.s3.amazonaws.com/",
:key => key,
:policy => {
'expiration' => expiration,
'conditions' => [
{'bucket' => config['bucket']},
['starts-with', '$key', 'some/prefix/to/'],
{'acl' => 'private'},
{'success_action_redirect' => new_item_url}
]
}
)
e.g. for uploads/new action, first controller action above:
<% ungulate_upload_form_for(@upload) do %>
<%= label_tag :file, 'Upload File' %>
<%= file_field_tag :file %>
<%= submit_tag 'Upload' %>
<% end %>
This outputs something like:
<form action="http://my-bucket.s3.amazonaws.com/" enctype="multipart/form-data" method="post">
<div>
<input name="key" type="hidden" value="boring_images/201004250000/123" />
<input name="AWSAccessKeyId" type="hidden" value="ASDFASDFASDF" />
<input name="acl" type="hidden" value="private" />
<input name="policy" type="hidden" value="SOMEGOBBLEDYNONSENSE=" />
<input name="signature" type="hidden" value="MORENONSENSEASDFASDF=" />
<input name="success_action_redirect" type="hidden" value="http://my.domain/items/new" />
<label for="file">Upload File</label>
<input id="file" name="file" type="file" />
<input name="commit" type="submit" value="Upload" />
</div>
</form>
You'll only need an enqueue method if you intend to do some image processing, such as thumbnailing and watermarking. Here's an example model with an enqueue method, for thumbnailing and watermarking:
class Item < ActiveRecord::Base
after_create :ungulate_enqueue
# send the image processing job to SQS
def ungulate_enqueue
config = YAML.load_file(Rails.root.join('config', 's3.yml'))[Rails.env]
Ungulate::FileUpload.enqueue(
:bucket => config['bucket'],
:key => key,
:notification_url => 'http://some.url/that/receives/a/put',
:versions => {
# Chained resize then watermark from URL.
# See http://studio.imagemagick.org/RMagick/doc/image1.html#composite
# RMagick constants are expressed as symbols, then converted when queue job is run
# URLs are assumed to be the location of image blobs, and are converted to Magick::Image objects
:large => [
[ :resize_to_fill, 713, 600 ],
[ :composite, 'https://some.host/someimage.png', :center_gravity, :soft_light_composite_op ]
],
:thumbnail => [ :resize_to_fill, 224, 156 ],
:large_thumbnail => [ :resize_to_fill, 231, 159 ],
}
)
end
end
Here's an example Document class, that could be used to upload arbitrary documents. If you want to produce signed links to content with private ACL set, you'll need a method to produce URLs, such as in the following example, which makes the link available for two hours.
class Document < ActiveRecord::Base
belongs_to :owner, :polymorphic => true
validates_presence_of :key
validates_uniqueness_of :key
def url
RightAws::S3Generator.new(S3_CONFIG['access_key_id'],
S3_CONFIG['secret_access_key'],
:port => 80,
:protocol => 'http').
bucket(S3_CONFIG['bucket']).
get(key, 2.hours)
end
end