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 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