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 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
- if current_files.length == 0
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
- path = $('Key', result).text()
81
- split_path = path.split('/')
82
- content.url = domain + path
83
- content.filename = split_path[split_path.length - 1]
84
- content.filepath = split_path.slice(0, split_path.length - 1).join('/')
85
- else # IE8 and IE9 return a null result object so we use the file object instead
86
- path = settings.path + $uploadForm.find('input[name=key]').val().replace('/${filename}', '')
87
- content.url = domain + path + '/' + file.name
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
@@ -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
- "AWSAccessKeyId" => @options[:aws_access_key_id],
47
- success_action_status: "201"
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://#{@options[:bucket]}.s3.amazonaws.com/"
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,7 @@
1
+ module S3DirectUpload
2
+ class Railtie < Rails::Railtie
3
+ initializer "railtie.configure_rails_initialization" do |app|
4
+ app.middleware.use JQuery::FileUpload::Rails::Middleware
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module S3DirectUpload
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  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.5
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: 2012-12-06 00:00:00.000000000 Z
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.1
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.1
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.3.5
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.3.5
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