s3_direct_upload 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +34 -0
- data/app/assets/javascripts/s3_direct_upload.js.coffee +14 -18
- data/lib/s3_direct_upload.rb +1 -0
- data/lib/s3_direct_upload/config_aws.rb +2 -2
- data/lib/s3_direct_upload/form_helper.rb +7 -5
- data/lib/s3_direct_upload/railtie.rb +7 -0
- data/lib/s3_direct_upload/version.rb +1 -1
- data/lib/tasks/s3_direct_upload.rake +57 -0
- metadata +14 -6
data/README.md
CHANGED
@@ -144,6 +144,13 @@ jQuery ->
|
|
144
144
|
|
145
145
|
### Javascript Events Hooks
|
146
146
|
|
147
|
+
#### First upload started
|
148
|
+
`s3_uploads_start` is fired once when any batch of uploads is starting.
|
149
|
+
```coffeescript
|
150
|
+
$('#myS3Uploader').bind 's3_uploads_start', (e) ->
|
151
|
+
alert("Uploads have started")
|
152
|
+
```
|
153
|
+
|
147
154
|
#### Successfull upload
|
148
155
|
When a file has been successfully to S3, the `s3_upload_complete` is triggered on the form. A `content` object is passed along with the following attributes :
|
149
156
|
|
@@ -173,6 +180,33 @@ $(document).bind 's3_uploads_complete', ->
|
|
173
180
|
alert("All Uploads completed")
|
174
181
|
```
|
175
182
|
|
183
|
+
## Cleaning old uploads on S3
|
184
|
+
You may be processing the files upon upload and reuploading them to another
|
185
|
+
bucket or directory. If so you can remove the originali files by running a
|
186
|
+
rake task.
|
187
|
+
|
188
|
+
First, add the fog gem to your `Gemfile` and run `bundle`:
|
189
|
+
```ruby
|
190
|
+
require 'fog'
|
191
|
+
```
|
192
|
+
|
193
|
+
Then, run the rake task to delete uploads older than 2 days:
|
194
|
+
```
|
195
|
+
$ rake s3_direct_upload:clean_remote_uploads
|
196
|
+
Deleted file with key: "uploads/20121210T2139Z_03846cb0329b6a8eba481ec689135701/06 - PCR_RYA014-25.jpg"
|
197
|
+
Deleted file with key: "uploads/20121210T2139Z_03846cb0329b6a8eba481ec689135701/05 - PCR_RYA014-24.jpg"
|
198
|
+
$
|
199
|
+
```
|
200
|
+
|
201
|
+
Optionally customize the prefix used for cleaning (default is `uploads/#{2.days.ago.strftime('%Y%m%d')}`):
|
202
|
+
**config/initalizers/s3_direct_upload.rb**
|
203
|
+
```ruby
|
204
|
+
S3DirectUpload.config do |c|
|
205
|
+
# ...
|
206
|
+
c.prefix_to_clean = "my_path/#{1.week.ago.strftime('%y%m%d')}"
|
207
|
+
end
|
208
|
+
```
|
209
|
+
|
176
210
|
## Contributing / TODO
|
177
211
|
This is just a simple gem that only really provides some javascript and a form helper.
|
178
212
|
This gem could go all sorts of ways based on what people want and how people contribute.
|
@@ -35,6 +35,9 @@ $.fn.S3Uploader = (options) ->
|
|
35
35
|
$uploadForm.append(data.context)
|
36
36
|
data.submit()
|
37
37
|
|
38
|
+
start: (e) ->
|
39
|
+
$uploadForm.trigger("s3_uploads_start", [e])
|
40
|
+
|
38
41
|
progress: (e, data) ->
|
39
42
|
if data.context
|
40
43
|
progress = parseInt(data.loaded / data.total * 100, 10)
|
@@ -49,11 +52,9 @@ $.fn.S3Uploader = (options) ->
|
|
49
52
|
$.post(to, content)
|
50
53
|
|
51
54
|
data.context.remove() if data.context && settings.remove_completed_progress_bar # remove progress bar
|
52
|
-
$uploadForm.trigger("s3_upload_complete", [content])
|
53
55
|
|
54
56
|
current_files.splice($.inArray(data, current_files), 1) # remove that element from the array
|
55
|
-
|
56
|
-
$(document).trigger("s3_uploads_complete")
|
57
|
+
$uploadForm.trigger("s3_uploads_complete", [content]) unless current_files.length
|
57
58
|
|
58
59
|
fail: (e, data) ->
|
59
60
|
content = build_content_object $uploadForm, data.files[0], data.result
|
@@ -69,25 +70,20 @@ $.fn.S3Uploader = (options) ->
|
|
69
70
|
name: "Content-Type"
|
70
71
|
value: fileType
|
71
72
|
|
72
|
-
data[1].value = settings.path + data[1].value
|
73
|
-
|
73
|
+
data[1].value = settings.path + data[1].value #the key
|
74
74
|
data
|
75
|
-
|
75
|
+
|
76
76
|
build_content_object = ($uploadForm, file, result) ->
|
77
|
-
domain = $uploadForm.attr('action')
|
78
77
|
content = {}
|
79
78
|
if result # Use the S3 response to set the URL to avoid character encodings bugs
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
content.filepath =
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
content.filename = file.name
|
89
|
-
content.filepath = path
|
90
|
-
|
79
|
+
content.url = $(result).find("Location").text()
|
80
|
+
content.filepath = $('<a />').attr('href', content.url)[0].pathname
|
81
|
+
else # IE <= 9 return a null result object so we use the file object instead
|
82
|
+
domain = $uploadForm.attr('action')
|
83
|
+
content.filepath = settings.path + $uploadForm.find('input[name=key]').val().replace('/${filename}', '')
|
84
|
+
content.url = domain + content.filepath + '/' + encodeURIComponent(file.name)
|
85
|
+
|
86
|
+
content.filename = file.name
|
91
87
|
content.filesize = file.size if 'size' of file
|
92
88
|
content.filetype = file.type if 'type' of file
|
93
89
|
content = $.extend content, settings.additional_data if settings.additional_data
|
data/lib/s3_direct_upload.rb
CHANGED
@@ -8,5 +8,6 @@ require 'digest/sha1'
|
|
8
8
|
require 's3_direct_upload/config_aws'
|
9
9
|
require 's3_direct_upload/form_helper'
|
10
10
|
require 's3_direct_upload/engine' if defined?(Rails)
|
11
|
+
require 's3_direct_upload/railtie' if defined?(Rails)
|
11
12
|
|
12
13
|
ActionView::Base.send(:include, S3DirectUpload::UploadHelper) if defined?(ActionView::Base)
|
@@ -4,7 +4,7 @@ module S3DirectUpload
|
|
4
4
|
class Config
|
5
5
|
include Singleton
|
6
6
|
|
7
|
-
ATTRIBUTES = [:access_key_id, :secret_access_key, :bucket]
|
7
|
+
ATTRIBUTES = [:access_key_id, :secret_access_key, :bucket, :prefix_to_clean]
|
8
8
|
|
9
9
|
attr_accessor *ATTRIBUTES
|
10
10
|
end
|
@@ -15,4 +15,4 @@ module S3DirectUpload
|
|
15
15
|
end
|
16
16
|
Config.instance
|
17
17
|
end
|
18
|
-
end
|
18
|
+
end
|
@@ -41,19 +41,20 @@ module S3DirectUpload
|
|
41
41
|
{
|
42
42
|
:key => @options[:key] || key,
|
43
43
|
:acl => @options[:acl],
|
44
|
+
"AWSAccessKeyId" => @options[:aws_access_key_id],
|
44
45
|
:policy => policy,
|
45
46
|
:signature => signature,
|
46
|
-
|
47
|
-
|
47
|
+
:success_action_status => "201",
|
48
|
+
'X-Requested-With' => 'xhr'
|
48
49
|
}
|
49
50
|
end
|
50
51
|
|
51
52
|
def key
|
52
|
-
@key ||= "uploads/#{SecureRandom.hex}/${filename}"
|
53
|
+
@key ||= "uploads/#{DateTime.now.utc.strftime("%Y%m%dT%H%MZ")}_#{SecureRandom.hex}/${filename}"
|
53
54
|
end
|
54
55
|
|
55
56
|
def url
|
56
|
-
"https
|
57
|
+
"https://s3.amazonaws.com/#{@options[:bucket]}/"
|
57
58
|
end
|
58
59
|
|
59
60
|
def policy
|
@@ -66,6 +67,7 @@ module S3DirectUpload
|
|
66
67
|
conditions: [
|
67
68
|
["starts-with", "$utf8", ""],
|
68
69
|
["starts-with", "$key", ""],
|
70
|
+
["starts-with", "$x-requested-with", ""],
|
69
71
|
["content-length-range", 0, @options[:max_file_size]],
|
70
72
|
["starts-with","$Content-Type",""],
|
71
73
|
{bucket: @options[:bucket]},
|
@@ -85,4 +87,4 @@ module S3DirectUpload
|
|
85
87
|
end
|
86
88
|
end
|
87
89
|
end
|
88
|
-
end
|
90
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
namespace :s3_direct_upload do
|
2
|
+
desc "Removes old uploads from specified s3 bucket/directory -- Useful when uploads are processed into another directory"
|
3
|
+
task :clean_remote_uploads do
|
4
|
+
require 'thread'
|
5
|
+
require 'fog'
|
6
|
+
|
7
|
+
s3 = Fog::Storage::AWS.new(aws_access_key_id: S3DirectUpload.config.access_key_id, aws_secret_access_key: S3DirectUpload.config.secret_access_key)
|
8
|
+
bucket = S3DirectUpload.config.bucket
|
9
|
+
prefix = S3DirectUpload.config.prefix_to_clean || "uploads/#{2.days.ago.strftime('%Y%m%d')}"
|
10
|
+
|
11
|
+
queue = Queue.new
|
12
|
+
semaphore = Mutex.new
|
13
|
+
threads = []
|
14
|
+
thread_count = 20
|
15
|
+
total_listed = 0
|
16
|
+
total_deleted = 0
|
17
|
+
|
18
|
+
threads << Thread.new do
|
19
|
+
Thread.current[:name] = "get files"
|
20
|
+
# Get all the files from this bucket. Fog handles pagination internally.
|
21
|
+
s3.directories.get("#{bucket}").files.all({prefix: prefix}).each do |file|
|
22
|
+
queue.enq(file)
|
23
|
+
total_listed += 1
|
24
|
+
end
|
25
|
+
# Add a final EOF message to signal the deletion threads to stop.
|
26
|
+
thread_count.times { queue.enq(:EOF) }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Delete all the files in the queue until EOF with N threads.
|
30
|
+
thread_count.times do |count|
|
31
|
+
threads << Thread.new(count) do |number|
|
32
|
+
Thread.current[:name] = "delete files(#{number})"
|
33
|
+
# Dequeue until EOF.
|
34
|
+
file = nil
|
35
|
+
while file != :EOF
|
36
|
+
# Dequeue the latest file and delete it. (Will block until it gets a new file.)
|
37
|
+
file = queue.deq
|
38
|
+
unless file == :EOF
|
39
|
+
file.destroy
|
40
|
+
puts %Q{Deleted file with key: "#{file.key}"}
|
41
|
+
end
|
42
|
+
# Increment the global synchronized counter.
|
43
|
+
semaphore.synchronize {total_deleted += 1}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Wait for the threads to finish.
|
49
|
+
threads.each do |t|
|
50
|
+
begin
|
51
|
+
t.join
|
52
|
+
rescue RuntimeError => e
|
53
|
+
puts "Failure on thread #{t[:name]}: #{e.message}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
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.
|
4
|
+
version: 0.0.6
|
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:
|
12
|
+
date: 2013-01-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 3.2.
|
53
|
+
version: 3.2.5
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 3.2.
|
61
|
+
version: 3.2.5
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: jquery-fileupload-rails
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.
|
69
|
+
version: 0.4.0
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 0.
|
77
|
+
version: 0.4.0
|
78
78
|
description: Direct Upload to Amazon S3 With CORS and jquery-file-upload
|
79
79
|
email:
|
80
80
|
- w@waynehoover.com
|
@@ -85,8 +85,10 @@ files:
|
|
85
85
|
- lib/s3_direct_upload/config_aws.rb
|
86
86
|
- lib/s3_direct_upload/engine.rb
|
87
87
|
- lib/s3_direct_upload/form_helper.rb
|
88
|
+
- lib/s3_direct_upload/railtie.rb
|
88
89
|
- lib/s3_direct_upload/version.rb
|
89
90
|
- lib/s3_direct_upload.rb
|
91
|
+
- lib/tasks/s3_direct_upload.rake
|
90
92
|
- app/assets/javascripts/s3_direct_upload.js.coffee
|
91
93
|
- app/assets/stylesheets/s3_direct_upload_progress_bars.css.scss
|
92
94
|
- LICENSE
|
@@ -103,12 +105,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
105
|
- - ! '>='
|
104
106
|
- !ruby/object:Gem::Version
|
105
107
|
version: '0'
|
108
|
+
segments:
|
109
|
+
- 0
|
110
|
+
hash: 865831684437857007
|
106
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
112
|
none: false
|
108
113
|
requirements:
|
109
114
|
- - ! '>='
|
110
115
|
- !ruby/object:Gem::Version
|
111
116
|
version: '0'
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
hash: 865831684437857007
|
112
120
|
requirements: []
|
113
121
|
rubyforge_project:
|
114
122
|
rubygems_version: 1.8.23
|