s3_direct_upload 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -6,7 +6,6 @@ Multi file uploading supported by jquery-fileupload.
6
6
  Code extracted from Ryan Bates' [gallery-jquery-fileupload](https://github.com/railscasts/383-uploading-to-amazon-s3/tree/master/gallery-jquery-fileupload).
7
7
 
8
8
  ## Installation
9
-
10
9
  Add this line to your application's Gemfile:
11
10
 
12
11
  gem 's3_direct_upload'
@@ -39,27 +38,32 @@ In production the AllowedOrigin key should be your domain.
39
38
 
40
39
  Add the following js and css to your asset pipeline:
41
40
 
42
- **application.js**
43
- ```ruby
44
- //= require s3_direct_upload
41
+ **application.js.coffee**
42
+ ```coffeescript
43
+ #= require s3_direct_upload
45
44
  ```
46
45
 
47
46
  **application.css**
48
- ```ruby
47
+ ```css
49
48
  //= require s3_direct_upload_progress_bars
50
49
  ```
51
50
 
52
51
  ## Usage
53
-
54
- Create a new view that uses the helper:
52
+ Create a new view that uses the form helper `s3_uploader_form`:
55
53
  ```ruby
56
- <%= s3_uploader_form post: model_url, as: "model[image_url]" do %>
54
+ <%= s3_uploader_form post: model_url, as: "model[image_url]", id: "myS3Uploader" do %>
57
55
  <%= file_field_tag :file, multiple: true %>
58
56
  <% end %>
59
57
  ```
60
58
 
59
+ Then in your application.js.coffee, call the S3Uploader jQuery plugin on the element you created above:
60
+ ```coffeescript
61
+ jQuery ->
62
+ $("#myS3Uploader").S3Uploader()
63
+ ```
64
+
61
65
  Also place this template in the same view for the progress bars:
62
- ```javascript
66
+ ```js+erb
63
67
  <script id="template-upload" type="text/x-tmpl">
64
68
  <div class="upload">
65
69
  {%=o.name%}
@@ -68,40 +72,94 @@ Also place this template in the same view for the progress bars:
68
72
  </script>
69
73
  ```
70
74
 
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.
75
+ ## Options for form helper
76
+ `post:` -> url in which is POST'd to after file is uploaded to S3. Example: model_url
73
77
 
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.
78
+ `as:` -> parameter value for the POST in which the key will be the URL of the file on S3. If for example this is set to "model[image_url]" then the data posted would be `model[image_url] : http://bucketname.s3.amazonws.com/filename.ext`
79
+
80
+ `key:` -> key on s3. defaults to `"uploads/#{SecureRandom.hex}/${filename}"`. needs to be at least `"${filename}"`.
81
+
82
+ `acl:` -> acl for files uploaded to s3, defaults to "public-read"
83
+
84
+ `max_file_size:` -> maximum file size, defaults to 500.megabytes
81
85
 
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.
86
+ `id:` -> html id for the form, its recommended that you give the form an id so you can reference with the jQuery plugin.
85
87
 
86
- You could have your create action render a javascript file like this:
88
+ `class:` -> optional html class for the form.
87
89
 
90
+
91
+ ### Persisting the S3 url
92
+ It is recommended that you persist the image_url that is sent back from the POST request (to the url given to the `post` option and as the key given in the `as` option). So to access your files later.
93
+
94
+ One way to do this is to make sure you have `resources model` in your routes file, and add the `image_url` (or whatever you would like to name it) attribute to your model, and then make sure you have the create action in your controller for that model.
95
+
96
+ You could then have your create action render a javascript file like this:
88
97
  **create.js.erb**
89
98
  ```ruby
90
99
  <% if @model.new_record? %>
91
100
  alert("Failed to upload model: <%= j @model.errors.full_messages.join(', ').html_safe %>");
92
101
  <% else %>
93
- $("#paintings").append("<%= j render(@model) %>");
102
+ $("#container").append("<%= j render(@model) %>");
94
103
  <% end %>
95
104
  ```
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.
105
+ So that javascript code would be executed after the model instance is created, without a page refresh. See [@rbates's gallery-jquery-fileupload](https://github.com/railscasts/383-uploading-to-amazon-s3/tree/master/gallery-jquery-fileupload)) for an example of that method.
97
106
 
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)
107
+ Note: the POST request to the rails app also includes the following parameters `filesize`, `filetype`, `filename` and `filepath`.
99
108
 
