s3_direct_upload 0.0.5 → 0.0.6
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/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
|