s3_direct_upload 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Wayne
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # S3DirectUpload
2
+
3
+ Easily generate a form that allows you to upload directly to Amazon S3.
4
+ Multi file uploading supported by jquery-fileupload.
5
+
6
+ Code extracted from Ryan Bates' [gallery-jquery-fileupload](https://github.com/railscasts/383-uploading-to-amazon-s3/tree/master/gallery-jquery-fileupload).
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 's3_direct_upload'
13
+
14
+ Then add a new initalizer with your AWS credentials:
15
+
16
+ **config/initalizers/s3_direct_upload.rb**
17
+ ```ruby
18
+ S3DirectUpload.config do |c|
19
+ c.access_key_id = "" # your access key id
20
+ c.secret_access_key = "" # your secret access key
21
+ c.bucket = "" # your bucket name
22
+ end
23
+ ```
24
+
25
+ Make sure your AWS S3 CORS settings for your bucket look something like this:
26
+ ```
27
+ <CORSConfiguration>
28
+ <CORSRule>
29
+ <AllowedOrigin>http://0.0.0.0:3000</AllowedOrigin>
30
+ <AllowedMethod>GET</AllowedMethod>
31
+ <AllowedMethod>POST</AllowedMethod>
32
+ <AllowedMethod>PUT</AllowedMethod>
33
+ <MaxAgeSeconds>3000</MaxAgeSeconds>
34
+ <AllowedHeader>*</AllowedHeader>
35
+ </CORSRule>
36
+ </CORSConfiguration>
37
+ ```
38
+ In production the AllowedOrigin key should be your domain.
39
+
40
+ Add the following js and css to your asset pipeline:
41
+
42
+ **application.js**
43
+ ```ruby
44
+ //= require s3_direct_upload
45
+ ```
46
+
47
+ **application.css**
48
+ ```ruby
49
+ //= require s3_direct_upload_progress_bars
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ Create a new view that uses the helper:
55
+ ```ruby
56
+ <%= s3_uploader_form post: model_url, as: "model[image_url]" do %>
57
+ <%= file_field_tag :file, multiple: true %>
58
+ <% end %>
59
+ ```
60
+
61
+ Also place this template in the same view for the progress bars:
62
+ ```javascript
63
+ <script id="template-upload" type="text/x-tmpl">
64
+ <div class="upload">
65
+ {%=o.name%}
66
+ <div class="progress"><div class="bar" style="width: 0%"></div></div>
67
+ </div>
68
+ </script>
69
+ ```
70
+
71
+ ### Customizations
72
+ Feel free to override the styling for the progress bars in s3_direct_upload_progress_bars, look at the source for inspiration.
73
+
74
+ Also feel free to write your own js to interface with jquery-file-upload. You might want to do this to do custom validations on the files before it is sent to S3 for example.
75
+ To do this remove `s3_direct_upload` from your application.js and include the necissary jquery-file-upload scripts (they are included in this gem automatically):
76
+ ```javascript
77
+ //= require jquery-fileupload/basic
78
+ //= require jquery-fileupload/vendor/tmpl
79
+ ```
80
+ and use the `s3_direct_upload` script as a guide, the form helper will still work fine if thats all you need.
81
+
82
+ ### s3_uploader_form options and after upload callback
83
+ After the upload is complete, the script will execute an ajax POST to the model_url given in the `post` option in the form helper.
84
+ The url to the file on S3 will be passed as a key to whatever is in the `as` option.
85
+
86
+ You could have your create action render a javascript file like this:
87
+
88
+ **create.js.erb**
89
+ ```ruby
90
+ <% if @model.new_record? %>
91
+ alert("Failed to upload model: <%= j @model.errors.full_messages.join(', ').html_safe %>");
92
+ <% else %>
93
+ $("#paintings").append("<%= j render(@model) %>");
94
+ <% end %>
95
+ ```
96
+ So that javascript code would be executed after the model instance is created, which would render your _model.html.erb template without a page reload if you wish.
97
+
98
+ It is recommended that you persist the image_url as an attribute on the model. To do this To do this add `resources model` in the routes file, and add the 'image_url' attribute to your model (can be whatever you set it as in the as options)
99
+
100
+
101
+ ## Gotchas
102
+
103
+ Right now you can only have one upload form on a page.
104
+ Upload form is hardcoded with id '#fileupload'
105
+
106
+
107
+ ## Contributing / TODO
108
+
109
+ This is just a simple gem that only really provides some javascript and a form helper.
110
+ This gem could go all sorts of ways based on what people want and how people contribute.
111
+ Ideas:
112
+ More specs!
113
+ More options to control expiration, max filesize, file types etc.
114
+ Create generators.
115
+ Model methods.
116
+
117
+ ## Credit
118
+
119
+ This gem is basically a small wrapper around code that [Ryan Bates](http://github.com/rbates) wrote for [Railscast#383](http://railscasts.com/episodes/383-uploading-to-amazon-s3). Most of the code in this gem was extracted from [gallery-jquery-fileupload](https://github.com/railscasts/383-uploading-to-amazon-s3/tree/master/gallery-jquery-fileupload).
120
+
121
+ Thank you Ryan Bates!
122
+
123
+ This code also uses the excellecnt [jQuery-File-Upload](https://github.com/blueimp/jQuery-File-Upload), which is included in this gem by its rails counterpart [jquery-fileupload-rails](https://github.com/tors/jquery-fileupload-rails)
@@ -0,0 +1,30 @@
1
+ #= require jquery-fileupload/basic
2
+ #= require jquery-fileupload/vendor/tmpl
3
+
4
+ jQuery ->
5
+ $('#fileupload').fileupload
6
+ add: (e, data) ->
7
+ file = data.files[0]
8
+ data.context = $(tmpl("template-upload", file))
9
+ $('#fileupload').append(data.context)
10
+ data.submit()
11
+
12
+ progress: (e, data) ->
13
+ if data.context
14
+ progress = parseInt(data.loaded / data.total * 100, 10)
15
+ data.context.find('.bar').css('width', progress + '%')
16
+
17
+ done: (e, data) ->
18
+ file = data.files[0]
19
+ domain = $('#fileupload').attr('action')
20
+ path = $('#fileupload input[name=key]').val().replace('${filename}', file.name)
21
+ to = $('#fileupload').data('post')
22
+ content = {}
23
+ content[$('#fileupload').data('as')] = domain + path
24
+ $.post(to, content)
25
+ data.context.remove() if data.context # remove progress bar
26
+
27
+ fail: (e, data) ->
28
+ alert("#{data.files[0].name} failed to upload.")
29
+ console.log("Upload failed:")
30
+ console.log(data)
@@ -0,0 +1,17 @@
1
+ .upload {
2
+ border-top: solid 1px #CCC;
3
+ width: 400px;
4
+ padding-top: 10px;
5
+ margin-top: 10px;
6
+
7
+ .progress {
8
+ margin-top: 8px;
9
+ border: solid 1px #555;
10
+ border-radius: 3px;
11
+ -moz-border-radius: 3px;
12
+ .bar {
13
+ height: 10px;
14
+ background: #3EC144;
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,12 @@
1
+ require 's3_direct_upload/version'
2
+ require 'jquery-fileupload-rails' if defined?(Rails)
3
+
4
+ require 'base64'
5
+ require 'openssl'
6
+ require 'digest/sha1'
7
+
8
+ require 's3_direct_upload/config_aws'
9
+ require 's3_direct_upload/form_helper'
10
+ require 's3_direct_upload/engine' if defined?(Rails)
11
+
12
+ ActionView::Base.send(:include, S3DirectUpload::UploadHelper) if defined?(ActionView::Base)
@@ -0,0 +1,18 @@
1
+ require "singleton"
2
+
3
+ module S3DirectUpload
4
+ class Config
5
+ include Singleton
6
+
7
+ ATTRIBUTES = [:access_key_id, :secret_access_key, :bucket]
8
+
9
+ attr_accessor *ATTRIBUTES
10
+ end
11
+
12
+ def self.config
13
+ if block_given?
14
+ yield Config.instance
15
+ end
16
+ Config.instance
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ module S3DirectUpload
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,84 @@
1
+ module S3DirectUpload
2
+ module UploadHelper
3
+ def s3_uploader_form(options = {}, &block)
4
+ uploader = S3Uploader.new(options)
5
+ form_tag(uploader.url, uploader.form_options) do
6
+ uploader.fields.map do |name, value|
7
+ hidden_field_tag(name, value)
8
+ end.join.html_safe + capture(&block)
9
+ end
10
+ end
11
+
12
+ class S3Uploader
13
+ def initialize(options)
14
+ @options = options.reverse_merge(
15
+ id: "fileupload",
16
+ aws_access_key_id: S3DirectUpload.config.access_key_id,
17
+ aws_secret_access_key: S3DirectUpload.config.secret_access_key,
18
+ bucket: S3DirectUpload.config.bucket,
19
+ acl: "public-read",
20
+ expiration: 10.hours.from_now,
21
+ max_file_size: 500.megabytes,
22
+ as: "file"
23
+ )
24
+ end
25
+
26
+ def form_options
27
+ {
28
+ id: @options[:id],
29
+ method: "post",
30
+ authenticity_token: false,
31
+ multipart: true,
32
+ data: {
33
+ post: @options[:post],
34
+ as: @options[:as]
35
+ }
36
+ }
37
+ end
38
+
39
+ def fields
40
+ {
41
+ :key => key,
42
+ :acl => @options[:acl],
43
+ :policy => policy,
44
+ :signature => signature,
45
+ "AWSAccessKeyId" => @options[:aws_access_key_id],
46
+ }
47
+ end
48
+
49
+ def key
50
+ @key ||= "uploads/#{SecureRandom.hex}/${filename}"
51
+ end
52
+
53
+ def url
54
+ "https://#{@options[:bucket]}.s3.amazonaws.com/"
55
+ end
56
+
57
+ def policy
58
+ Base64.encode64(policy_data.to_json).gsub("\n", "")
59
+ end
60
+
61
+ def policy_data
62
+ {
63
+ expiration: @options[:expiration],
64
+ conditions: [
65
+ ["starts-with", "$utf8", ""],
66
+ ["starts-with", "$key", ""],
67
+ ["content-length-range", 0, @options[:max_file_size]],
68
+ {bucket: @options[:bucket]},
69
+ {acl: @options[:acl]}
70
+ ]
71
+ }
72
+ end
73
+
74
+ def signature
75
+ Base64.encode64(
76
+ OpenSSL::HMAC.digest(
77
+ OpenSSL::Digest::Digest.new('sha1'),
78
+ @options[:aws_secret_access_key], policy
79
+ )
80
+ ).gsub("\n", "")
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,3 @@
1
+ module S3DirectUpload
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: s3_direct_upload
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - WayneH
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.2'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.2'
30
+ - !ruby/object:Gem::Dependency
31
+ name: coffee-rails
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 3.2.1
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 3.2.1
46
+ - !ruby/object:Gem::Dependency
47
+ name: sass-rails
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 3.2.1
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 3.2.1
62
+ - !ruby/object:Gem::Dependency
63
+ name: jquery-fileupload-rails
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.3.4
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.3.4
78
+ description: Direct Upload to Amazon S3 With CORS and jquery-file-upload
79
+ email:
80
+ - wayne@blissofbeing.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - lib/s3_direct_upload/config_aws.rb
86
+ - lib/s3_direct_upload/engine.rb
87
+ - lib/s3_direct_upload/form_helper.rb
88
+ - lib/s3_direct_upload/version.rb
89
+ - lib/s3_direct_upload.rb
90
+ - app/assets/javascripts/s3_direct_upload.js.coffee
91
+ - app/assets/stylesheets/s3_direct_upload_progress_bars.css.scss
92
+ - LICENSE
93
+ - README.md
94
+ homepage: ''
95
+ licenses: []
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 1.8.23
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: Gives a form helper for Rails which allows direct uploads to s3. Based on
118
+ RailsCast#383
119
+ test_files: []