109
+ ### Advanced Customizations
110
+ Feel free to override the styling for the progress bars in s3_direct_upload_progress_bars.css, look at the source for inspiration.
100
111
 
101
- ## Gotchas
112
+ 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.
113
+ To do this remove `s3_direct_upload` from your application.js and include the necessary jquery-file-upload scripts in your asset pipeline (they are included in this gem automatically):
114
+ ```cofeescript
115
+ #= require jquery-fileupload/basic
116
+ #= require jquery-fileupload/vendor/tmpl
117
+ ```
118
+ Use the javascript in `s3_direct_upload` as a guide.
119
+
120
+
121
+ ## Options for S3Upload jQuery Plugin
122
+
123
+ `path` -> manual path for the files on your s3 bucket. Example: `path/to/my/files/on/s3`
124
+
125
+ Note: the file path in your s3 bucket will effectively be `path + key`.
126
+
127
+ `additional_data` -> You can send additional data to your rails app in the persistence POST request. Example: `{key: value}`
128
+
129
+ This would be accessable in your params hash as `params[:key][:value]`
130
+
131
+ `before_add` -> Callback function that executes before a file is added to the que. It is passed file object and expects `true` or `false` to be returned.
132
+
133
+ This could be useful if you would like to validate the filenames of files to be uploaded for example. If true is returned file will be uploaded as normal, false will cancel the upload.
134
+
135
+ ### Public methods
136
+ You can change the settings on your form later on by accessing the jQuery instance:
137
+
138
+ ```cofeescript
139
+ jQuery ->
140
+ v = $("#myS3Uploader").S3Uploader()
141
+ ...
142
+ v.path("new/path/")
143
+ v.exta_data("newdata")
144
+
145
+ ### Global Event Hooks
146
+
147
+ When all uploads finish in a batch an `s3_uploads_complete` event will be triggered on `document`, so you could do something like:
148
+ ```javascript
149
+ $(document).bind('s3_uploads_complete', function(){
150
+ ...
151
+ alert("All Uploads completed")
152
+ });
153
+ ````
154
+ ### Example with all options.
155
+ ```cofeescript
156
+ jQuery ->
157
+ $("#myS3Uploader").S3Uploader
158
+ path: 'path/to/my/files/on/s3'
159
+ additional_data: {key: 'value'}
160
+ before_add: myCallBackFunction() # must return true or false if set
161
+ ```
102
162
 
103
- Right now you can only have one upload form on a page.
104
- Upload form is hardcoded with id '#fileupload'
105
163
 
106
164
 
107
165
  ## Contributing / TODO
@@ -109,10 +167,13 @@ Upload form is hardcoded with id '#fileupload'
109
167
  This is just a simple gem that only really provides some javascript and a form helper.
110
168
  This gem could go all sorts of ways based on what people want and how people contribute.
111
169
  Ideas:
112
- More specs!
113
- More options to control expiration, max filesize, file types etc.
114
- Create generators.
115
- Model methods.
170
+ * More specs!
171
+ * More options to control file types, ability to batch upload.
172
+ * More convention over configuration on rails side
173
+ * Create generators.
174
+ * Model methods.
175
+ * Model method to delete files from s3
176
+
116
177
 
117
178
  ## Credit
118
179
 
@@ -1,30 +1,94 @@
1
1
  #= require jquery-fileupload/basic
2
2
  #= require jquery-fileupload/vendor/tmpl
