flash_s3_rails 0.0.1.beta1
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/.gitignore +7 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +156 -0
- data/README.md +92 -0
- data/Rakefile +46 -0
- data/app/assets/images/vendor/flash_s3/start_button.png +0 -0
- data/app/assets/images/vendor/flash_s3/swfupload.swf +0 -0
- data/app/assets/images/vendor/flash_s3/upload_button.png +0 -0
- data/app/assets/javascripts/jquery.flashS3.js +128 -0
- data/app/assets/javascripts/vendor/flash_s3/swfupload.fileprogress.js +151 -0
- data/app/assets/javascripts/vendor/flash_s3/swfupload.handlers.js +199 -0
- data/app/assets/javascripts/vendor/flash_s3/swfupload.js +980 -0
- data/app/assets/javascripts/vendor/flash_s3/swfupload.queue.js +98 -0
- data/app/assets/javascripts/vendor/flash_s3/swfupload.swfobject.js +111 -0
- data/app/assets/stylesheets/jquery.flashS3.css +53 -0
- data/app/helpers/flash_s3_helper.rb +45 -0
- data/app/views/flash_s3/_flash_s3_uploader.html.erb +5 -0
- data/app/views/layouts/_flash_s3.html.erb +6 -0
- data/config/routes.rb +5 -0
- data/flash_s3.gemspec +34 -0
- data/lib/flash_s3.rb +66 -0
- data/lib/flash_s3/attachment.rb +28 -0
- data/lib/flash_s3/attachment_definition.rb +39 -0
- data/lib/flash_s3/engine.rb +13 -0
- data/lib/flash_s3/s3_post_params.rb +80 -0
- data/lib/flash_s3/version.rb +3 -0
- data/spec/models/upload_spec.rb +72 -0
- data/spec/rails_spec_helper.rb +32 -0
- data/spec/requests/new_upload_spec.rb +12 -0
- data/spec/spec_helper.rb +18 -0
- metadata +204 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
flash_s3_rails (0.0.1.beta1)
|
5
|
+
activesupport
|
6
|
+
jquery-ui-rails
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
actionmailer (3.2.3)
|
12
|
+
actionpack (= 3.2.3)
|
13
|
+
mail (~> 2.4.4)
|
14
|
+
actionpack (3.2.3)
|
15
|
+
activemodel (= 3.2.3)
|
16
|
+
activesupport (= 3.2.3)
|
17
|
+
builder (~> 3.0.0)
|
18
|
+
erubis (~> 2.7.0)
|
19
|
+
journey (~> 1.0.1)
|
20
|
+
rack (~> 1.4.0)
|
21
|
+
rack-cache (~> 1.2)
|
22
|
+
rack-test (~> 0.6.1)
|
23
|
+
sprockets (~> 2.1.2)
|
24
|
+
activemodel (3.2.3)
|
25
|
+
activesupport (= 3.2.3)
|
26
|
+
builder (~> 3.0.0)
|
27
|
+
activerecord (3.2.3)
|
28
|
+
activemodel (= 3.2.3)
|
29
|
+
activesupport (= 3.2.3)
|
30
|
+
arel (~> 3.0.2)
|
31
|
+
tzinfo (~> 0.3.29)
|
32
|
+
activeresource (3.2.3)
|
33
|
+
activemodel (= 3.2.3)
|
34
|
+
activesupport (= 3.2.3)
|
35
|
+
activesupport (3.2.3)
|
36
|
+
i18n (~> 0.6)
|
37
|
+
multi_json (~> 1.0)
|
38
|
+
addressable (2.2.7)
|
39
|
+
arel (3.0.2)
|
40
|
+
builder (3.0.0)
|
41
|
+
capybara (1.1.2)
|
42
|
+
mime-types (>= 1.16)
|
43
|
+
nokogiri (>= 1.3.3)
|
44
|
+
rack (>= 1.0.0)
|
45
|
+
rack-test (>= 0.5.4)
|
46
|
+
selenium-webdriver (~> 2.0)
|
47
|
+
xpath (~> 0.1.4)
|
48
|
+
childprocess (0.3.2)
|
49
|
+
ffi (~> 1.0.6)
|
50
|
+
daemons (1.0.10)
|
51
|
+
database_cleaner (0.7.2)
|
52
|
+
diff-lcs (1.1.3)
|
53
|
+
erubis (2.7.0)
|
54
|
+
eventmachine (0.12.10)
|
55
|
+
ffi (1.0.11)
|
56
|
+
gem_plugin (0.2.3)
|
57
|
+
hike (1.2.1)
|
58
|
+
i18n (0.6.0)
|
59
|
+
journey (1.0.3)
|
60
|
+
jquery-rails (2.0.2)
|
61
|
+
railties (>= 3.2.0, < 5.0)
|
62
|
+
thor (~> 0.14)
|
63
|
+
jquery-ui-rails (0.3.0)
|
64
|
+
jquery-rails
|
65
|
+
railties (>= 3.1.0)
|
66
|
+
json (1.6.6)
|
67
|
+
libwebsocket (0.1.3)
|
68
|
+
addressable
|
69
|
+
mail (2.4.4)
|
70
|
+
i18n (>= 0.4.0)
|
71
|
+
mime-types (~> 1.16)
|
72
|
+
treetop (~> 1.4.8)
|
73
|
+
mime-types (1.18)
|
74
|
+
mongrel (1.2.0.pre2)
|
75
|
+
daemons (~> 1.0.10)
|
76
|
+
gem_plugin (~> 0.2.3)
|
77
|
+
multi_json (1.3.2)
|
78
|
+
nokogiri (1.5.2)
|
79
|
+
polyglot (0.3.3)
|
80
|
+
rack (1.4.1)
|
81
|
+
rack-cache (1.2)
|
82
|
+
rack (>= 0.4)
|
83
|
+
rack-ssl (1.3.2)
|
84
|
+
rack
|
85
|
+
rack-test (0.6.1)
|
86
|
+
rack (>= 1.0)
|
87
|
+
rails (3.2.3)
|
88
|
+
actionmailer (= 3.2.3)
|
89
|
+
actionpack (= 3.2.3)
|
90
|
+
activerecord (= 3.2.3)
|
91
|
+
activeresource (= 3.2.3)
|
92
|
+
activesupport (= 3.2.3)
|
93
|
+
bundler (~> 1.0)
|
94
|
+
railties (= 3.2.3)
|
95
|
+
railties (3.2.3)
|
96
|
+
actionpack (= 3.2.3)
|
97
|
+
activesupport (= 3.2.3)
|
98
|
+
rack-ssl (~> 1.3.2)
|
99
|
+
rake (>= 0.8.7)
|
100
|
+
rdoc (~> 3.4)
|
101
|
+
thor (~> 0.14.6)
|
102
|
+
rake (0.9.2.2)
|
103
|
+
rdoc (3.12)
|
104
|
+
json (~> 1.4)
|
105
|
+
rspec (2.9.0)
|
106
|
+
rspec-core (~> 2.9.0)
|
107
|
+
rspec-expectations (~> 2.9.0)
|
108
|
+
rspec-mocks (~> 2.9.0)
|
109
|
+
rspec-core (2.9.0)
|
110
|
+
rspec-expectations (2.9.1)
|
111
|
+
diff-lcs (~> 1.1.3)
|
112
|
+
rspec-mocks (2.9.0)
|
113
|
+
rspec-rails (2.9.0)
|
114
|
+
actionpack (>= 3.0)
|
115
|
+
activesupport (>= 3.0)
|
116
|
+
railties (>= 3.0)
|
117
|
+
rspec (~> 2.9.0)
|
118
|
+
rubyzip (0.9.7)
|
119
|
+
selenium-webdriver (2.21.2)
|
120
|
+
childprocess (>= 0.2.5)
|
121
|
+
ffi (~> 1.0)
|
122
|
+
libwebsocket (~> 0.1.3)
|
123
|
+
multi_json (~> 1.0)
|
124
|
+
rubyzip
|
125
|
+
sprockets (2.1.2)
|
126
|
+
hike (~> 1.2)
|
127
|
+
rack (~> 1.0)
|
128
|
+
tilt (~> 1.1, != 1.3.0)
|
129
|
+
sqlite3 (1.3.6)
|
130
|
+
thin (1.3.1)
|
131
|
+
daemons (>= 1.0.9)
|
132
|
+
eventmachine (>= 0.12.6)
|
133
|
+
rack (>= 1.0.0)
|
134
|
+
thor (0.14.6)
|
135
|
+
tilt (1.3.3)
|
136
|
+
treetop (1.4.10)
|
137
|
+
polyglot
|
138
|
+
polyglot (>= 0.3.1)
|
139
|
+
tzinfo (0.3.33)
|
140
|
+
xpath (0.1.4)
|
141
|
+
nokogiri (~> 1.3)
|
142
|
+
|
143
|
+
PLATFORMS
|
144
|
+
ruby
|
145
|
+
|
146
|
+
DEPENDENCIES
|
147
|
+
capybara
|
148
|
+
database_cleaner
|
149
|
+
flash_s3_rails!
|
150
|
+
jquery-rails
|
151
|
+
mongrel (~> 1.2.0.pre2)
|
152
|
+
rails
|
153
|
+
rspec
|
154
|
+
rspec-rails
|
155
|
+
sqlite3
|
156
|
+
thin
|
data/README.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# FlashS3Rails
|
2
|
+
|
3
|
+
Upload files to s3 with flash, including progress bars, in your Rails app. Configuration requires an s3 key and secret only.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'flash_s3_rails', :require => 'flash_s3'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install flash_s3_rails
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### In `application.rb` or `<environment>.rb` or an initializer
|
22
|
+
|
23
|
+
``` ruby
|
24
|
+
config.flash_s3.bucket = 'mybucketname'
|
25
|
+
config.flash_s3.s3_access_key_id = "myaccesskey"
|
26
|
+
config.flash_s3.s3_secret_access_key = "mysecretaccesskey"
|
27
|
+
```
|
28
|
+
|
29
|
+
### In a migration
|
30
|
+
|
31
|
+
``` ruby
|
32
|
+
add_column :<your_model_name_pluralized>, :<your_attachment_name>_s3_key :string
|
33
|
+
```
|
34
|
+
|
35
|
+
e.g.
|
36
|
+
|
37
|
+
``` ruby
|
38
|
+
add_column :videos, :media_s3_key, :string
|
39
|
+
```
|
40
|
+
|
41
|
+
### In the Model
|
42
|
+
|
43
|
+
Let's say it's called `Video`.
|
44
|
+
|
45
|
+
``` ruby
|
46
|
+
has_attached_s3_file :media
|
47
|
+
```
|
48
|
+
|
49
|
+
Substitute your upload name for `media`.
|
50
|
+
|
51
|
+
### In the View
|
52
|
+
|
53
|
+
#### Erb
|
54
|
+
|
55
|
+
``` erb
|
56
|
+
<%= flash_s3_uploader @video, :media, post_upload_callback_url %>
|
57
|
+
```
|
58
|
+
|
59
|
+
#### Haml
|
60
|
+
|
61
|
+
``` haml
|
62
|
+
= flash_s3_uploader @video, :media, post_upload_callback_url
|
63
|
+
```
|
64
|
+
|
65
|
+
Note: You must use the url and not the path for your post callback hook.
|
66
|
+
|
67
|
+
### In your Controller (post upload callback action)
|
68
|
+
|
69
|
+
``` ruby
|
70
|
+
def create
|
71
|
+
@video = Video.new(params[:video])
|
72
|
+
@video.save!
|
73
|
+
head :ok
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
Or whatever ;) The point is to `new`, `create`, `update_attributes`, etc, your Model instance with the `attachment_s3_key` column and `has_attached_s3_file` and save it! Your s3_key will be saved automagically.
|
78
|
+
|
79
|
+
## Upcoming
|
80
|
+
|
81
|
+
* Additional _custom_ post callback params
|
82
|
+
* More configurable, e.g. max file size, file type(s) accepted
|
83
|
+
* Drop jquery-ui dependency and implement a simple css progress bar
|
84
|
+
* Make the green box a little less ugly ;)
|
85
|
+
|
86
|
+
## Contributing
|
87
|
+
|
88
|
+
1. Fork it
|
89
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
90
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
91
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
92
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
desc "Run specs"
|
6
|
+
RSpec::Core::RakeTask.new :spec => ['spec:prepare'] do |t|
|
7
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
8
|
+
# Put spec opts in a file named .rspec in root
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
namespace :spec do
|
13
|
+
desc 'Create spec'
|
14
|
+
task :create, :path do |t, args|
|
15
|
+
spec_path = File.join('spec', args[:path].gsub(%r{.rb$}, '_spec.rb'))
|
16
|
+
klass = File.basename(args[:path], File.extname(args[:path])).split('_').map {|s| "#{s[0,1].upcase}#{s[1..-1]}" }.join
|
17
|
+
mkdir_p File.dirname(spec_path)
|
18
|
+
|
19
|
+
spec_doc = <<-EOS
|
20
|
+
require 'spec_helper'
|
21
|
+
|
22
|
+
describe #{klass} do
|
23
|
+
end
|
24
|
+
EOS
|
25
|
+
|
26
|
+
File.open(spec_path, 'w+') do |f|
|
27
|
+
f.puts spec_doc
|
28
|
+
end
|
29
|
+
|
30
|
+
puts spec_doc
|
31
|
+
end
|
32
|
+
|
33
|
+
task :prepare => ['db:migrate:reset', 'db:test:prepare']
|
34
|
+
end
|
35
|
+
|
36
|
+
ENV["RAILS_ENV"] ||= 'test'
|
37
|
+
require 'flash_s3_test/config/application'
|
38
|
+
FlashS3Test::Application.load_tasks
|
39
|
+
|
40
|
+
task :server => 'db:migrate:reset' do
|
41
|
+
app = Rack::Builder.new { run FlashS3Test::Application }.to_app
|
42
|
+
Rack::Handler::Thin.run app, :Port => 3000
|
43
|
+
end
|
44
|
+
|
45
|
+
desc 'Default: run specs.'
|
46
|
+
task :default => :spec
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,128 @@
|
|
1
|
+
//= require vendor/flash_s3/swfupload
|
2
|
+
|
3
|
+
(function ($) {
|
4
|
+
var methods = {
|
5
|
+
initialize: function (options) {
|
6
|
+
var elem = $(this);
|
7
|
+
|
8
|
+
methods.elem = function () {
|
9
|
+
return $(elem);
|
10
|
+
};
|
11
|
+
|
12
|
+
var settings = $.extend(true, {
|
13
|
+
file_queued_handler: methods.handleFileQueued,
|
14
|
+
|
15
|
+
upload_success_handler: methods.handleFileSuccess,
|
16
|
+
|
17
|
+
upload_progress_handler: methods.handleFileProgress,
|
18
|
+
|
19
|
+
file_size_limit : "0"
|
20
|
+
}, options);
|
21
|
+
|
22
|
+
elem.data('flashS3Settings', settings);
|
23
|
+
|
24
|
+
var sfwu = new SWFUpload(settings);
|
25
|
+
elem.data('flashS3Swfu', sfwu);
|
26
|
+
|
27
|
+
elem.find('a.flash_s3-start_button').click(function (evt) {
|
28
|
+
evt.preventDefault();
|
29
|
+
sfwu.startUpload();
|
30
|
+
});
|
31
|
+
},
|
32
|
+
|
33
|
+
progressbar: function (fileId) {
|
34
|
+
return $('li#' + fileId).data('flashS3Progressbar');
|
35
|
+
},
|
36
|
+
|
37
|
+
sfsu: function () {
|
38
|
+
return methods.elem().data('flashS3Swfu');
|
39
|
+
},
|
40
|
+
|
41
|
+
handleFileSuccess: function (file, serverData) {
|
42
|
+
var pb = methods.progressbar.call(methods.elem(), file.id);
|
43
|
+
if ($(pb).is('.ui-progressbar')) {
|
44
|
+
pb.progressbar('value', 100);
|
45
|
+
} // TODO else: make a css progress bar and handle here
|
46
|
+
|
47
|
+
var settings = methods.elem().data('flashS3Settings');
|
48
|
+
var recordKlass = settings.custom_settings.record_class_name;
|
49
|
+
var attachmentName = settings.custom_settings.attachment_name;
|
50
|
+
var s3KeyQueryParamKey = recordKlass + '[' + attachmentName + '][s3_key]';
|
51
|
+
var params = {};
|
52
|
+
params[s3KeyQueryParamKey] = $($.parseXML(serverData)).find('Key').text();
|
53
|
+
params.s3_file_class_name = recordKlass;
|
54
|
+
$.post(settings.custom_settings.create_s3_attachment_url, params);
|
55
|
+
this.startUpload();
|
56
|
+
},
|
57
|
+
|
58
|
+
handleFileProgress: function (file, bytesLoaded, bytesTotal) {
|
59
|
+
var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
|
60
|
+
var pb = methods.progressbar.call(methods.elem(), file.id);
|
61
|
+
if ($(pb).is('.ui-progressbar')) {
|
62
|
+
pb.progressbar('value', percent);
|
63
|
+
} // TODO else: make a css progress bar and handle here
|
64
|
+
},
|
65
|
+
|
66
|
+
handleFileQueued: function (file) {
|
67
|
+
var settings = methods.elem().data('flashS3Settings');
|
68
|
+
|
69
|
+
var listItem;
|
70
|
+
if (settings.custom_settings.file_upload_list_item_renderer) {
|
71
|
+
listItem = $.globalEval(settings.custom_settings.file_upload_list_item_renderer).call(this, file);
|
72
|
+
} else {
|
73
|
+
listItem = methods.fileUplaodListItemRenderer.call(this, file);
|
74
|
+
|
75
|
+
$('.ui-icon-close', listItem).click(function (evt) {
|
76
|
+
evt.preventDefault();
|
77
|
+
methods.sfsu().cancelUpload(file.id);
|
78
|
+
listItem.remove();
|
79
|
+
});
|
80
|
+
}
|
81
|
+
methods.elem().find('ol.flash_s3-file_transfers').append(listItem);
|
82
|
+
},
|
83
|
+
|
84
|
+
fileUplaodListItemRenderer: function (file) {
|
85
|
+
var listItem = $('<li class="flash_s3-file" id="' + file.id + '">' +
|
86
|
+
'<div class="flash_s3-filename">' + file.name + '</div>' +
|
87
|
+
'<div class="flash_s3-progress_bar" />' +
|
88
|
+
'<div class="ui-icon-close ui-icon" />' +
|
89
|
+
'</li>');
|
90
|
+
var pb;
|
91
|
+
if (methods.enablesJQueryUI()) {
|
92
|
+
pb = listItem.find('.flash_s3-progress_bar').progressbar();
|
93
|
+
listItem.data("flashS3Progressbar", pb);
|
94
|
+
} else {
|
95
|
+
pb = listItem.find('.flash_s3-progress_bar');
|
96
|
+
listItem.data("flashS3Progressbar", pb);
|
97
|
+
}
|
98
|
+
|
99
|
+
return listItem;
|
100
|
+
},
|
101
|
+
enablesJQueryUI: function () {
|
102
|
+
return true;
|
103
|
+
}
|
104
|
+
};
|
105
|
+
|
106
|
+
$.makePlugin = function (name, methods) {
|
107
|
+
$.fn[name] = function () {
|
108
|
+
var retVal;
|
109
|
+
var command = arguments[0] || 'initialize';
|
110
|
+
var args, options;
|
111
|
+
if ($.isPlainObject(command) || command === 'initialize') {
|
112
|
+
command = 'initialize';
|
113
|
+
args = [arguments[0] || {}];
|
114
|
+
} else if (command) {
|
115
|
+
args = $.makeArray(arguments).slice(1);
|
116
|
+
}
|
117
|
+
|
118
|
+
var iterator = $(this).each(function () {
|
119
|
+
var elem = $(this);
|
120
|
+
retVal = methods[command].apply(elem, args);
|
121
|
+
});
|
122
|
+
|
123
|
+
return retVal || iterator;
|
124
|
+
};
|
125
|
+
};
|
126
|
+
|
127
|
+
$.makePlugin('flashS3', methods);
|
128
|
+
})(jQuery);
|