3
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)
4
+ (($) ->
5
+ $.fn.S3Uploader = (options) ->
6
+
7
+ # support multiple elements
8
+ if @length > 1
9
+ @each ->
10
+ $(this).S3Upleader options
11
+
12
+ return this
13
+
14
+ $uploadForm = this
15
+
16
+ settings =
17
+ path: ''
18
+ additional_data: null
19
+ before_add: null
20
+
21
+ settings = $.extend settings, options
22
+
23
+ current_files = []
24
+
25
+ setUploadForm = ->
26
+ $uploadForm.fileupload
27
+
28
+ add: (e, data) ->
29
+ current_files.push data
30
+ file = data.files[0]
31
+ unless settings.before_add and not settings.before_add(file)
32
+ data.context = $(tmpl("template-upload", file))
33
+ $uploadForm.append(data.context)
34
+ data.submit()
35
+
36
+ progress: (e, data) ->
37
+ if data.context
38
+ progress = parseInt(data.loaded / data.total * 100, 10)
39
+ data.context.find('.bar').css('width', progress + '%')
40
+
41
+ done: (e, data) ->
42
+ file = data.files[0]
43
+ domain = $uploadForm.attr('action')
44
+ path = settings.path + $uploadForm.find('input[name=key]').val().replace('/${filename}', '')
45
+ to = $uploadForm.data('post')
46
+ content = {}
47
+ content[$uploadForm.data('as')] = domain + path + '/' + file.name
48
+ content.filename = file.name
49
+ content.filepath = path
50
+ if settings.additional_data
51
+ content = $.extend content, settings.additional_data
52
+ if 'size' of file
53
+ content.file_size = file.size
54
+ if 'type' of file
55
+ content.file_type = file.type
56
+
57
+ $.post(to, content)
58
+ data.context.remove() if data.context # remove progress bar
59
+
60
+ current_files.splice($.inArray(data, current_files), 1) # remove that element from the array
61
+ if current_files.length == 0
62
+ $(document).trigger("s3_uploads_complete")
63
+
64
+ fail: (e, data) ->
65
+ alert("#{data.files[0].name} failed to upload.")
66
+ console.log("Upload failed:")
67
+ console.log(data)
68
+
69
+ formData: (form) ->
70
+ data = form.serializeArray()
71
+ fileType = ""
72
+ if "type" of @files[0]
73
+ fileType = @files[0].type
74
+ data.push
75
+ name: "Content-Type"
76
+ value: fileType
77
+
78
+ data[1].value = settings.path + data[1].value
79
+
80
+ data
81
+
82
+ #public methods
83
+ @initialize = ->
84
+ setUploadForm()
85
+ this
86
+
87
+ @path = (new_path) ->
88
+ settings.path = new_path
89
+
90
+ @additional_data = (new_data) ->
91
+ settings.additional_data = additional_data
92
+
93
+ @initialize()
94
+ ) jQuery
@@ -12,20 +12,21 @@ module S3DirectUpload
12
12
  class S3Uploader
13
13
  def initialize(options)
14
14
  @options = options.reverse_merge(
15
- id: "fileupload",
16
15
  aws_access_key_id: S3DirectUpload.config.access_key_id,
17
16
  aws_secret_access_key: S3DirectUpload.config.secret_access_key,
18
17
  bucket: S3DirectUpload.config.bucket,
19
18
  acl: "public-read",
20
19
  expiration: 10.hours.from_now,
21
20
  max_file_size: 500.megabytes,
22
- as: "file"
21
+ as: "file",
22
+ key: key
23
23
  )
24
24
  end
25
25
 
26
26
  def form_options
27
27
  {
28
28
  id: @options[:id],
29
+ class: @options[:class],
29
30
  method: "post",
30
31
  authenticity_token: false,
31
32
  multipart: true,
@@ -38,7 +39,7 @@ module S3DirectUpload
38
39
 
39
40
  def fields
40
41
  {
41
- :key => key,
42
+ :key => @options[:key] || key,
42
43
  :acl => @options[:acl],
43
44
  :policy => policy,
44
45
  :signature => signature,
@@ -65,6 +66,7 @@ module S3DirectUpload
65
66
  ["starts-with", "$utf8", ""],
66
67
  ["starts-with", "$key", ""],
67
68
  ["content-length-range", 0, @options[:max_file_size]],
69
+ ["starts-with","$Content-Type",""],
68
70
  {bucket: @options[:bucket]},
69
71
  {acl: @options[:acl]}
70
72
  ]
@@ -1,3 +1,3 @@
1
1
  module S3DirectUpload
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s3_direct_upload
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-30 00:00:00.000000000 Z
12
+ date: 2012-10-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails